agentleFS
aaroncohnaaroncohn/openspec-conductor-powerups/skills/hq/SKILL.md

hq

Skill1 starsChanged 10 days agoMITView on GitHub

Coordinate every other Conductor workspace of this repo whose OpenSpec change has been proposed, messaging their Claude sessions directly and keeping them moving until each change is built, tested, merged into main with green CI and archived, then promote main to production. Answers their questions on the user's behalf, and sends decisions to revisit, tests only the user can do, and actions only the user can do (secrets, accounts, payment details) to separate Open Decisions, Open Tests and Open Actions workspaces, which present them one at a time. Works in local and cloud Conductor workspaces. Run with `/babysitter:hq`, optionally followed by the workspaces or milestones to cover, --mode cautious|standard|fast|hyperspeed, --auto-prod or --stop-after merged|dev.

The file

Show its rules and text

We split this skill into the rules it gives an agent

19 rules. About 0 are common, 10 are distinctive, and 9 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈10

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 9

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    If safe-to-archive is installed, it has run in the change's workspace and its verdict is in the final report.

    line 55
  2. Distinctive:

    Only one babysitter may drive a repo's workspaces.

    line 61
  3. Very specific:

    If a tool for proposing a session goal is available, propose this condition with it (trimmed to match --stop-after, if given).

    line 73
  4. Very specific:

    If the user named workspaces or milestones after /babysitter:hq, cover exactly those.

    line 81
  5. Very specific:

    Before the first message, back up Conductor's database: sqlite3 "$CONDUCTOR_DB_PATH" ".backup …

    line 93
  6. Distinctive:

    PR:: follow the repo's conventions (title, body sections, commit author, CI labels).

    line 155
  7. Distinctive:

    Don't: run the full CI suite on main or touch production: the coordinator does that once everything is in.

    line 157
  8. Distinctive:

    Log: after each step (tasks done, tests run, PR opened, merged, archived) and each decision you made without asking, add a line, dated in …

    line 161
  9. Very specific:

    Never carry a stage over from state.py or an earlier digest without re-checking it.

    line 168
  10. Distinctive:

    Overlap: when one change lands, tell the remaining sessions what moved on main that touches their files.

    line 185
  11. Distinctive:

    New workspaces and stage changes: when the re-scan finds them:

    line 187
  12. Distinctive:

    If there's nothing worth posting right away (step 6), restart the watcher without posting.

    line 191
  13. Very specific:

    Stop babysitting: when the user says to stop babysitting a workspace, stop messaging and watching it, mark it (state.py workspace set …

    line 192
  14. Very specific:

    Don't poll in a loop yourself.

    line 194
  15. Distinctive:

    ETA: when it should be merged, as a duration and a time ("~2 h, around 4 pm EST"), or "on you" when it's waiting on the user

    line 244
  16. Distinctive:

    When the choices aren't a fixed set, still offer the likely answers as options.

    line 324
  17. Very specific:

    Action done: check it took effect where you can (the variable is listed, the deploy picks it up, the page responds), state.py item set <ID> …

    line 343
  18. Very specific:

    Never run login/logout for any CLI and never write secrets to files.

    line 350
  19. Distinctive:

    Don't rename branches, and don't archive Conductor workspaces.

    line 352

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

babysitter

The user has finished /opsx:explore and /opsx:propose in one or more other Conductor workspaces and wants the features shipped without more involvement. This session is the coordinator. Each workspace's own Claude session keeps doing its own work, with its explore context intact. The coordinator sends instructions straight into those sessions, answers their questions on the user's behalf, nudges them when they stall, and owns the steps that span workspaces: CI on main, the production release, and the final report.

Fully autonomous: never wait on the user for anything a session can do or decide. Only actions that need the user's own accounts go to the user (see step 5), and blocking decisions wait for them ("Blocking or batch"); so does production, unless --auto-prod was given.

Who "the user" is. The person who ran /babysitter:hq. If the project names more than one owner (in AGENTS.md/CLAUDE.md, or in the docs they point to), each ⚠️ BLOCKED item and each Open Actions, Open Decisions or Open Tests item says who should answer it when that's clear (for example, the owner of that area, or the person who made the original decision). When it isn't clear, it's the person who ran /babysitter:hq.

Local or cloud. If CONDUCTOR_IS_LOCAL is 0, this is a cloud workspace: the other workspaces run in their own sandboxes, so read cloud.md (next to this file) and use it for finding the workspaces (step 1), messaging them (step 3), and watching them (step 4). Everything else is the same.

Locally, message sessions with conductor-local.py (next to this file), so each message and the session's reply show in that workspace's chat. Claude's own SendMessage reaches the session too, but Conductor doesn't record those turns, so the workspace chat stays blank. The script queues messages in Conductor's own outbox, which is undocumented: a Conductor update can break it, so fall back to SendMessage when it fails (step 3).

main below means the repo's default branch: $CONDUCTOR_DEFAULT_BRANCH if it's set, otherwise the one origin/HEAD points to. conductor-local.py scan works it out the same way and prints it as base.

Options

By default the babysitter goes all the way to production, but asks once first: before promoting (step 7.4) it posts what's going out (PRs, database migrations) and waits for the user's go. The user can change that after /babysitter:hq, as a flag or in plain words ("don't ask before prod", "stop after dev"):

  • --auto-prod: promote to production without asking.
  • --stop-after merged: stop once every change is merged and archived. Skip step 7: no full CI run on main, no dev check, no production release. Archive-blocking tasks that need a deployed environment stay open and go in the report.
  • --stop-after dev: do step 7 up to and including dev (full CI on main, dev verified, archives merged), then stop before production.
  • How often to post digests (step 6), in plain words, e.g. "update me every 15 minutes", or "only when something changes" (digests: on change), the cheap setting: no digest on a quiet half hour, so fewer scans and fewer tokens. Only the user picks it; never switch to it yourself, e.g. because nothing is building; /babysitter:status-check gives the full digest with the table any time. The default is every 30 minutes; the first run in a repo asks whether the user would rather have every 15 minutes, every hour, or only on change (see "Mode").
  • How often to release (step 7), in plain words, e.g. "release whenever something's ready" or "once a day". The default is at most twice a day.

Repo defaults. A ## babysitter section in the project's AGENTS.md/CLAUDE.md can set these for every run (e.g. mode: fast, stop after: dev, release: once a day, digests: every 15 minutes, Timezone: America/New_York). The user's flags and words for this run win over it.

Mode

The mode says how much the babysitter does on its own. Four, from careful to all-in:

ModeWhat's blocking (waits for the user)MergesProduction"Go" for sessions (step 4)ReleasesStuck session
cautiouseverything in "Blocking or batch", plus every merge to main and every decision that's hard to reverseasks firstasks firstno: the user gives itat most once a dayprod it, then tell the user
standard (default)as written in "Blocking or batch"on its ownasks onceyesat most twice a dayprod it, then ⚠️ STOPPED
fastmoney, security or privacy, data loss, migrationson its ownwithout asking (--auto-prod)yeswhenever something's readyprod it, then ⚠️ STOPPED
hyperspeedmoney, security or privacy, irreversible data loss; everything else is decided and logged to Open Decisionson its ownwithout askingyeswhenever something's ready; /babysitter:safe-to-archive and the archive PRs run alongside the release, not before ittake over right away (Rules), no prod first

A flaky CI job on main is re-run once without asking in every mode (step 7.1). Pick the mode this way, in order: --mode <name> or plain words after /babysitter:hq ("go fast", "be careful") for this run; else mode: in the repo's ## babysitter section; else ask, once, the first time babysitter runs in this repo, in its own short message that explains the four modes in two lines each (what it decides alone, what it asks you about), recommends standard, and asks which to use. In the same message, ask how often they want digests: every 30 minutes is the default; would they rather every 15 minutes, every hour, or only when something changes (cheapest; /babysitter:status-check any time for the full picture)? When they answer, suggest adding mode: <name> and digests: <interval> to the ## babysitter section so the next run doesn't ask. Until they answer, run as standard with digests every 30 minutes. Explicit flags (--auto-prod, --stop-after, a release cadence) win over what the mode implies.

Record the mode and the other options in the state file (state.py option set mode fast, option set digests "every 15 minutes", step 2) and apply them to the goal, the "Done means" list, and the final report. Name the mode in the first message and the final report.

Done means

For every in-scope change:

  1. Its PR is squash-merged into main (rebased on the latest main first).
  2. CI has passed: quick checks on the PR, plus the full suite on main after the last merge.
  3. It was tested as far as an LLM can, and the suites that ran are listed in the PR.
  4. It's archived (/opsx:archive with specs synced) in a separate openspec-only PR that is merged.
  5. If safe-to-archive is installed, it has run in the change's workspace and its verdict is in the final report.

Then (unless an option says to stop earlier) the latest main is verified on dev, promoted to production, and verified there, and the final report has been posted.

Before anything else: one HQ per repo

Only one babysitter may drive a repo's workspaces. Check first, before the goal, the mode question or any message:

git fetch origin -q
python3 <this skill's dir>/conductor-local.py scan > .context/scan.jsonl
python3 <this skill's dir>/state.py other-hq < .context/scan.jsonl

In the cloud, see cloud.md. If other-hq exits non-zero, stop here: change nothing, and tell the user "Babysitter HQ is already open for this repo: <where>. Use that one (/babysitter:keep-going if it's paused), or archive it and run /babysitter:hq here again." If the scan itself fails, say you couldn't check, and carry on.

0. Set the goal

If a tool for proposing a session goal is available, propose this condition with it (trimmed to match --stop-after, if given). Otherwise print it for the user to paste, and carry on without waiting:

/goal Every workspace in .context/babysitter.json has its change merged into main and archived, full CI on main is green after the last merge, the latest main is promoted to production and verified, and the babysitter final report (with the Open Decisions, Open Tests and Open Actions counts) has been posted; or babysitter's most recent message starts with "Babysitter is paused."

1. Find the workspaces

If the user named workspaces or milestones after /babysitter:hq, cover exactly those. Otherwise detect them:

.context/scan.jsonl, from the check above, has one JSON line per open workspace of this repo (conductor-local.py scan makes a fresh one). Each line has the workspace's name, path, branch, chat session id and status, its OpenSpec changes that aren't archived on origin/main, its PR (the open one, otherwise the newest: number and state), and its stage (see "Stage in the workspace name"). It only reads Conductor's database. If it fails, fall back to git worktree list --porcelain and git ls-tree --name-only origin/main openspec/changes/archive/, and work these out by hand.

A worktree other than this one is in scope when openspec/changes/ (skip archive/, include uncommitted files) has a change that isn't archived on origin/main. It's also in scope when it has work that isn't on origin/main (uncommitted changes, an open PR, or commits whose content isn't on origin/main), or when its session last stopped asking whether to commit, open a PR or merge: drive that work to merge too. Other worktrees are still exploring. Leave them alone and list them as skipped.

