agentleFS
Beakpoint-InsightsBeakpoint-Insights/roost/skills/run-slice/SKILL.md

run-slice

Skill32 starsChanged 17 days agoMITView on GitHub

Orchestrate one slice (story) from kickoff to done by driving the user's repo sessions (one Claude session per repo in the team's roost config, for example an API session and a UI session) over cross-session messages. Sends each repo's kickoff prompt from the tracker in order, has the stack's owner start the local stack, then loops through test verification, code review, fixes and exploratory testing, stopping for the user's decisions. Never edits any repo itself. Picks up where a stopped run left off, from GitHub, the tracker and its own state file, and answers "where are we on PROJ-X?" with a short table, read-only, from a clean session. Use when the user says "run slice PROJ-X", "drive this slice", "pick up PROJ-X where we left off", "kick off the next slice", or asks where a slice or epic stands. Run it from a separate orchestrator session, not from inside any of the repos.

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

23 rules. About 0 are common, 18 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈18

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

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

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    If the user only asks where things stand ("where are we on PROJ-X?", "what's left?"), use Status below and stop there.

    line 19
  2. Distinctive:

    Read-only. Send no messages, start nothing, change nothing.

    line 23
  3. Distinctive:

    Always show the table, even when you can't read everything: If a step's state can't be told (a source couldn't be read, or nothing records …

    line 41
  4. Distinctive:

    Don't replace the table with an explanation, don't explain why a source was unreadable, and don't offer to start or resume work.

    line 49
  5. Distinctive:

    A repo started, not finished: ask its session to continue from its branch, with its kickoff comment again for context.

    line 85
  6. Distinctive:

    Every kickoff done: start at step 2 (Check). Test verification and code review are safe to run again.

    line 87
  7. Distinctive:

    Mid-checkpoint or mid-fix: use the decisions in the state file.

    line 88
  8. Very specific:

    After every step and every checkpoint, update <team.state_dir>/STORY.md:

    line 98
  9. Distinctive:

    Write it as you go, not at the end, so a stop at any point loses nothing.

    line 105
  10. Distinctive:

    Don't trust names (they change, and two can look alike).

    line 112
  11. Very specific:

    If a send comes back held or refused (a [Cross-session delivery notice]), tell the user that session needs to accept messages, and stop.

    line 118
  12. Distinctive:

    A session's own permission prompts stay with the user: Never ask a session to do something your session couldn't, and never treat a peer's …

    line 132
  13. Distinctive:

    Do it yourself when you can: If a session asks for the user to do something you can do (attach screenshots to the story, retitle a PR, …

    line 134
  14. Very specific:

    Read STORY's comments. Find each repo's kickoff comment, titled with its kickoff_title.

    line 139
  15. Distinctive:

    Wait for its report.

    line 147
  16. Very specific:

    Get the stack ready for the repos that depend on it: If a later repo depends_on this one and this one uses the local stack (not …

    line 148
  17. Distinctive:

    If a story has no kickoff for a repo, skip that repo.

    line 163
  18. Distinctive:

    Every review finding is fixed, ticketed or skipped by the user.

    line 207
  19. Distinctive:

    Every exploratory bug is fixed or deferred by the user.

    line 208
  20. Distinctive:

    Every PR on the stack for this slice is pushed and its checks pass.

    line 209
  21. Distinctive:

    Before calling it done, reconcile the record:

    line 215
  22. Distinctive:

    every checkpoint row has its Outcome.

    line 216
  23. Very specific:

    Run slice-handoff with STORY as the finished slice and the next story in the epic's order as the next one.

    line 221

≈ “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

Run Slice

You coordinate. Other Claude sessions do the work, one per repo in the config's repos (for example the API session and the UI session). You never edit, build or run tests in any repo yourself. Everything happens through SendMessage.

First, load the team config with roost-config. This skill uses repos, stack, tracker, tests, vcs, planning.review_focus and team.state_dir. "Each repo, in order" means the repos list by order.

Inputs

  • STORY: the slice's ticket key.
  • A session for each repo the story touches must already be open. If one isn't, ask the user to open it and stop.

Every run starts with step R (resume check), even a first run, so stopping and restarting is always safe. Before step R's report, work out which roost you run ("Which roost is running" in roost-config) and say it in that report. Before sending any work, new or resumed, do step 0 (find the sessions and check they run the same roost as you), even when step R picks up at a later step.

If the user only asks where things stand ("where are we on PROJ-X?", "what's left?"), use Status below and stop there.

Status: "where are we?"

Read-only. Send no messages, start nothing, change nothing. It must work from a fresh session with no memory of earlier runs, so use only GitHub, the tracker and the state file (step R, items 1 to 4).

For a story, one table and one line. Nothing else. One kickoff row per repo the story touches, in order:

StepStateEvidence
Backend kickoff✅ Done#571, checks pass
Frontend kickoff🔄 In progressPROJ-2788-frontend, no PR yet
Tests verified⏳ Remaining2 of 5 tests Done
Code review⏳ Remaining
Fixes⏳ Remaining
Exploratory testing⏳ Remaining
Slice done⏳ Remaining

Next: finish the frontend kickoff (UI session), then check.

The steps are always these, in this order: the kickoffs, then the same five. Name each kickoff row by its repo's kickoff_title without the repo name in brackets. "Evidence" is one short fact a person can check: a PR number, a branch, a count, a ticket key.

Always show the table, even when you can't read everything. If a step's state can't be told (a source couldn't be read, or nothing records it), mark that row ❔ Unknown rather than guess.

Under the table, at most two lines, no bullet lists:

  • one line naming everything that couldn't be read, together: "Couldn't read the tracker, GitHub or the state file from this session."
  • one line starting Next: with the single next action, in one sentence.

The table is the first thing in the reply. Nothing above it: no greeting, no summary, no apology.

Don't replace the table with an explanation, don't explain why a source was unreadable, and don't offer to start or resume work; the user asked where things stand.

For an epic, first one row per story, in the epic's story order, then the story table above for the one in progress:

StorySliceState
PROJ-2787Free plan at sign-up✅ Done
PROJ-2788API key on Get started🔄 Frontend kickoff
PROJ-2789API keys page⏳ Not started

A story is ✅ when it's at tracker.statuses.ready_for_release or later (or done, if the config has no ready-for-release status); 🔄 when any repo has a branch or the run's state file exists; otherwise ⏳.

R. Resume check: where is this slice?

Work out the slice's real state before sending anything. Reading is fine; you still change nothing in any repo.

  1. Your own record. Read the state file <team.state_dir>/STORY.md if it exists. If it records a different config from the one you loaded, stop ("Orchestrators record their config" in roost-config). It holds what only you know: the sessions found, each step's outcome, and the user's decisions at checkpoints. It's a record, not the truth: check it against steps 2 to 4. If the file isn't there (another machine, or it was cleaned up), read STORY's comments that start with run-slice checkpoint: instead; a checkpoint comment also means the check before it (tests and code review) ran.
  2. The kickoff comments on STORY name each repo's branch (for example PROJ-2788-backend). For each branch, in that repo's github:

    gh pr list -R <repo.github> --head <branch> --state all --json number,state,isDraft,url
    gh pr view <number> -R <repo.github> --json statusCheckRollup

    A repo's side is done when its PR exists on the stack and its checks pass, and, for a repo with apply_gate, its plan is applied and recorded in an apply: comment on STORY (see "The apply gate" in roost-config). A branch with no PR means that side started and didn't finish.

    Judge checks by each check's newest completed result on the PR's current head. A run that a newer push cancelled is harmless, and a re-run still in progress isn't "pending" when the same check already passed: report it as "green; a re-run is in progress". If the list shows only the unfinished entry for a check (a re-run of the same job can replace its earlier result), call that check pending. gh pr checks lists cancelled and re-run entries as pending, so don't use it to decide. Before anything is merged, use the stricter rule: the latest run of every check on the current head has completed successfully, and a queued or running check blocks the merge.

  3. The tracker: STORY's status, its linked tests' labels and statuses, and any tickets already created from this slice (linked "relates to"), so they aren't filed twice.
  4. The stack: whether every stack.services URL answers (curl -s -o /dev/null -w '%{http_code}' <url>). Skip this when every repo the story touches has local_stack: false.

Then tell the user what you found and where you're picking up, in one short table, and carry straight on. Being asked to run the slice is the go-ahead; don't ask for another. Stop only for a real blocker: a session that isn't open, two candidates for one repo, a refused message, or a resume that would act again on decisions the user may have changed (below).

StepStateEvidence
Backend kickoffDone#571, checks pass
Frontend kickoffNot startedno PROJ-2788-frontend branch

Pick up at the first step that isn't done:

  • A repo started, not finished: ask its session to continue from its branch, with its kickoff comment again for context. It decides what's left from the branch and the plan.
  • A repo done: go on to the next repo in order (after getting the stack ready, if a later repo depends on it).
  • Every kickoff done: start at step 2 (Check). Test verification and code review are safe to run again.
  • Mid-checkpoint or mid-fix: use the decisions in the state file. Show them to the user before acting on them again, since they may have changed their mind.

A session opened fresh after a stop knows nothing about this run. Every message you send already stands alone, so that's fine; but say in the first message that you're resuming STORY at a given step.

Migrations

When a session's report (or its branch) adds a database migration, and deploy.migrations_run_on_deploy is false, make sure the epic's deploy ticket covers it, as stacked-prs describes: the Migrations to apply comment and the staging and production pre-deploy sub-tasks. Add or update them yourself if the session didn't. Check the stack's migration files against the list; don't rely on the report alone.

Keep the state file current

After every step and every checkpoint, update <team.state_dir>/STORY.md:

  • the config this run uses: its path and team.name (see "Orchestrators record their config" in roost-config)
  • the roost this run uses (from step 0), and the session names and refs, and the directory each reported
  • each step: done, its outcome, PRs and commits from the session's report
  • each checkpoint: the list shown and the user's decisions, word for word
  • tickets you created

Write it as you go, not at the end, so a stop at any point loses nothing.

The state file lives on this machine only. So that Status works anywhere, also post each checkpoint's decisions to STORY as a comment starting with run-slice checkpoint:, with the decisions table. Status and the resume check read those comments when the state file isn't there.

0. Find the sessions

  1. ListAgents to see the other sessions on this machine.
  2. Don't trust names (they change, and two can look alike). Send each candidate:

    Connectivity check from the run-slice orchestrator: reply with your working directory (pwd), whether you're busy, and which roost you're running (the one line roost-config gives under "Which roost is running"), then carry on as before.

  3. A session whose directory ends in a repo's name is that repo's session. If there are two for one repo, or none for a repo the story touches, ask the user which to use.
  4. Note each session's name and ref for the rest of the run.
  5. Check every session runs the same roost as you ("Which roost is running" in roost-config). Record yours and theirs in the state file and say yours in your first report. If any differs (an installed version in one session and a checkout in another, or two versions), tell the user which session runs which, and that a session started with claude --plugin-dir <checkout> runs that checkout; carry on only once they say which roost the run uses.

If a send comes back held or refused (a [Cross-session delivery notice]), tell the user that session needs to accept messages, and stop.

How to talk to the sessions

  • One instruction per message, fully self-contained. The receiver reads it literally: no "as discussed", and no @file references, which attach nothing. Paste the text itself.
  • First line says what it is, for example "run-slice: backend kickoff for PROJ-2788". The user sees that line as the preview in their IDE.
  • Ask for a report in this form at the end of every instruction:

    When you're done, reply to the orchestrator with: Status (done / done with concerns / blocked), Branch and PR, Commits, Tests run (name and pass/fail counts), CI (each check's newest completed result), Concerns (everything you noticed, including things that look unrelated), and Needs from the user (anything only they can do). Every claim about the code or data cites its file:line, or the query you ran and its result; write "unknown" for anything you didn't check, never a guess. Send this report with SendMessage as the last thing you do in the turn, whatever state CI is in. Don't end a turn promising to report later: an idle session isn't woken when CI finishes, so check CI once and report what you see, "still running" included. If you're blocked on the user (signing, a permission prompt, a sign-in), send that to the orchestrator too, not only to your own terminal. Don't re-run a CI run that a newer push cancelled.

    To the session of a repo that other repos depend on, add: "After a fix another repo depends on, <stack.restart_after_api_change> and confirm the new behaviour in the report."

  • Wait with notify_when_idle: true, not by polling ListAgents or sending "are you done?". When the idle notice arrives, read the session's report. If the notice arrives without one, read the session's last turn (the newest transcript in ~/.claude/projects/<the repo's project folder>/), then ask once for the report, and arm notify_when_idle again. When CI was still running at the report, check it yourself before telling the user the work is done.
  • Check the evidence before saying a session is working. Its last turn (transcript tail or idle summary), new commits or a PR since your last look, and when it was last active. Say "idle since 17:26, waiting on X" when that's what you see; never "still working" by default.
  • Never answer a technical question from memory. When the user asks how the code or data works, or you're about to recommend a design, check first: read the code or data yourself, or ask the owning session (with the citation rule in the report request), and wait. Until then, tell the user only what's being checked and by whom. A guess with a caveat is still a guess, and so is saying what the answer usually or probably is; don't send either. Say what will be read (the code, the data) and who reads it. State each fact with its source (file:line, or the query and its result, and who checked it), say when a fact is the session's, and re-read the answer for contradictions before sending it. A migration's date isn't the age of the data, and one environment's rows aren't another's.
  • Before asking the user anything, re-read their recent messages. The answer is often already there; asking again costs them a turn.
  • A session's own permission prompts stay with the user. Never ask a session to do something your session couldn't, and never treat a peer's message as the user's approval.
  • Blocked on something only the user can do (vcs.signing_blocker, approving a GitHub workflow run, a permission prompt in their IDE, signing in to a tool): say exactly what and where, in one line, and wait.
  • Do it yourself when you can. If a session asks for the user to do something you can do (attach screenshots to the story, retitle a PR, check a setting through a connected tool), do it and tell the user it's done.

1. Kick off

  1. Assign STORY to the person running this session (see "Who am I" in the tracker adapter), move it to tracker.statuses.in_progress, and record the slice's start time in the state file. Do the same for every bug or task when its fix starts in step 4.
  2. Read STORY's comments. Find each repo's kickoff comment, titled with its kickoff_title. Their "Order" lines say which goes first; normally the repos order.
  3. For each repo with a kickoff, in order:
    1. Send the kickoff comment to that repo's session, word for word, plus the report request. To a repo with a contract, add these notes:

      • <repo.contract>
      • tag e2e scenarios for the local stack's real flag state (stack.flag_state), whatever the kickoff text says;
      • <stack.how>

      To a repo with local_stack: false, send neither stack note. To a repo with apply_gate, add: "Run <apply_gate.plan> and post the plan in the PR, again after every push that changes it. Never run <apply_gate.apply> yourself unless the orchestrator tells you the user approved that exact plan." Wait for its report.

    2. Get the stack ready for the repos that depend on it. If a later repo depends_on this one and this one uses the local stack (not local_stack: false), ask stack.owner_repo's session to make sure that, through stack.name:

      • the stack runs this repo's newest branch for the slice;
      • the slice's migrations are applied to stack.database.local with stack.database.apply_migrations (stack.database.note);
      • one call that touches the new schema succeeds;
      • any resource the slice needs is started (stack.extra_resources).

      Then check yourself that every stack.services URL answers. Don't trust "it's running": a resource can be down while the others are up. Ask the owning session to start anything missing.

      A repo with local_stack: false isn't run on the stack: for one with apply_gate, the apply checkpoint (next) is what makes its work ready for the repos that consume it.

    3. Apply checkpoint, for a repo with apply_gate, once its PR's checks pass and its plan is posted: follow "The apply gate" in roost-config. Show the user the plan's summary, with anything destroyed or replaced first, and stop for their decision. When it's applied, record the apply: comment on STORY and check a fresh plan shows no changes. A later repo that consumes what this one creates (its outputs, a cluster, a role) starts only after the apply.

      With apply_gate.when: after_merge, the plan can't be applied yet: hold this checkpoint until the PR has been through steps 2 to 5 and the user has merged it (step 6), then apply from main. Repos that consume its outputs start after that apply.

    4. After each kickoff: check the new PR's title follows vcs.pr_title (retitle it yourself with gh pr edit if not), and add it to the epic's Release order comment with its deploy (see stacked-prs). If it's the first branch of a later deploy than the branch below it, check it isn't linked into that branch's stack (stacked-prs, One deploy per stack).
  4. Before telling the user to merge, check every repo with apply_gate and when: before_merge has its apply recorded for the PR's head; then list exactly which PRs the merge takes (the PRs linked into the stack, from gh stack view --short) and check each one belongs to this deploy. Name them in the message. Separately, check any other open PR whose base is a branch of this stack is unlinked and belongs to a later deploy (stacked-prs, One deploy per stack).

If a story has no kickoff for a repo, skip that repo. If a session reports blocked, stop and tell the user.

2. Check

Send these, then wait for every report:

  • The session of the repo that holds the e2e suite (the one with e2e in the config), or, when the config has none, the session of the repo that owns STORY's work: "Use the verify-slice-tests skill for STORY. Don't carry out any split until the orchestrator tells you the decision." Skip this when STORY has no linked tests (retired ones don't count) because no suite can prove its work before release (a docs slice, for example). Instead, ask that repo's session to check each of STORY's acceptance criteria against its PR (the build and the preview), one row per criterion with its evidence.
  • Manual tests of STORY's ("Manual tests" in the tests adapter), once the work they check is in place: send each to the session of the repo that owns that work, with the test's description, to run what it can read-only and record the run as the tests adapter says. It runs nothing that changes a shared or production resource, and nothing in deploy.runbooks.never_run_against: those steps go to the user as 🙋 Your turn actions, and the session records the run from the user's answer. Skip tests with When: after release.
  • Every session the slice touched: "Run /code-review on every change in this stack compared with main, with a focus on <the repo's review_focus, or planning.review_focus>. Report the findings; don't fix anything yet." To the session of a repo with apply_gate, add: "Review the posted plan too, not only the code: anything destroyed or replaced, public exposure, and permissions wider than the change needs."

3. Checkpoint: the user decides

Give the user one combined list, bottom line first ("2 tests need a decision, 5 review findings, nothing failing"):

#FromItemRecommendation
1TestsPROJ-XXXX: split proposedSplit as proposed
2API review…Fix now
3UI review…Ticket for later

Recommend one of: fix now, ticket for later, or skip (with why). Recommend "fix now" only for two kinds of finding: anything this slice introduced (in its code, tests, data changes, docs or behavior), and anything, introduced here or not, that stands in the way of the story's or the epic's goal (its acceptance criteria, a security or data-loss risk, or a problem the slice's own change exposes). Everything else, such as older bugs the review happened to read and minor polish, is "ticket for later" unless the user chooses otherwise. Mark each row "introduced here", "blocks the goal" or "older". Without this rule the loop doesn't end: every review of new fixes finds something new, and each fix adds code for the next review to find. For security findings, use the triage-ticket way of judging them: is it real, who could exploit it, how bad. Then wait for the user's decisions.

Everything a session reported becomes a row: every finding, concern or odd thing in any report since the last checkpoint (pre-existing lint errors, a resource that failed to start, a flaky test), not only the review findings. Nothing stays only in a session's report, where the next slice can't find it.

The run-slice checkpoint: comment uses one fixed table, so later steps can check it: #, Item, Key (the ticket, once there is one), Decision, Outcome. Fill Outcome as each item is carried out: a commit or PR for "fix now", a ticket key for "ticket for later", a reason for "skip". Say where deferred work goes in the table ("with PROJ-2809"), not only in prose.

4. Fix

  • Send each "fix now" item to the session that owns the code, test-first, one commit per item, pushed on the stack (stacked-prs).
  • An item that needs more than one repo: write each repo's part with cross-repo-handoff and send them in repos order. Send a dependent repo's part only after the repo it depends on reports done and the stack is restarted.
  • Tell the e2e repo's session the split decisions, so verify-slice-tests can carry them out.
  • "Ticket for later" items: create the tickets yourself. Each gets the epic as its parent (set at creation; see the tracker adapter for fixing a parent later), Components when the config requires them, and a "relates to" link to STORY.

5. Explore

Skip this step when the slice changes no UI (its story names no prototype screen), or the config has no e2e repo: its tests, its acceptance criteria and, for a repo with apply_gate, the fresh plan after the apply, are its checks. Otherwise, ask the e2e repo's session to do exploratory testing of this slice only, using release-qa steps 3 and 4, after loading the data the slice's screens need with stack.test_data if the config has it (local stack only): charters from STORY's prototype screen and states, in a real browser, filing only bugs it reproduced, as Bugs under the epic with Components set, each behaviour bug with the test that would catch it (release-qa step 4 says how). It shouldn't run the whole e2e suite or give a release call.

New bugs go back to step 3 for the user's decision, then to bug-bash in the session that owns each one.

6. Done for this slice?

Loop through steps 2 to 5 until all of these are true:

  • verify-slice-tests shows every test automated, passing and done, or split with the user's approval, and every manual test done on a passing manual run: comment, except those whose description says When: after release ("Manual tests" in the tests adapter). For a slice with no tests because no suite can prove its work before release, every acceptance criterion is checked on its PR, with evidence.
  • A test created for an exploratory bug the user deferred may stay open and unlabelled: it's automated with that bug's fix, not in this slice. List it in the slice-done comment's Left open table with the bug and where the bug went.
  • Every review finding is fixed, ticketed or skipped by the user.
  • Every exploratory bug is fixed or deferred by the user.
  • Every PR on the stack for this slice is pushed and its checks pass.
  • Without stacking, last: once everything else here holds, ask the user to merge the slice's PRs, naming each in Release order, and check each merged. The story moves to ready for release only after that ("Without stacking" in roost-config).
  • Every repo with apply_gate has its plan applied and recorded for its PR's current head (or, with when: after_merge, for the merged commit), with a fresh plan showing no changes ("The apply gate" in roost-config). A fix in step 4 or a Copilot fix that changes the plan after an apply sends that repo back to the apply checkpoint (step 1) for the new plan; an earlier apply doesn't count.
  • Every PR for this slice has had a Copilot review, and every Copilot thread has an outcome: accepted with its fix commit, declined with a reply saying why, or older and ticketed. As soon as a slice's PRs are pushed, without waiting for CI, send each owning session references/copilot-review.md, word for word with the PR numbers filled in, and wait for its table. File the "older" threads as tickets yourself (epic as parent, Components, "relates to" STORY). Accepted fixes count as fixes made since the slice's code review, so the next bullet's review covers them.
  • The fixes made since the slice's code review were reviewed too: each session ran /code-review on just the commits after the review in step 2, and each finding is fixed or decided by the user. When you send that review, tell the session to report findings without fixing anything yet, identifying findings those fixes introduced or that stand in the way of the story's or epic's goal, and marking the rest as "older" for the checkpoint. Route all findings through step 3 using its recommendation rule, and carry out only the fixes the user approves in step 4. Review any resulting fixes in the same way. The slice is done when the latest fixes have been reviewed and every finding is fixed, ticketed or skipped by the user.

Before calling it done, reconcile the record:

  • every checkpoint row has its Outcome;
  • a wide search finds no ticket from this slice that isn't linked to STORY: everything created since the slice's start time whose parent is the epic or whose text mentions STORY, except person-owned tasks (see roost-config) and the tests' shared setup where it's a ticket (the tests adapter's "Shared setup"). The start time is the one in the state file; when there isn't one (a resumed run on another machine), use the earlier of STORY's first kickoff comment and its first move to In Progress, and record it. Link any that belong, with the epic as parent and Components set.

Then:

  1. Comment on STORY with the final state: the PRs, the tests and their status, tickets created for later, and bugs filed. End the comment with a Left open table (key, summary, where it goes: next slice, before release, or later), which slice-handoff reads and checks. Mark the state file's run as finished.
  2. Run slice-handoff with STORY as the finished slice and the next story in the epic's order as the next one. It sorts what's left over, checks the whole epic's tests, and brings the next slice's kickoffs up to date.
  3. Checkpoint: ask the user whether to start the next slice, in the same message as slice-handoff's sorting table. Never start it on your own. When build-epic is running this slice, skip the question: the user's answers to the sorting table are enough, and build-epic starts the next slice.

Progress updates while sessions work

Whenever you've sent work to a session and are waiting on it (a kickoff, fixes, exploratory testing, a rebase), give the user a short update every 5 minutes. Do this without being asked; the user shouldn't have to request it. Every update, scheduled or not, follows the update prompt below.

  • Schedule it with CronCreate, every 5 minutes, recurring, as soon as you send the work. Its prompt is the update prompt below, with {STORY}, {EPIC}, {SESSIONS}, {LOG} and {STATE_DIR} filled in and everything else word for word, so every scheduled run follows the format without rereading this skill. Tell the user once that updates are on and that "stop" ends them.
  • Each update is read-only. Don't message the sessions to ask how they're doing. Check only what you can see (the update prompt lists it). If the config has stack.telemetry, read it from stack.owner_repo with stack.telemetry.logs and stack.telemetry.traces (stack.telemetry.note): report only what's new since the last update, group repeats with a count, and flag anything that looks like a bug in this slice or a problem with the stack. Errors no session has mentioned are worth the user's attention.
  • Log skill gaps you notice in <team.state_dir>/lessons.md (date, slice, what happened, skill affected, possible change).
  • Stop the schedule (CronDelete) when nothing is outstanding: every session you sent work to has reported, the slice reaches a checkpoint that needs the user, it's done, or the user says stop. Arm it again when you next send work.

The update prompt

roost progress update for {STORY} (epic {EPIC}). Read-only: don't message any session.

Check the evidence first: each session's transcript tail and last-activity time ({SESSIONS}), new commits on the slice's branches, each PR's checks and mergeStateStatus, open review threads, whether every stack.services URL answers, the stack's telemetry if the roost config has stack.telemetry, and any reports or idle notices received. Never report "working" without that check.

Then write exactly one of these three updates. Choose in this order: YOUR TURN if anything needs the user (new, or still unresolved from an earlier update); otherwise STALLED if work is stalled; otherwise moving.

1. Nothing needs the user. A level-4 heading, then ONE plain line. No bold, no tables, no bullets.

   #### 🟢 HH:MM · {STORY} · moving
   One plain sentence on what changed, for example "#603 CI 8/11 · 2 Copilot threads being fixed."

2. Something needs the user (a decision, a sign-in, a credential, a production query or change). Start with a level-2 heading, put the actions first as a numbered list, then at most two lines of context. Also send a PushNotification whose single line starts with the action.

   ## 🙋 YOUR TURN · HH:MM · {STORY}
   1. **The action, bolded.** Exactly what to do and where, for example `! aws sso login --profile X`.
   2. ...
   One or two plain lines of context: why the action is needed and what's waiting on it. Nothing else; status details (checks, commits, other PRs) go in the log line.
   For example: "The API session can't run its tests until you sign in. The UI session is waiting on it."

   Use this heading for nothing else. While anything in it is unresolved, repeat this block in every update, showing only what's still open.

3. Stalled: no session activity and no commits for 15+ minutes while work is outstanding. Start with:

   ## ⚠️ STALLED · HH:MM · {STORY}
   Who stalled, since when, and the evidence (last transcript activity time, last commit).

Rules for all three:
- The update is the whole reply: nothing before or after it, and no explaining what you left out.
- Lead with the answer; one line per fact; plain words, no jargon.
- Every heading carries the current time (HH:MM, local) and {STORY}: first in the moving heading, right after the label in the other two.
- Don't paste earlier updates under the new one; the log file keeps the history.
- Append one line per update to {STATE_DIR}/{LOG}-updates.md: "- HH:MM · {STORY} · what's happening · what's new".

{LOG} is the story's key when run-slice runs on its own, and the epic's key when build-epic runs it (build-epic keeps one log for the epic). {SESSIONS} names each session you sent work to.

Examples

Nothing needs the user:

#### 🟢 13:05 · PROJ-2789 · moving
#603 CI 8/11 · 2 Copilot threads being fixed.

Something needs the user (and a PushNotification: "Run aws sso login --profile beakpoint-dev in the API session"):

## 🙋 YOUR TURN · 14:10 · PROJ-2789
1. **Sign in to AWS in the API session.** In its terminal, run `! aws sso login --profile beakpoint-dev`.
2. **Approve the workflow run on #604.** Open the PR's Checks tab and choose "Approve and run".
The API session is blocked on the expired AWS session; the UI session is waiting on its endpoint.

Stalled:

## ⚠️ STALLED · 13:40 · PROJ-2789
The UI session, since 13:20: its transcript was last active at 13:19 and its last commit (a1b2c3d, "test: create dialog") was at 13:12. The frontend kickoff for PROJ-2789 is still outstanding.

Report to the user

Anything the user must do goes first, in its own block headed 🙋 Your turn: one line per action, saying exactly what and where. Leave the block out when there's nothing; never write "nothing needed". Don't hand the user anything you can do yourself (attaching files to the tracker, retitling a PR, checking a setting through a connected tool); only sign-ins, vcs.signing_blocker and decisions are theirs. Then lead with where the slice is ("PROJ-2788: backend done, frontend running"), then a short table of what each session last reported. Keep a running status table during the run, one column per session:

StepAPI sessionUI session
Kickoffdone, #NNNrunning

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.