# Babysit

> Keep one of your open PRs healthy on a schedule: poll for new review activity, auto-address bot/Copilot nits and routine rebases, re-run the project gate, and reconcile the PR thread — looping until the PR has zero blocking findings and is mergeable, with HITL checkpoints on anything irreversible. This is the scheduled, guardrailed loop around git-pr-feedback (which does the per-pass fetch/triage/fix). Run it as Boris Cherny's daily-driver "/loop 5m /babysit", or invoke /babysit once. Use when you want a PR babysat while you work elsewhere, want review comments auto-handled on a cadence, or want a PR kept rebased and green. Trigger on "babysit my PR", "babysit prs", "watch this PR", "keep my PR green", "auto-address review comments on a schedule", "loop 5m babysit", "keep the PR rebased", "poll the PR for new feedback". Never auto-merges and never force-pushes a shared branch unattended. A configuration of loop-controller.

- Skill: `ivy00johns/babysit` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add ivy00johns/babysit`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ivy00johns/babysit/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: ivy00johns (https://skillmd.com/u/ivy00johns)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/ivy00johns/babysit

---


# babysit

> **A configuration of [`loop-controller`].** That skill supplies the loop
> machinery — primitive selection, the full guardrail stack, state
> externalization. This skill supplies the three things specific to "keep a PR
> healthy": the **per-pass recipe** (it schedules [`git-pr-feedback`], it does
> not re-implement it), the **mechanical proof** (zero open blocking findings +
> mergeable), and the **HITL boundary** that decides what's AFK-safe vs what
> pauses. Read `loop-controller` for the guardrails; they're inherited, not
> repeated here.
>
> **Why `disable-model-invocation`:** this loop commits, pushes, rebases, and
> touches a live PR thread on its own, on a clock. It is user-driven — you want
> to *type* `/loop 5m /babysit` (or `/babysit`), not have Claude silently start
> tending a PR because a reviewer happened to comment.

## The 5-part contract

| Part | This loop |
|---|---|
| **trigger** | an open PR of yours with potential review activity; scheduled via `/loop 5m /babysit`, or an explicit `/babysit` (optionally a PR number) |
| **action** | ONE pass: fetch new review findings (Copilot + human) via [`git-pr-feedback`] → triage → address **one root-cause finding** (or rebase if base moved) → re-run the project gate → push → reconcile the PR thread. One change per pass; re-check the whole PR state after |
| **proof** | the `gh` PR review/status query returns **zero OPEN actionable/blocking comments AND `mergeable == "MERGEABLE"`** (up to date with base, CI green) — default-FAIL: assume findings are unaddressed until the fetch proves otherwise (treat `mergeable == "UNKNOWN"` as not-yet-proven and re-check) |
| **memory** | a per-PR fix log (findings addressed, findings deferred + why), git history, and the PR thread itself — all durable across the session-scoped `/loop` fires |
| **stop** | zero blocking findings **AND** mergeable **OR** poll/iteration cap **OR** no-progress for 3 rounds (same finding unaddressed 3×) **OR** budget cap **OR** an HITL checkpoint is hit |

## The proof: zero blocking findings AND mergeable, default-FAIL

"Healthy" is not "I replied to the last comment." It is **two conditions
observed together from `gh`**: the PR has zero *open, actionable, blocking*
review comments, **and** GitHub reports it mergeable (rebased onto base, CI
green). Assume the PR is **not** healthy until a fresh fetch proves both — that's
the default-FAIL stance, and it's why every pass *re-fetches* rather than
trusting last pass's verdict. A loop that stops after answering one comment ships
a PR that picked up three new ones and went stale behind a base push.

Name the artifact explicitly: a `gh pr view --json mergeable,reviewDecision`
plus the open-comments count from `git-pr-feedback`'s fetch (see
`references/scheduling.md` for the exact query). Both must read clean *in the
same pass*.

## Step 1 — One pass = one git-pr-feedback cycle

The per-pass work **is** [`git-pr-feedback`]: identify the PR, fetch inline +
issue comments + review summaries (paginated), triage each by author and
category, address what's clear, reply on GitHub. **Do not re-document or
re-implement that** — invoke it. babysit adds only the loop discipline around it:
one root-cause change per pass, then re-check the *whole* PR state. If the base
branch moved and the only blocker is staleness, the pass is a routine rebase (not
a finding fix). The full per-pass algorithm and the handoff are in
`references/scheduling.md`.

## Step 2 — Schedule it with /loop (the watcher, not /goal)

Per `loop-controller` Step 1: this is a **watch/poll** job — you wait for review
activity to *change* on a cadence — so the primitive is **`/loop`**, the
scheduler, **not** `/goal` (which pushes to a finish line). The recipe is the
documented daily driver:

```
/loop 5m /babysit
```

`/loop` is **session-scoped, expires after ~3 days, and does not catch up** on
missed intervals — those mechanics (and the `loop.md` self-paced variant) live in
`loop-controller`'s `references/primitives.md`; don't re-document them. What goes
in `loop.md` and how to scope the run to one PR are in
`references/scheduling.md`.

## HITL is load-bearing for this loop

babysit runs **only inside the reversible boundary** unattended. The irreversible
or human-facing actions are **HITL checkpoints — never autonomous**:

- **Force-push / rebasing a shared branch** — pause. A fast-forward push of your
  own commits is fine; a history rewrite of a branch others may have pulled is
  not.
- **Resolving or replying to a *human* reviewer's conversation** — pause. A
  bot/Copilot nit can be answered and resolved unattended; a human's thread is a
  conversation, and **you do not argue with a reviewer inside a loop.** On any
  substantive disagreement with a human reviewer, stop and surface it.
- **Merging** — never. babysit does **not** auto-merge, full stop. Reaching the
  proof (zero blocking + mergeable) means *ready for the human to merge*, not
  "merge it."

Within the boundary — addressing Copilot/bot nits, routine fast-forward rebases,
re-running the gate, fast-forward pushes — it is AFK-safe. The full AFK-safe vs
pause table is in `references/scheduling.md`.

## Guardrails specific to this loop

Inherits the full stack from `loop-controller` → `references/safety.md`. The caps
this loop sets:

- **Poll / iteration cap** — `/loop`'s ~3-day session expiry is the outer bound;
  set an inner per-PR pass cap (default ~20) so a wedged PR doesn't burn the
  whole window. Hitting it is a *stop-and-escalate*, not a reason to loosen the
  proof.
- **No-progress detection** — if the **same blocking finding** survives **3
  consecutive passes** (addressed but the reviewer/check still flags it, or it
  can't be resolved within the reversible boundary), stop and surface it. Three
  passes on one finding means it needs a human, not a fourth attempt.
- **Budget cap** — a watch loop that fires every 5 minutes for days adds up;
  enforce a token/cost ceiling that *terminates* the loop (read it from
  `.claude/profile.yaml` when present), not just warns.
- **Never cheat the proof.** Don't mark a thread resolved without addressing it,
  don't dismiss a human reviewer's comment to clear the count, and don't merge to
  make "mergeable" moot. A green that came from silencing a reviewer is a
  *finding*, not a win.

## Choosing the driver primitive

`/loop 5m /babysit` is the scheduler. The *per-pass* exit (this pass made one
clean, reversible change and re-checked the PR) is provable from `gh` output, so a
pass can run under auto mode unattended within the HITL boundary above. The loop
as a whole has **no `/goal` finish line** — it watches until you stop it or a stop
condition fires.

## Long-run hygiene (wired per loop-controller Step 6)

This loop runs unattended for days, so the Claude 5 long-run rules are part of
its contract, not inherited ambience (drop-in text: `model-adaptation` →
`references/long-run-hygiene.md`):

- **Evidence-backed progress** — every per-pass report line (finding addressed,
  rebase done, gate green) traces to a tool result from *that pass*: the `gh`
  query output, the gate's exit code, the push result. Never narrate a fix the
  re-fetch didn't confirm.
- **Don't end a pass on a promise** — a pass ends with the change made and the
  whole PR state re-checked, or at an explicit HITL stop; never with "I'll
  rebase next pass" and no action. The autonomous-operation reminder applies
  while the user is away — the HITL checkpoints above are the only sanctioned
  pauses.
- **Budget is a harness decision** — the cost ceiling reads from externalized
  state (`.claude/profile.yaml`); don't surface a remaining-token countdown to
  the working pass, and never summarize-and-quit on a phantom context worry.
- **Effort per pass** — routine nit/rebase passes run at `medium`/`high`;
  reserve `xhigh` for a genuinely hard finding (tiering: `model-adaptation`).

## Reference files

- `references/scheduling.md` — the per-pass algorithm and the `git-pr-feedback`
  handoff, the scheduling recipe (`/loop 5m /babysit`, what to put in `loop.md`,
  scoping to one PR, the exact `gh` proof query), and the HITL boundary table
  (what's AFK-safe vs what pauses).

[`loop-controller`]: ../loop-controller/SKILL.md
[`git-pr-feedback`]: ../../git/git-pr-feedback/SKILL.md
[`git-pr`]: ../../git/git-pr/SKILL.md
[`git-commit`]: ../../git/git-commit/SKILL.md