The scan gives each worktree's chat session (the tab open in that workspace); for one workspace, python3 <this skill's dir>/conductor-local.py session <worktree path> does the same. The session's transcript is the newest .jsonl in ~/.claude/projects/<worktree path with every character that isn't a letter or digit replaced by ->/. Read its last assistant messages to see where it stopped:

jq -r 'select(.type=="assistant") | .message.content[]? | select(.type=="text") | .text' <file> | tail -20

Before the first message, back up Conductor's database: sqlite3 "$CONDUCTOR_DB_PATH" ".backup '$HOME/conductor-backups/conductor-<timestamp>.db'" (make the folder first). Tell the user where the backup is, and that your messages will appear in each workspace's chat starting with "Via Babysitter:".

Then name this workspace Babysitter HQ, so the user can find it in the sidebar: the same sqlite3 update as in "Stage in the workspace name", with this worktree's path.

Then put each workspace's stage in its name (see "Stage in the workspace name"), skipped ones included.

Also learn the repo's conventions before the first message: CI workflows and labels (which checks are quick and which are full, how the full suite is triggered), AGENTS.md / CLAUDE.md / README rules for PRs and commit authors, how past archive PRs looked (gh pr list --state merged -L 10), and how dev and production deploy and get verified.

If the repo has values two sessions could both claim (ordered migration timestamps, sequence or build numbers, a shared counter), hand each session its value in the brief and keep the list in .context/babysitter-notes.md. Two sessions picking the same migration timestamp costs each a rebase, a fix and a re-test.

2. Keep a state file

