| name | agent-worker-flow |
| description | Standard claim/branch/verify/publish workflow for pod agent sessions. Read this skill at the start of any feature, review, summarize, or meditate session. |
| allowed-tools | Bash, Read, Glob, Grep |
Standard Worker Flow for Pod Agent Sessions
This skill covers the shared workflow used by all pod worker agents.
Session-specific commands reference this skill rather than duplicating it.
Coordination Reference
The coordination script handles all GitHub-based multi-agent coordination.
Session UUID is available as $POD_SESSION_ID (exported by pod).
The gh CLI defaults to the current repo, so --repo is not needed.
| Command | What it does |
|---|
coordination orient | List unclaimed/claimed issues, open PRs, PRs needing attention |
coordination plan [--label L] "title" | Create GitHub issue with agent-plan + optional label; body from stdin |
coordination create-pr N [--partial] ["title"] | Push branch, create PR closing issue #N, enable auto-merge, swap claimed → has-pr. With --partial: adds replan label. |
coordination claim-fix N | Comment on failing PR #N claiming fix (30min cooldown) |
coordination close-pr N "reason" | Comment reason and close PR #N |
coordination list-unclaimed [--label L] | List unclaimed agent-plan issues (FIFO order); optional label filter |
coordination queue-depth [L] | Count of unclaimed issues; optional label for per-type count |
coordination claim N | Claim issue #N — adds claimed label + comment, detects races |
coordination skip N "reason" | Mark claimed issue as needing replan — removes claimed, adds replan label |
coordination add-dep N M | Add depends-on: #M to issue #N's body; adds blocked label if #M is open |
coordination check-blocked | Unblock issues whose depends-on dependencies are all closed; remove orphan blocked from issues whose body has no depends-on: lines |
coordination check-has-pr | Remove orphan has-pr from open issues that have no currently-open PR closing them (post audit comment) |
coordination release-stale-claims [SECS] | Release claimed issues with no PR after SECS seconds (default 4h); manual use only |
coordination release-orphan-claims | Release claims whose owning session UUID is no longer in .pod/agents/ (liveness-based, no age threshold); manual use only |
coordination lock-planner | Acquire advisory planner lock (20min TTL) |
coordination unlock-planner | Release planner lock early |
coordination critical-path-depth [L] | Count unclaimed critical-path issues; optional label filter |
coordination set-target N | Planner sets recommended target agent count (wind-down use only) |
Issue lifecycle: planner creates issue (label: agent-plan) →
worker claims it (adds label: claimed) → worker creates PR closing it
(label swaps to has-pr) → auto-merge squash-merges.
Issues marked replan (by skip, partial completion, or worker-led
decomposition) are handled by the next planner. Issues with has-pr are
excluded from list-unclaimed and queue-depth.
Never apply has-pr manually. The label is set automatically by
coordination create-pr (full path) and cleared by GitHub's auto-close
on merge of a Closes #N PR. Hand-applying it desynchronises the label
from any actual PR — when the supposed PR closes or merges without
Closes #N, the issue stays has-pr forever and is silently excluded
from the work queue. If you want to "park" an issue while sub-issues
do the work, use coordination add-dep <parent> <sub> for each
sub-issue: the parent becomes blocked, and check-blocked auto-clears
the label when all subs close. The orphan-label housekeeping cycle
(check-has-pr, check-blocked) auto-removes mis-applied labels and
posts an audit comment on the issue.
Partial completion: worker uses --partial → label swaps to
replan. A planner creates a new issue for remaining work, then closes
the replan issue with a link to the new one.
Worker-led decomposition: if the claimed issue is too large for one
session, worker creates sub-issues and coordination skips the parent
with a Decomposed into #X, #Y breadcrumb comment. The next planner
either closes the parent (sub-issues fully cover it) or narrows it to the
residual scope. See "Assess Scope" (Step 4b) for the full procedure.
Dependencies: Issues can declare depends-on: #N in their body.
coordination plan auto-adds the blocked label if any dependency is
open. check-blocked (run by pod each loop) removes blocked when
all dependencies close. Blocked issues are excluded from
list-unclaimed and queue-depth.
Branch naming: agent/<first-8-chars-of-UUID>
Plan files: plans/<UUID-prefix>.md
Progress files: progress/<UTC-timestamp>_<UUID-prefix>.md
Step 1: Claim a Work Item
coordination orient
Priority order:
0. Directives first: Check for open directive issues before anything else.
These are direct instructions from the project owner — work flowing down from
the human, not work awaiting human attention — and take absolute precedence over
all other work:
coordination list-unclaimed --label directive
If any are open and unclaimed, claim the oldest one immediately.
Directives cannot be skipped or refused because you disagree with the approach.
The valid exits from a directive are (a) completing the deliverables and
closing the issue yourself, (b) opening a partial PR and noting the
remaining scope so a successor can pick it up, or (c) posting a comment
explaining a genuine technical blocker (e.g. a missing dependency) and
coordination skip with that reason. Do not leave a directive open
with a "for owner closure" note — if the deliverables are in, close it.
Do not skip because you think a different approach is better — that is
the owner's call, not yours.
- Oldest unclaimed issue of your type:
coordination list-unclaimed --label <your-label>
Don't repair PRs from a worker session. PR health (merge conflicts,
failed CI, stuck CI) is the repair agent's responsibility; pod dispatches
/repair automatically when coordination list-pr-repair reports
candidates, ahead of /plan / /work. Focus on fresh issue work.
If the queue is empty, write a brief progress note and exit.
coordination claim <issue-number>
You MUST check the output. If it says CLAIM FAILED, you MUST NOT work
on that issue — pick a different one. Only proceed if the output says
Claimed issue #N. Read the full issue body:
coordination read-issue <N> --json body --jq .body
Step 2: Set Up
git checkout -b agent/<first-8-chars-of-session-UUID>
git rev-parse HEAD
If the branch already exists (common in reused worktrees): check for an
open PR on it first (gh pr list --head agent/<id>). If a PR exists, create
a new branch with a suffix (agent/<id>-v2). If no PR exists, reset it to
master: git checkout agent/<id> && git reset --hard origin/master.
Before that reset --hard, run git status — reused worktrees commonly
carry uncommitted pod-local .claude/ edits. If any uncommitted changes
exist, git stash them first (never -u/--include-untracked), so the
hard reset does not silently discard in-progress work.
Record any project-specific quality metrics (e.g. sorry count, test coverage)
as described in the project's CLAUDE.md.
Step 3: Codebase Orientation
Read the specific files mentioned in the plan/issue. Understand the current state
of code you'll be modifying. Don't read progress history — the issue body provides
that context.
Step 4: Verify Assumptions
Check that the plan's assumptions still hold:
- Quality metrics match what the issue says
- Files mentioned in the issue still exist and haven't been restructured
- No recently merged PR invalidates the plan
If stale:
coordination skip <issue-number> "reason: <what changed>"
Go back to Step 1 and try the next issue.
PR fix plans: If the plan asks you to fix a broken PR, use judgement. If the
PR is low quality or not worth salvaging:
coordination close-pr <pr-number> "reason: <why not worth fixing>"
Step 4b: Assess Scope
After orienting but before writing code, check whether the task fits
in a single session. Warning signs it doesn't:
- Target file is 500+ lines and you need to understand most of it
- The work naturally splits into independent sub-lemmas or sub-tasks
- Difficulty feels higher than the issue says
If the issue is too large, decomposing it into smaller sub-issues is a
normal success path, not a failure mode. You have the freshest codebase
context and can usually scope sub-tasks more accurately than a planner could
in advance. A good decomposition is more valuable than a failed heroic
attempt — and far better than overrunning the session trying to salvage it.
You may decompose when any of these is true:
- the claimed issue is too large for one session,
- the work naturally splits into independent sub-tasks,
- you can write self-contained successor issues without further investigation.
echo "body..." | coordination plan --label feature "Sub-task 1: ..."
echo "body..." | coordination plan --label feature "Sub-task 2: ..."
coordination add-dep <sub2> <sub1>
gh issue comment <parent> --body "Decomposed into #<sub1>, #<sub2>
(reason: <one-line scope assessment>)"
coordination skip <parent> "Decomposed into #<sub1>, #<sub2> — see comment"
The planner's next replan-triage cycle picks the parent up and either
closes it (if the sub-issues fully cover it) or narrows the body to the
residual scope (if not).
After decomposing, you have two options:
- Continue on one of the sub-issues: claim it via
coordination claim,
then return to Step 2 with the sub-issue. Common case when the parent
was just two work items glued together.
- Stop and exit: if you've used most of your session orienting, write a
brief progress entry and exit. The next worker will claim a sub-issue.
If you've already done a coherent subset of the parent's work before
deciding to decompose, prefer the partial-PR path:
coordination create-pr <parent> --partial "feat: <what landed>"
The next planner sees the breadcrumb on the parent and closes it with a
forward link to the sub-issues.
Step 5: Execute
After each coherent chunk of changes:
- Build and test using the project's build commands (see project CLAUDE.md)
- Commit with conventional prefixes:
feat:, fix:, refactor:, test:, doc:, chore:
Each commit must compile. One logical change per commit.
One lake build at a time. Lake serializes on a single build lock, so
concurrent lake build invocations do not parallelize — they queue, and each
may redo the same expensive targets (a full HexBerlekampZassenhaus* build is
minutes per file). Never launch a new build while one is still running. Run a
build with run_in_background: true, then wait for its completion
notification (or one until grep -q "Built <target>" log; do sleep N; done
waiter) before starting another. Do not stack build + waiter loops.
compiled configuration is invalid; run with '-R' to reconfigure is NOT
spurious. When lake build ends with only that message and no Built …
lines, the build did nothing — it served stale .oleans and reported a
false green. In a fresh worktree this silently masks real errors (a proof that
depends on beta-reduction or a fragile simp can "pass" locally and then fail
in CI, which compiles from scratch). Fix it once with lake build -R <target>
to reconfigure. Caution: -R may re-clone mathlib and wipe its cached
oleans, after which a full build recompiles mathlib from source (hours). If you
see it start building Mathlib.*, stop and run lake exe cache get to restore
the oleans (download, never rebuild — see the global CLAUDE.md), then build only
Hex targets. After reconfiguring once, plain lake build is a real incremental
build again. Always confirm a green build shows Build completed successfully (N jobs) with N matching a real compile, not just the absence of error:.
Commit early, create PRs early. Sessions can terminate at any time.
Pushed-but-not-PR'd work is effectively lost — nobody will find it.
- Commit after every compiling milestone. Don't wait for the full feature.
- WIP commits are fine:
feat: WIP prove helper_lemma (2/4 sorries remain)
- If 20+ minutes have passed without a commit, stop and commit now.
- Use
coordination create-pr N --partial as soon as you have useful
progress, even if incomplete. This saves the work as a visible PR.
Failure handling:
- Build fails on pre-existing issue → log and work around
- Stuck after 3 fundamentally different attempts → decompose into sub-issues (Step 4b)
- 3 consecutive iterations with no commits → end session, document blockers
(does not apply to review or self-improvement sessions)
- If
/second-opinion or /reflect is unavailable, skip and note in progress entry
Step 5b: Context Health
If conversation compaction occurs:
- Finish your current sub-task (get to compiling state)
- Commit what you have
- Skip remaining deliverables — do NOT start new work
- Go directly to Step 6 then Step 7 with
--partial
Commit early and often. Each commit is a checkpoint.
Step 6: Verify
Build and test the project. Compare quality metrics with the starting values.
Review your diff: git diff <starting-commit>..HEAD.
Use /second-opinion if available.
Mathlib environment linter (Phase 6 audits). To check "the Mathlib
linter is clean" on a library, run the linter exe straight from the
mathlib dependency on each module: lake exe runLinter <Module.Name>
(e.g. lake exe runLinter HexPolyMathlib.Basic). This runs the full
#lint suite (docBlame, simpNF, unusedArguments, …) and prints
"Linting passed" per module — stronger evidence than build-time
syntactic linters alone. There is no project-local runLinter target;
it resolves from mathlib.
Calibrate before treating runLinter output as a blocker. The full
#lint suite flags simpNF and unusedArguments findings that the
project tolerates by design — simpNF noise from intentional @[simp]
unfolding lemmas (e.g. toNat_eq_val), and unusedArguments on
deliberate API-symmetry args (e.g. an _hp kept for signature parity).
These are NOT what "the Mathlib linter is clean" gates on: runLinter is
wired into neither .github/ nor scripts/, and the build-time linter
(a green lake build with zero warnings) is the actual CI gate. Confirm
by running runLinter on a sibling library already at done_through ≥ 6
(e.g. HexGFqRing): if it shows the same finding categories, they are
non-gating, so do not block the bump and do not attempt a cross-cutting
@[simp] refactor to silence them. Only build-time-linter warnings and
genuine docBlame (missing-docstring) hits gate the bump.
Fixing docBlame hits. docBlame is the ground-truth list of
missing-docstring gaps — trust it over a manual scan. Two traps a manual
scan hits: typeclass instances are docBlame-exempt (not in the
def/structure/class/inductive rule), so a scan that flags every
undocumented instance massively over-reports; and structure fields
each need their own /-- -/, not just the structure. For an internal
recursion helper flagged as Foo.go (from a let rec go/where go
inside a term-mode def), you cannot put /-- -/ before the let rec
(it fails to parse: "unexpected token '/--'"). Document it with a
/-- -/-prefixed add_decl_doc Foo.go placed after the enclosing
def.
Step 7: Publish
Write a progress entry to progress/<UTC-timestamp>_<UUID-prefix>.md:
- Date/time (UTC), session type, what was accomplished
- Decisions made, key patterns discovered
- What remains, quality metric deltas
Full completion:
git push -u origin <branch>
coordination create-pr <issue-number>
Once the PR is created, exit. Do not poll CI, wait for the merge, or
otherwise spin on the PR. Another session will pick up any follow-up work
(e.g. a "fix PR #N" issue if CI fails). Polling burns context and tokens
for no benefit.
Partial completion (did NOT complete all deliverables):
If you only closed a bad PR (no code changes):
gh issue close <N> --comment "Closed PR #M as not worth salvaging. See progress entry."
Step 8: Reflect
Run /reflect. If it suggests improvements to skills or commands, make those
changes and commit before finishing. Do NOT modify the project's top-level
CLAUDE.md or roadmap files — those are off-limits to agents.