state.py (next to this file; python3 <this skill's dir>/state.py) keeps .context/babysitter.json, so IDs, counts and the workspace table come from a script, not from memory. Never edit the file by hand. It holds:

  • options: state.py option set <key> <value> (mode, digests, release, stop-after, tz).
  • one row per workspace: state.py workspace set <name> --stage apply --effort M --progress "PR open, checks running" --next "rebase and merge" --eta "~2 h, 4 pm EST" --monitoring yes --pr 12 --waiting "<what it's waiting on>". Set only the fields that changed. --gone when a workspace is archived. Locally, conductor-local.py scan | state.py sync-scan fills in name, stage, PR and session for every open workspace and marks the missing ones gone; run it before every digest. In the cloud, see cloud.md.
  • every queue item (step 9): state.py item add OD "<a few words>" --grade normal --workspace <name> prints its ID; state.py item set OD017 --status answered --note "<the answer>"; state.py item list --open.
  • digest times: state.py digest-posted after each one; state.py last-digest.
  • the digest itself: state.py digest prints the whole digest to fill in (step 6).
  • workspaces to take over: state.py adopt (step 4).
  • the merge lock (step 4): state.py merge ready|next|release|prodded|show.

state.py show prints all of it, readable. Run it after a context compaction, before acting, and read step 4's re-scan and step 6 again: long runs lose them. Keep notes that don't fit a field (what a session said, what you told it) in .context/babysitter-notes.md, by hand.

Times are in the user's timezone. Every time you write, in this chat, in messages to sessions and queues, in the state file and in logs, is in the user's timezone, 12-hour with the zone's current abbreviation: "7:45 pm EDT", never UTC. Work out the zone once, before you first write a time (also when you switch to this skill partway through a run), and keep its name in the state file (e.g. America/New_York):

  • Locally: the Mac's zone, from readlink /etc/localtime (it ends in the name).
  • In the cloud: the sandbox's clock is on UTC, which is never the user's zone. Use a timezone the project's AGENTS.md/CLAUDE.md names. Otherwise ask the user right away, in its own short message: "What timezone are you in, so I can give times in it? e.g. New York". Until they answer, say times relative to now ("in about an hour"). Once they answer, suggest adding a line like Timezone: America/New_York to AGENTS.md, so the next run doesn't ask.

Get the current time with TZ=<zone> date '+%-I:%M %p %Z' | sed 's/AM/am/;s/PM/pm/'. The abbreviation follows daylight saving by itself (EDT in summer, EST in winter).

Stage in the workspace name

Start each workspace's name with its OpenSpec stage, so the sidebar shows where it is: explore-, propose-, apply- or archive- (e.g. m10-alerts becomes apply-m10-alerts). Set it in step 1 for every workspace of the repo except this one and the Open Decisions, Open Tests and Open Actions workspaces (step 9), and rename again whenever a workspace's stage changes:

StageWhen
exploreno change that isn't on origin/main yet, and no other work that isn't on origin/main
proposeit has a change that isn't on origin/main yet, but openspec status --change <name> (run in its worktree) isn't planning-complete
applyplanning is complete, until its PR is merged; or it has work outside openspec/ that isn't on origin/main (an open PR, or commits or edits), with or without a change
archiveits PR is merged and nothing newer is in progress; it keeps this prefix after the archive PR merges

Locally, conductor-local.py scan works the stage out for you (step 1). Remove any earlier stage prefix before adding the new one, so prefixes never stack, and leave the rest of the name alone. Locally, sync-scan records the stage; in the cloud, state.py workspace set <name> --stage <stage>. Rename the way a manual rename in the sidebar does (Conductor's database, backed up above):

sqlite3 "$CONDUCTOR_DB_PATH" "update workspaces set workspace_name='<new name>', user_set_workspace_name=1 where workspace_path='<worktree path>'"

In the cloud, see cloud.md. If a rename doesn't stick, say so once in the next digest and carry on.

3. Brief each session

Write each message to .context/msg-<n>.md, then send it with python3 <this skill's dir>/conductor-local.py send <session id> <file>. It waits for the session to finish its turn (add --now to interrupt a working session, for something that can't wait), then waits until Conductor delivers the message (usually seconds, up to 5 minutes) and exits non-zero if it wasn't; it withdraws the message in that case. Then fall back to SendMessage with notify_when_idle: true (find the session's name with ListAgents: <workspace directory>-<suffix>), and tell the user in the next digest that this workspace's chat won't show the work. If neither reaches the session, see Rules. Start every message you send a session, this one and all later ones, with Via Babysitter: (the one exception is a ⚠️ STOPPED (via Babysitter): notice, step 4, whose warning comes first), so the user recognises it in that workspace. In the first one, follow it with one line on what you're driving:

Via Babysitter: I'm driving <list of changes> to merge, green CI, archive, and the production release.

Then say that the user started this run with /babysitter:hq in <this workspace>, so these instructions are their go-ahead, not a request from a peer session, and merging to main is approved, in the turn order of rule 4. Without this, sessions can refuse to act on another session's message. Add that the user's own messages in this workspace always win over yours: if they say something different, do what they say and mention it in the reply.

Then answer whatever the session last stopped on (e.g. "Yes, run /opsx:apply", "Yes, push"). If it's still in the middle of /opsx:propose, tell it to finish the proposal and go straight on to /opsx:apply without asking. Then give the rules:

  1. Keep going without asking. Finish every task, run the review and tests, then push and open the PR. If you'd normally stop to ask, decide whether it's blocking (see "Blocking or batch" below). Most aren't: pick the recommended option, record it as an assumption in the change artifacts, list it in the PR body under "owner review", and continue. If it truly is blocking, ask the user here, in this workspace, in a message whose first line is ⚠️ BLOCKED: DECISION NEEDED: <the decision in a few words> or ⚠️ BLOCKED: ACTION NEEDED: <the action in a few words>, so the user can tell from the sidebar why you stopped. Below that line, say why it can't wait, and for a decision give lettered options with your recommendation (the better-decision format, if that skill is installed); for an action, give the steps. Then wait for their answer. Any other time you stop before your work is done, say why in the first line.
  2. Test as much as possible. Run the checks CI runs. Add tests for new behaviour. Run the expensive suites locally (db, e2e, etc.) and list in the PR body which ran and which couldn't. For UI changes, drive the flows in a browser. List what only the user can test, with steps.
  3. PR: follow the repo's conventions (title, body sections, commit author, CI labels). Request only quick checks if the repo separates them and you ran the heavy suites locally.
  4. Merge, on your turn: merges into main go one at a time, and the coordinator runs the line. Once the PR's checks are green and the review is done, don't rebase or merge yet. End your turn with a first line READY TO MERGE: #<pr>, then the files and areas it touches, and wait for Via Babysitter: your turn to merge. Then rebase on the latest origin/main once. Re-run only the checks the rebase can affect: the quick checks, plus the suites covering files that changed on both sides. Don't run the full local suites again just because main moved. Then gh pr merge --squash. Resolve conflicts keeping both sides. Reply with a first line MERGED: #<pr> (or MERGE FAILED: <why>) and what you touched. The archive PR (rule 6) doesn't wait for a turn.
  5. Don't run the full CI suite on main or touch production: the coordinator does that once everything is in.
  6. Archive: after the merge, run /opsx:archive (sync the specs) and open its result as a separate openspec-only archive PR ( plus whatever past archive PRs did, e.g. roadmap or notes updates) and merge it once its checks pass. If CI skips openspec-only PRs, run openspec validate --all --strict and merge it yourself. Exception: a check that only an automated step can do against a deployed environment (a cron, a webhook, a real DNS record) keeps the archive open until the coordinator says the deploy is live. A check that needs the user's own eyes or devices never blocks an archive: archive now, note it in the change and the roadmap row as "owner checks still open", and tell me so it goes to Open Tests. If it fails later, it's a follow-up PR.
  7. Setup only the user can do (secrets, dashboard settings, third-party accounts): don't block on it unless it's truly blocking (see below). Make sure nothing hard-fails without it, put the steps in the PR body under "owner setup", and tell me right away.
  8. Reply with the PR URL(s) when merged.
  9. Log: after each step (tasks done, tests run, PR opened, merged, archived) and each decision you made without asking, add a line, dated in the user's timezone (<the zone, e.g. America/New_York>), to .context/babysitter-log.md in your workspace, with PR links.
  10. Last: once the archive PR is merged, if the safe-to-archive skill is installed (in your skill list as safe-to-archive, or babysitter:safe-to-archive as a plugin), run /babysitter:safe-to-archive as your final command. Fix any blocker that's your own work (e.g. commit and push), run it again, and reply with its verdict. Don't archive the workspace.

4. Watch and keep them moving

  • Run python3 <this skill's dir>/conductor-local.py watch <session id> ... from this worktree, in the background (Bash run_in_background), for every session still in flight (with none, it still watches for new workspaces), adding --ignore "$(python3 <this skill's dir>/state.py ignored)" for the workspaces you were told to stop babysitting. It stays quiet until there's something to act on, then exits and prints what: a session finished a turn, a session has been working for 30 minutes without a new message, or its scan (step 1, every 10 minutes) found a workspace that's new, gone, at a new stage, or has a new turn while you aren't watching its session. Give it a background timeout that ends when the next digest is due (step 6) or the merge lock's 45 minutes are up, whichever is sooner, at most 2 hours (Bash timeout in milliseconds), so you wake to act. When a session finished a turn, read the end of its transcript, check its PR (gh pr view <n> --json state,mergeStateStatus,statusCheckRollup), act, and start the watcher again. For a session on the SendMessage fallback, notify_when_idle does this job; it's one-shot, so subscribe again with each reply.
  • Re-scan on every wake, before anything else. Every time you wake, for any reason (the watcher exiting or timing out, a digest coming due, a user message, /babysitter:status-check, /babysitter:keep-going), re-scan all open workspaces of the repo before you act, post or restart the watcher. Locally: mv .context/scan.jsonl .context/scan-last.jsonl, a fresh conductor-local.py scan > .context/scan.jsonl, state.py sync-scan < .context/scan.jsonl, then read the newest messages (step 1) of every workspace you aren't driving, skipping one whose updated matches scan-last.jsonl. In the cloud: watch.py scan (cloud.md section 1). A workspace's last few user and assistant messages are the source of truth for where it is: did it run /opsx:propose, /opsx:ff, /opsx:continue or /opsx:apply, has it finished planning, did it push, does it have a PR (gh pr list --head <branch>, or gh pr list --search)?
    • Never carry a stage over from state.py or an earlier digest without re-checking it.
    • Take over every workspace on the ADOPT NOW line, every time, before you post anything. This is the rule HQ most often broke. Locally sync-scan ends with that line, and in the cloud watch.py scan does; state.py adopt prints the list again. It names each workspace whose user typed /opsx:propose (or /opsx:ff, /opsx:continue, /opsx:apply), or whose files are past exploring, and that you aren't driving yet. That includes one that's still in the middle of proposing, and one the user is working in themselves. Adopt it as in "New workspaces and stage changes", and don't wait for the user to say so. The line only clears once you state.py workspace set <name> --monitoring yes (or no, when the user said to stop babysitting it). Never post "I'll take it over once you propose" about a workspace you haven't checked in this scan.
    • Then read every workspace on the CHECK NOW line, printed right after it. It names clues that a workspace may be proposing although nobody typed the command: the session offered to start /opsx:propose and the user replied (e.g. "yes", or the letter of that option), or the session named /opsx:apply, which is what it usually says once a proposal is done. Read its newest messages. If the user accepted, or it has a proposal (a tasks.md, or it says planning is done), take it over as above. If not (the reply was "not yet", or it only explained the workflow), state.py workspace set <name> --not-yet, so only a new clue brings it back.
    • An explore row never says "on you" unless that workspace's latest message really is waiting on the user.
    • Then run the merge lock (below). If nothing needs posting (step 6), stay silent.
    • The only exception is the "Paused" rule below: while paused, re-scan only when the user asks where things stand.
  • It asked something: first decide whether it's blocking ("Blocking or batch" below). If not, answer as the user would: the recommended option, recorded as an assumption. Then add it to Open Decisions (step 9) so the user can review it later, and mention it in the next digest. If it is blocking, check that the session's last message starts with the ⚠️ BLOCKED: line (rule 1). If it doesn't, tell it to post one now and wait. Then tell the user right away in this chat (step 6), and keep it under Waiting on you until it's answered.
  • It's waiting for a "go": when a session stops for a go-ahead ("say go when ready", "shall I continue?", "ready to push when you are"), you have the user's authority to give it: reply Via Babysitter: go ahead and say what it was waiting for, so it doesn't ask again. The one go that stays the user's is production (step 7.4), unless --auto-prod or the mode says otherwise. READY TO MERGE isn't one of these: it goes through the merge lock. If it said it will ask for a go once something finishes (a CI run, a deploy, another PR landing, an action from Open Actions coming back "done"), watch that thing yourself, and the moment it's ready tell the session so: "Via Babysitter: <what> is ready, continue". Don't let a session sit on a condition that's already true.
  • Its PR is ready and it's gone quiet (checks green and mergeable, or an openspec-only PR the repo runs no checks on, and no reply for 10 minutes): if it's openspec-only, or it holds the merge lock and is already on the latest main, merge it yourself (gh pr merge --squash), tell the session what you did so it carries on with the next step, and log it in that worktree's .context/babysitter-log.md. Prodding a session to run one command costs more than the command. Any other PR joins the merge line as if it had posted READY TO MERGE.
  • Merge lock: one merge at a time. Sessions build, test and open PRs in parallel. Only the last step (rebase onto the latest main, re-run what that affects, merge) goes one at a time, so nobody tests against a main that another merge then changes. You run it in every mode, from the state file. Don't use GitHub's merge queue: it runs CI per queued PR, and Actions minutes are limited.
    • READY TO MERGE: #<pr>: gh pr diff <pr> --name-only | python3 <this skill's dir>/state.py merge ready <name> --pr <pr>. In cautious mode, ask the user first, and join the line only after their go. The digest's table shows the place in line by itself.
    • On every wake, after the re-scan: state.py merge next. It keeps one holder, and when the lock is free it picks the PR the most others overlap with, then the oldest. If it names a workspace, send it Via Babysitter: your turn to merge #<pr>, with what landed since its last rebase and which overlapping files to keep both sides of (e.g. "the build number moved on main: use main's value + 1").
    • MERGED or MERGE FAILED, or the re-scan shows the PR merged anyway: state.py merge release <name>, then merge next. After a failure, it joins the line again when it next posts READY TO MERGE.
    • Holder not merged after 45 minutes (state.py merge show): prod it once, as for a stalled session, and state.py merge prodded. If it still holds the lock at a later wake, merge release it, tell it to post READY TO MERGE again when it can, run merge next, and say so in the next digest.
    • No lock needed: archive PRs (openspec/ only), the queue workspaces, and a hotfix the holder needs because main is broken: that one merges straight away, ahead of the line.
  • It stopped and you can't tell why (no ⚠️ BLOCKED: line, no question, work not done; e.g. a long test run finished but it never woke up to read it): prod it once to check where it is and continue, or, if it's waiting on the user, to post its ⚠️ BLOCKED: line. If it still hasn't moved when the watcher next names it, or it's erroring, send ⚠️ STOPPED (via Babysitter): <what it was doing>. <what you tried>. <what the user can do, e.g. open the workspace and press continue, or restart the session> to that workspace, so that's the last thing the user sees there, and put it under Waiting on you (step 6).
  • Stay on the latest main: after every merge into main (a change or an archive PR), update this workspace: git fetch origin -q and git merge --ff-only origin/main (or git pull --ff-only). You never commit here, so it should fast-forward; if it can't, check out origin/main detached instead. Read specs, the roadmap and code from this up-to-date copy.
  • Overlap: when one change lands, tell the remaining sessions what moved on main that touches their files.
  • A session that won't take messages (the notice says the subscription expired, or a delivery notice says messages are held for approval): tell the user right away, as for a ⚠️ STOPPED workspace (step 6), and keep the others moving.
  • New workspaces and stage changes: when the re-scan finds them:

    • rename any workspace whose stage changed ("Stage in the workspace name");
    • adopt any workspace that has newly come into scope (the ADOPT NOW line, above). Brief its session (step 3) once it finishes its current turn (no --now), add it to the watcher, state.py workspace set <name> --monitoring yes, and mention it in the next digest (step 6).

    If there's nothing worth posting right away (step 6), restart the watcher without posting.

  • Stop babysitting: when the user says to stop babysitting a workspace, stop messaging and watching it, mark it (state.py workspace set <name> --monitoring no --waiting "stopped by user"), and don't adopt it again on a re-scan unless the user asks. Confirm in one line.
  • Paused (/babysitter:pause, or the user says to pause; state.py paused tells you): do nothing on your own until /babysitter:keep-going, or the user says to keep going or resume. No messages, merges, renames, adoptions, watcher or scheduled digests. If a notice or a finished session wakes you, end the turn with no text. If the user asks where things stand, answer with a digest from a fresh scan, opening with "Paused since <time>." The queues keep taking the user's answers; handle them on resume.
  • Don't poll in a loop yourself. Between events, end the turn quietly (step 6). For PR checks you're waiting on, gh pr checks <n> --watch is fine.

Blocking or batch

The goal is speed without lowering quality. So most decisions and actions don't stop the work: the recommended option is taken now and the user reviews it later, in batches. Only a few are blocking.

Blocking means getting it wrong would change what gets built in a way that's costly to undo, so it has to be settled before the work goes on. Examples:

  • a decision about scope, the data model or a migration, pricing or money, security or privacy, or something users will see that's hard to change once it ships
  • an action without which the work can't be built or tested at all, with no safe stand-in (a stub, a test key, a feature flag)

Batch is everything else: copy, naming, small UX choices, defaults that are easy to change later, follow-ups, and actions the work can ship without (it degrades gracefully until they're done). Batch items go to Open Decisions or Open Actions (step 9), and any change they lead to goes in a future PR.

When unsure, prefer batch if the choice can be reversed in a small later PR; otherwise blocking. A blocking item stays in the workspace where it came up: its session asks the user there, under a ⚠️ BLOCKED: first line (step 3, rule 1), and waits, while the other workspaces keep going. Record each blocking item: state.py workspace set <name> --waiting "your decision: <a few words>".

Big things first. Act like a product manager: the few items that move the release or change what users get come first, in your attention, in the digests and in the queues. Small, easily fixed or reversible things (a label, a default, a cosmetic test, a tidy-up) never hold up a merge, an archive or a release, and never wait their turn ahead of something that matters. Grade every item you send to a queue: release-blocking (the release waits on it), normal, or minor (easy to fix or reverse later). The queues present them in that order. If you catch yourself spending a digest on a minor item, or a session circling one, settle it with the recommended option, log it as minor, and move on.

5. User actions: send them to Open Actions as soon as they're known

When a session reports something only the user can do that isn't a decision or a test (an environment variable or secret to set, an account to create, a payment method to add, a dashboard setting, a DNS record), don't save it for the end. If it's blocking ("Blocking or batch"), it stays in that workspace under its ⚠️ BLOCKED: line and you tell the user right away (step 6). Otherwise send it to Open Actions (step 9) right away. Plan the production release so it waits for actions production needs, or confirm that nothing breaks without them.

6. Updates in this chat

The user wants to know, regularly, that everything is moving: what just got done, what's being worked on, and where they're needed. Nothing else. Post in this chat only at these moments, and stay quiet otherwise: end the turn with no text at all.

Right away, in two or three plain lines, when:

  • a new blocking decision or action comes up: what it is, why it holds things up, and the workspace to answer it in (where its ⚠️ BLOCKED: message is waiting)
  • a workspace is ⚠️ STOPPED (step 4)
  • something broke that the user would want to know about now: full CI on main fails, a deploy fails, production is rolled back
  • production is ready to go and needs the user's go (step 7.4)
  • in the cloud, the one-time question about the user's timezone (step 2)

That list is complete. Everything else waits for the next digest, however good the news: a PR opened, a merge, an archive, a session finishing early, a new explore started, an adopted workspace, a rename, an answer from a queue, and anything you told a session to do. "Two more explores started…", "X finished early…" or "X is merged" are digest material, never a message of their own. Never post a message of its own just to say that nothing needs the user, when the next digest is, what you checked, or what you asked a session to do ("I'm asking that session to renumber", "Restarted the watcher", "The other three are still testing"). A right-away message isn't a digest and doesn't move the digest clock.

Don't say what didn't happen, in a digest or anywhere else in this chat: no "Nothing needs you right now", "No answers since the last digest" or "Nothing new on the others". Leave that part out; a missing part means there's nothing to report. The one exception is a quiet digest's opening line (below).

Digests, as if the user walked into the room and asked "what's the latest on all this?". Post one every 30 minutes (or at whatever interval the user asked for), on the clock, and whenever the user asks ("what's the latest?", "status?", /babysitter:status-check). Keep posting them when nothing is building and every workspace is exploring: that's not a reason to skip one or to space them out. Only digests: on change, which only the user sets, skips quiet ones.

Write every digest from state.py digest, run after the re-scan (step 4) and after state.py workspace set for anything that moved. It prints the whole digest with the counts, the table and the next digest's time already in, and <...> for you to fill in. If it starts with ADOPT NOW, take those over first (step 4) and run it again. Never write a digest from memory, even hours into a run or after a compaction: the shape drifts. After posting one, state.py digest-posted. A digest is always the full shape below, table included; never a bare paragraph or a list of bullets on its own. When nothing moved since the last one, the first part is one line ("Quiet half hour: everything's still running, nothing finished") and the rest is as usual, so the user always has a current table. With digests: on change, post only when something moved, and still every section, table included. In this order:

  1. What happened, in a short paragraph or two of plain words, biggest thing first: what finished or moved since the last digest, said as what the product's users get and why it's better, e.g. "The profile-photo workspace opened PR #259. Photos keep their shape, there's a "replace photo" option, and the edit-photo popup is clearer." Fold in, briefly, anything you sorted out along the way ("It had taken a roadmap number another change already uses, so I asked it to move to the next free one"), workspaces you renamed, and each workspace you took over: "Babysitter is taking over <workspace name> now to keep it moving forward. You can tell me to stop babysitting it at any time."
  2. Waiting on you: one line per open blocking item or ⚠️ STOPPED workspace, with the workspace to go to. Leave it out when there are none.
  3. Working on now: a bullet per workspace you're babysitting that isn't done, the one that matters most to the release first: the feature in words (with its PR or roadmap number), what it's doing, what's next, and when you expect it merged, e.g. "Instant email sign-in (#252): one unrelated test failed, so it's being re-run on its own. Merged in about an hour, around 4 pm EST." Then one line for the whole run: when everything should be merged, and when it should release given the release cadence ("Everything merged around 6 pm EST; release in tomorrow morning's window").
  4. Critical path: the chain of things that has to happen, in order, before the next release can go out, each with who or what it's waiting on, and the link that's holding it up marked, e.g. "spam check: e2e suite (running, ~40 min) → rebase and merge → archive PR → full CI on main → dev → your go → production. Holding it up: the e2e suite." Work it out from the workspaces still open, the release cadence and the open blocking items; it's the longest chain, not every chain. One short list, or one line when only one workspace is left.
  5. Open actions: K · Open decisions: N · Open tests: M: the output of state.py counts, pasted as is (each count followed by its open IDs), plus one line on any answer that came back and what you did with it.
  6. The workspace table: the output of state.py table, pasted as is. Before running it: a fresh scan piped into state.py sync-scan (locally; in the cloud see cloud.md), then state.py workspace set for anything that moved. Its columns:
    • workspace: its name, with its PR number
    • stage: explore, propose, apply or archive
    • effort: S, M, L or XL, how big its whole task is next to the project's other changes. Use the roadmap's own size if it has one; otherwise estimate it once from the change's tasks and set it once, so it doesn't drift between digests.
    • progress: what's done so far; state.py table fills in waiting to merge (#2 in line) by itself
    • next step: what has to happen to finish, in a few words ("rebase and merge", "archive PR", "waiting on your decision in that workspace")
    • ETA: when it should be merged, as a duration and a time ("~2 h, around 4 pm EST"), or "on you" when it's waiting on the user
    • babysitter monitoring?: narrow, x for the ones you're babysitting
  7. The last line says when the next digest is due: "Next digest around <time>." (e.g. "around 7:45 pm EDT"). state.py digest fills it in from the interval.

Estimates. Whenever you say what's being worked on, say how long it should take. Base it on the effort column, the stage, and the pace you've seen in this run (how long similar steps took here: a test run, a PR's checks, an archive). Set each estimate with state.py workspace set <name> --eta; when the next digest comes, don't move it quietly: say it slipped and why ("the e2e suite took twice as long as last time"). Round to what you know: "about 2 hours" beats "1 h 47 min". With no basis, say "no estimate yet" rather than invent one.

Slash commands in backticks, everywhere you write one for the user or a session (/opsx:propose, /babysitter:safe-to-archive), so the chat shows the whole command; Conductor's chat cuts an unquoted one at the colon.

Plain words everywhere: name each feature in words, not just its roadmap ID ("2.2b, the spam check"). Leave out test counts, file names, task numbers, CI job names and internal labels unless something failed or the user has to act on them; then say what it means for the user. The only codes are the queue IDs (OA001, OD001, OT001, step 9), and each comes with a few words on what it is.

examples/digest.md (next to this file) shows a full digest and a quiet one; match its shape. The first message and the final report (examples/final-report.md) have the table too. Prose and the table do different jobs: the prose says what it means for the user, the table lets them scan every workspace at once. Each digest needs both.

Decisions you made for the user, tests only they can do, and actions only they can do don't go here: they go to Open Decisions, Open Tests and Open Actions (step 9).

7. After the last merge: CI on main, dev, production

  1. Run the repo's full CI suite on main once, the way the repo does it (e.g. gh workflow run <ci>.yml --ref main), and watch it to green. If a job fails before any test ran, or the failing test passed on its PR, re-run that job once yourself right away; don't hold the release on a session for it. If it fails again, or a test fails for the first time, have the owning session fix it forward with a normal PR. Flakes found during a run go in one fix PR at the end, not one per milestone.
  2. Confirm dev deployed and serves that commit (health endpoint, deploy workflow, or the URL the docs give).
  3. Tell sessions with deploy-dependent tasks that dev is live at <commit>. They run those checks, then archive (rule 6). Wait for every archive PR to merge and every /babysitter:safe-to-archive verdict (rule 10).
  4. Promote to production using the project's documented procedure (README/docs "promote"/"production", CLAUDE.md, memory, workflows on a production branch or tag). Note first what's going out, including DB migrations. Post that list and wait for the user's go, unless --auto-prod was given: then do it without asking. If no procedure is documented, stop and ask.
  5. Watch the production deploy to green and verify production serves the new commit. If it's broken, roll back as documented, tell the user, and fix forward.

Release once, after everything is in, not after each merge, and at most as often as the release cadence (Options; default twice a day). Adopting a workspace mid-run doesn't restart the clock: work merged after a release waits for the next window, unless the user asks for it now. With --stop-after merged, skip this whole step; with --stop-after dev, stop after item 3.

8. Final report

Your last message must contain everything:

  • Shipped: a table with one row per change: PR, archive PR, merged ✅, archived ✅. Then: full CI on main ✅ (run link), dev ✅, and production ✅ (commit, deploy link, URL verified, migrations applied). If an option stopped earlier, say where it stopped and what's left to release.
  • Skipped: workspaces not in scope, and any session that couldn't be reached.
  • Open actions: K · Open decisions: N · Open tests: M, each with its open IDs and a link or pointer to that workspace, and the answers that came back and what you did with them. Don't repeat the items themselves here.
  • Follow-ups: anything noticed along the way that isn't a decision or a test (e.g. an unexpected env var). Numbered, one line each.
  • Clean-up: each workspace's /babysitter:safe-to-archive verdict (✅ safe, or ⛔ with what's left), so the user knows which to archive in Conductor. If safe-to-archive isn't installed, say so and list the workspaces whose PRs and archive PRs are merged.

Keep watching Open Actions, Open Decisions and Open Tests after the report, and carry out answers as they come back (step 9). When all three reach 0 and every answer is handled, post a last plain-language wrap-up. Then, if safe-to-archive is installed, run /babysitter:safe-to-archive in this workspace as your final command.

9. Open Actions, Open Decisions and Open Tests

Actions only the user can do, decisions the user may want to revisit, and tests only the user can do each go to their own Conductor workspace, so they don't get mixed into this chat's updates. The user works through them in batches, at their own pace.

  • Open Decisions gets every decision you or a session made on the user's behalf that they might reverse, every "owner review" item from a PR, and any question you left for the user, as long as it's batch, not blocking ("Blocking or batch"). Send each one as soon as it's known.
  • Open Tests gets every test only the user can do. Send each one once its feature is live where the user can test it (dev or production), not before.
  • Open Actions gets every action only the user can do that isn't a decision or a test (step 5): secrets and environment variables, accounts, payment methods, dashboard settings, DNS, as long as it's batch, not blocking. Send each one as soon as it's known. Ones the release waits on go first.

IDs. Every item gets an ID when you send it, unique within the repo for as long as the queues live: OA001, OA002… for actions, OD001… for decisions, OT001… for tests (three digits, then four if a repo ever gets there). The ID is how the user, the queue and the digests refer to it, with a few words on what it is ("OD016, the spam-check threshold"); never a running position like "7 of 3". state.py item add hands out the next number. At the start of a run, before the first item, read the highest ID each existing queue workspace has seen (its transcript, or ask its session "what's the highest ID you've been sent?") and state.py item seed OD <that number>, so a new Babysitter HQ never reuses a number. With no queue workspace, numbering starts at 001.

An existing queue from an older babysitter (its first message has no IDs, items say "Decision 3 of 5") keeps working, but bring it up to date before sending it anything: send it the queue prompt below as a "Via Babysitter:" message, and ask it to give each item it still has open an ID from 001 up, oldest first, grade each (release-blocking, normal, minor), and reply with the list. Add each to the state file (state.py item add, in that order, so the IDs match), and numbering continues after them. Items already answered there stay as they were.

Find or create the workspace. Before sending an item, look for an open workspace of this repo named Open Actions, Open Decisions or Open Tests. If there is one, send the item to its session. If there isn't (e.g. the last one was finished and archived), create a new one with the queue prompt below as its first message, then send items to it. A queue lives where this workspace lives, on this repo. Locally, create it the way new-batch-explore does (python3 <this skill's dir>/conductor-local.py new-dialog <prompt file>, which the user confirms with Enter, then the name set in Conductor's database; never write a conductor:// link by hand). The Create dialog opens in the organization the switcher at the top left of Conductor is on: on a cloud organization it creates a cloud workspace, and the link's path can't select this local repo. new-dialog won't open it on a cloud organization: if it says so, ask the user to switch to the organization that shows this repo, wait for them, and run it again. It waits up to 3 minutes for the new workspace, so give the shell call that long, and tell the user: "press Enter, after checking the dialog says Local and <repo>". It prints the new local workspace of this repo as JSON (id, path, session); name it and send it items only after that. If it exits saying one appeared on another repo, say so, ask the user to archive it, and try again. Never use the conductor CLI from a local workspace: it only creates cloud workspaces, and from a local one it can't tell which project you mean, so the queue lands on whatever cloud project it picks (it has happened). In the cloud, see cloud.md. Either way, before sending the first item, confirm the new workspace shows up in a fresh scan of this repo (conductor-local.py scan locally; workspace list --repo "$REPO" in the cloud). If it doesn't within a few minutes, say so to the user and wait; don't send items somewhere else. Never stage-rename these three workspaces.

Queue prompt (the first message of a new one; fill in this workspace's name):

You're the Open <Actions|Decisions|Tests> queue for `/babysitter:hq`, which runs in the workspace "<this workspace's name>". It will send you <actions only the user can do|decisions the user may want to revisit|tests only the user can do>, each starting with "Via Babysitter:". Don't change code or open PRs yourself: the babysitter carries out the answers.

- Present one item at a time, by priority: release-blocking first, then normal, then minor; oldest first within each. Wait for the user's reply before the next. If new items arrive while one is waiting, queue them, and let a release-blocking one jump ahead of what's queued.
- Every item arrives with an ID (OA001, OD001 or OT001 and up). Use it everywhere you refer to the item. Keep a ledger at the top of your mind: which IDs are open, which are done. Before each item, say how many are open and list them: "5 open: OD005, OD016, OD021, OD027, OD031. Next up, **OD005**: …".
- The items come from different milestones, so each one stands on its own: after the ID, the milestone and feature in plain words, the workspace it came from, and what was built and why this is open.
- Always offer skip.
- After each reply, write one line starting "Done:" (actions), "Answered:" (decisions) or "Result:" (tests) with the item's ID, the reply, and anything the user added, then present the next item. If asked for a status, or when `/babysitter:status-check` runs here, list the open IDs with one line each.
- When the last open item is answered, post a short, warm message that makes the user feel good: what they got through, what it unblocked, and that the queue is empty. If more items arrive later, start again.

Each item you send ("Via Babysitter: add <action|decision|test> <ID> (<release-blocking|normal|minor>): …") carries everything the queue needs. examples/queue-item.md shows how a queue presents one.

For an action:

  • the milestone and feature in plain words, the workspace it came from, and whether it holds up a merge or the release
  • why it's needed and what happens until it's done (e.g. "until then, suspicious messages keep going to possible spam")
  • directions from scratch: the exact service and account (and to confirm the signed-in account first), a direct link to the right page, numbered steps naming what to click, and what "done" looks like
  • the project's rules that apply (e.g. paste secrets into the service's web UI, never into chat; stay on free plans unless the user says otherwise)
  • when a browser can do most of it, a self-contained prompt to paste into a browser agent (Claude in Chrome or similar), with goal, exact account, steps, done-when, don't-touch and report-back (if the browser-handoff skill is installed, write it with that skill). Never put passwords or secrets in it.
  • what to reply when done: "done", plus anything the babysitter needs back (e.g. a public key or ID, never a secret), or "skip"

For a decision:

  • the milestone and feature in plain words, and the workspace it came from
  • one or two lines of context: what was built and why it's open
  • lettered options (a, b, c…), each with its trade-off in a few words, with the current choice marked as such
  • one option marked (recommended) with a one-line reason
  • "skip: keep the current choice"

When the choices aren't a fixed set, still offer the likely answers as options. If there's truly no sensible recommendation, say why. Accept a letter, a letter plus tweaks, or a free answer.

For a test: assume the user hasn't followed the build. They don't know the new screens, flags, test data, or what the feature is even called in the UI. Testing is tedious, so every test does two things: (a) gives cohesive, from-scratch instructions, and (b) offers a way to make the test faster and less annoying without making it less thorough.

(a) How to do it, from scratch. Write it so someone who never saw the change can follow it top to bottom without guessing:

  • the milestone and feature it covers, the workspace it came from, and one or two plain-language lines on what it does for the end user and why it matters
  • where to start: a direct link to the exact page (not the home page), the account or role to use, and where its login lives
  • setup, already done for them where possible (test data seeded, a flag turned on, a test account created), with anything left for them spelled out, including prerequisites like "the site must be on a paid plan" and how to get there
  • numbered steps that name exactly what to click or type and where it is on the page ("in the left sidebar, open more, then add a page"). Check the real labels and navigation in the code before writing them. Don't guess from the spec, and say so if you couldn't confirm a label.
  • what should happen at each check, quoting the exact on-screen text where there is one, and what a failure would look like
  • how to clean up afterwards (turn the setting back off, delete test data), if the test leaves anything behind

(b) A shortcut that keeps it effective. Offer at least one, ideally both, and say how much time each saves:

  • a self-contained prompt they can paste into a browser agent (Claude in Chrome, Codex's browser extension, or similar) that runs the steps from (a) and reports pass/fail with screenshots. Include the URL, account, steps, expected results, clean-up, and what to report back. Never put real passwords in it; use throwaway test values. If the browser-handoff skill is installed, write it with that skill.
  • or an offer to have it done for them (headless browser, API calls, curl for status codes and headers, database checks), leaving the user only the part that needs their eyes or their logins. Say exactly which part that is.

End with: reply "pass", "fail: <what happened>", or "skip". On a fail, the queue asks at most one follow-up if it helps pin the bug down (a screenshot, or exactly what they clicked).

Handle the answers. Watch the queue sessions like the others (step 4). When one posts "Done:", "Answered:" or "Result:":

  • Action done: check it took effect where you can (the variable is listed, the deploy picks it up, the page responds), state.py item set <ID> --status done, and continue whatever was waiting on it. If it didn't take effect, send a follow-up action saying what's still missing.
  • Kept, skipped, or passed: state.py item set <ID> --status answered|skipped|passed. A skipped action that holds up the release stays under Waiting on you in the digests.
  • Reversed decision or failed test: send the fix to the session of the workspace where that work happened, as a normal "Via Babysitter:" brief, and drive it to merge like any other change. Its tests go back to Open Tests once the fix is live. If that workspace is gone or archived, open a follow-up the same way (a new workspace with a self-contained brief), and babysit it.
  • Report it in the next digest, and update the counts.

Rules

  • Never run login/logout for any CLI and never write secrets to files. Follow the project's account, secrets and browser-profile rules, and pass the relevant ones on to sessions when they matter.
  • Don't edit files in other worktrees yourself. The sessions own their workspaces. Exception: a session is gone or unresponsive and the work would otherwise stall. Then do the step from its worktree (git -C <path>), log it in that worktree's .context/babysitter-log.md starting with Via Babysitter: (tell helper agents to do the same), and say so in the next digest.
  • Don't rename branches, and don't archive Conductor workspaces.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.