$crank - Autonomous Epic Execution (Codex Native) Quick Ref: Execute every open issue in an epic via wave-based workers using , , , and . Output: closed issues + final validation. You must execute this workflow. Do not just describe it. Architecture Backend Rules 1. Prefer Codex session agents when is available. 2. Use for implementation agents and for discovery agents when the runtime exposes roles. 3. Use only for short steering or retry prompts. 4. Use for stalled or unnecessary agents. 5. Never depend on legacy CSV fan-out or host-task result polling. Use , , , and instead. Codex Lifecycl…

; then\n bash scripts/validate-ci-policy-parity.sh || exit 1\n fi\n ```\n See [references/wave-patterns.md](references/wave-patterns.md) \"CI-Policy Parity Gate\" for the worked example and the soc-lmww1 / commit `c587b361` motivation.\n\n### Step 5.7: Wave Checkpoint\n\n```bash\nFILES_CHANGED_JSON=\"${FILES_CHANGED_JSON:-$(git diff --name-only \"${WAVE_START_SHA:-HEAD~1}..HEAD\" | jq -R -s -c 'split(\"\\n\")[:-1]')}\"\nGIT_SHA=\"$(git rev-parse HEAD)\"\n\ncat > \".agents/crank/wave-${wave}-checkpoint.json\" \u003c\u003c EOF\n{\n \"schema_version\": 1,\n \"wave\": $wave,\n \"epic_id\": \"$EPIC_ID\",\n \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\n \"tasks_completed\": ${TASKS_COMPLETED_JSON:-[]},\n \"tasks_failed\": ${TASKS_FAILED_JSON:-[]},\n \"files_changed\": $FILES_CHANGED_JSON,\n \"git_sha\": \"$GIT_SHA\",\n \"acceptance_verdict\": \"${ACCEPTANCE_VERDICT:-WARN}\",\n \"commit_strategy\": \"${COMMIT_STRATEGY:-wave-batch}\",\n \"mutations_this_wave\": $(grep -c \"\\\"wave\\\":${wave}\" .agents/rpi/plan-mutations.jsonl 2>/dev/null || echo 0),\n \"total_mutations\": $(wc -l \u003c .agents/rpi/plan-mutations.jsonl 2>/dev/null | tr -d ' '),\n \"mutation_budget\": {\n \"task_added\": {\"used\": ${MUTATION_TASK_ADDED:-0}, \"limit\": 5},\n \"task_reordered\": {\"used\": ${MUTATION_TASK_REORDERED:-0}, \"limit\": 3}\n }\n}\nEOF\n\nbash skills-codex/crank/scripts/validate-wave-checkpoint.sh \".agents/crank/wave-${wave}-checkpoint.json\"\n```\n\nDo not copy or consume the checkpoint downstream until validation passes. The validator fails closed when `git_sha` does not resolve in the current repo, `timestamp` is invalid or more than 5 minutes in the future, or required checkpoint fields are missing/malformed.\n\n### Step 5.8: Update Shared Task Notes\n\nHarvest discoveries from completed workers and append to the shared notes file:\n\n```bash\nWAVE_DISCOVERIES=\"\"\nfor result_file in .agents/crank/results/*; do\n if [ -f \"$result_file\" ]; then\n DISCOVERIES=$(sed -n '/^## Discoveries/,/^## /{ /^## Discoveries/d; /^## /d; p; }' \"$result_file\" 2>/dev/null)\n if [ -n \"$DISCOVERIES\" ]; then\n WAVE_DISCOVERIES=\"${WAVE_DISCOVERIES}${DISCOVERIES}\\n\"\n fi\n fi\ndone\n\nif [ -n \"$WAVE_DISCOVERIES\" ]; then\n cat >> .agents/crank/SHARED_TASK_NOTES.md \u003c\u003cEOF\n\n## Wave ${wave} ($(date -Iseconds))\n$(echo -e \"$WAVE_DISCOVERIES\")\nEOF\nfi\n```\n\n**Capture:** Failed approaches, codebase quirks, convention discoveries, dependency notes.\n**Skip:** Full error logs, implementation details, task status.\n\n### Step 5.9: Log Plan Mutations\n\nAfter processing wave results, log mutations for any plan changes. Call `log_plan_mutation` for each:\n\n- **DECOMPOSE:** `task_removed` for original, `task_added` for each sub-task\n- **PRUNE:** `task_removed` with block reason\n- **Scope change:** `scope_changed` when file manifest updated after exploration\n- **Dependency discovered:** `dependency_changed` when blocked-by list modified\n- **Wave reassignment:** `task_reordered` when task moves between waves\n\n```bash\n# Example: task decomposed into sub-tasks\nlog_plan_mutation \"task_removed\" \"$decomposed_id\" \\\n \"{\\\"subject\\\":\\\"$ORIGINAL_SUBJECT\\\",\\\"status\\\":\\\"decomposed\\\"}\" \"null\"\nlog_plan_mutation \"task_added\" \"$sub_id\" \"null\" \\\n \"{\\\"subject\\\":\\\"$SUB_SUBJECT\\\",\\\"reason\\\":\\\"Split from $decomposed_id\\\"}\"\n\n# Example: scope change after exploration\nlog_plan_mutation \"scope_changed\" \"$task_id\" \\\n \"{\\\"files\\\":$ORIGINAL_FILES}\" \\\n \"{\\\"files\\\":$UPDATED_FILES,\\\"reason\\\":\\\"$REASON\\\"}\"\n```\n\nMutations are append-only to `.agents/rpi/plan-mutations.jsonl`. Read by `$post-mortem` for drift analysis.\n\n### Step 6: Commit Wave Results\n\n**Lead-only commit** - workers write files, lead validates and commits once per wave:\n\n```bash\nfor f in $WORKER_FILES_CHANGED; do\n git add -- \"$f\"\ndone\ngit commit -m \"feat(\u003cscope>): wave $wave - $COMPLETED_COUNT issues completed\"\n```\n\n### Step 7: Loop or Complete\n\n```bash\nwave=$((wave + 1))\n\nif [[ $wave -ge 50 ]]; then\n echo \"\u003cpromise>BLOCKED\u003c/promise>\"\n echo \"Global wave limit (50) reached.\"\n exit 1\nfi\n\nREMAINING=$(bd ready 2>/dev/null | wc -l)\nif [[ $REMAINING -eq 0 ]]; then\n ALL_CLOSED=$(bd children \"$EPIC_ID\" 2>/dev/null | grep -c \"CLOSED\" || echo 0)\n ALL_TOTAL=$(bd children \"$EPIC_ID\" 2>/dev/null | wc -l || echo 0)\n\n if [[ $ALL_CLOSED -eq $ALL_TOTAL ]]; then\n echo \"\u003cpromise>DONE\u003c/promise>\"\n else\n echo \"\u003cpromise>BLOCKED\u003c/promise>\"\n echo \"No ready issues but $((ALL_TOTAL - ALL_CLOSED)) issues remain unclosed.\"\n fi\nelse\n # Continue to next wave - return to Step 3\nfi\n```\n\n### Step 8: Final Validation\n\nWhen the epic is DONE:\n\n```bash\n$vibe validate the completed epic\n```\n\n### Step 8.5: Archive Shared Task Notes\n\nMove the shared notes to an archive after epic completion:\n\n```bash\nif [ -f .agents/crank/SHARED_TASK_NOTES.md ]; then\n mkdir -p .agents/crank/archives\n mv .agents/crank/SHARED_TASK_NOTES.md \\\n \".agents/crank/archives/SHARED_TASK_NOTES-${EPIC_ID:-unknown}-$(date +%Y%m%d-%H%M%S).md\"\nfi\n```\n\n## Retry Policy\n\n- Max 2 retries per issue across all waves\n- On third failure: mark BLOCKED and continue with remaining issues\n- Track retries with `bd comments add \"$issue_id\" \"retry $N: $reason\"`\n\n## Failure Recovery\n\n| Scenario | Action |\n|----------|--------|\n| Worker timeout | Mark BLOCKED, log reason, continue wave |\n| Test failure | Identify breaking change, retry once |\n| All workers fail | `\u003cpromise>BLOCKED\u003c/promise>` with diagnostics |\n| File conflict detected | Split into sub-waves, re-run |\n\n## Reference Documents\n\n- [references/de-sloppify.md](references/de-sloppify.md) - cleanup pass after implementation waves\n- [references/parallel-wave-isolation.md](references/parallel-wave-isolation.md) - branch-isolation rule + conditional ephemeral worktrees + cleanup gate for parallel waves\n- [references/plan-mutations.md](references/plan-mutations.md) - plan mutation audit trail for drift analysis\n- [references/shared-task-notes.md](references/shared-task-notes.md) - cross-wave context persistence\n- [references/commit-strategies.md](references/commit-strategies.md) - per-task vs wave-batch commits\n- [references/contract-template.md](references/contract-template.md) - contract template for worker specs\n- [references/failure-recovery.md](references/failure-recovery.md) - escalation and retry logic\n- [references/failure-taxonomy.md](references/failure-taxonomy.md) - failure classification\n- [references/fire.md](references/fire.md) - FIRE loop specification\n- [references/ralph-loop-contract.md](references/ralph-loop-contract.md) - Ralph Wiggum loop contract\n- [references/taskcreate-examples.md](references/taskcreate-examples.md) - task creation examples\n- [references/team-coordination.md](references/team-coordination.md) - worker coordination details\n- [references/worker-specs.md](references/worker-specs.md) - per-worker model/tool/prompt specs\n- [references/external-gate-protocol.md](references/external-gate-protocol.md) - external gate protocol for wave validation\n- [references/test-first-mode.md](references/test-first-mode.md) - test-first wave sequence\n- [references/troubleshooting.md](references/troubleshooting.md) - common issues and fixes\n- [references/uat-integration-wave.md](references/uat-integration-wave.md) - UAT integration wave patterns\n- [references/wave-patterns.md](references/wave-patterns.md) - acceptance checks and checkpoints\n- [references/gc-pool-dispatch.md](references/gc-pool-dispatch.md) - gc pool worker dispatch\n- [references/wave1-spec-consistency-checklist.md](references/wave1-spec-consistency-checklist.md) - Wave 1 spec consistency checklist\n- [references/worktree-per-worker.md](references/worktree-per-worker.md) - worktree isolation pattern\n\n\u003c!-- Lifecycle integration wired: 2026-03-28. See skills/crank/SKILL.md for canonical -->\n---","attachment_filenames":[".agentops-generated.json","prompt.md","references/branch-isolation.md","references/commit-strategies.md","references/contract-template.md","references/de-sloppify.md","references/external-gate-protocol.md","references/failure-recovery.md","references/failure-taxonomy.md","references/fire.md","references/gc-pool-dispatch.md","references/parallel-wave-isolation.md","references/plan-mutations.md","references/ralph-loop-contract.md","references/shared-task-notes.md","references/taskcreate-examples.md","references/team-coordination.md","references/test-first-mode.md","references/troubleshooting.md","references/uat-integration-wave.md","references/wave-patterns.md","references/wave1-spec-consistency-checklist.md","references/worker-specs.md","references/worktree-per-worker.md","scripts/validate-wave-checkpoint.sh","scripts/validate.sh"],"attachments":[{"filename":".agentops-generated.json","content":"{\n \"generator\": \"manual-maintained\",\n \"source_skill\": \"skills/crank\",\n \"layout\": \"modular\",\n \"source_hash\": \"96897f552e614ef9a4ed36557e8287262c5000775364c9dae3f5be31a0a04ecd\",\n \"generated_hash\": \"d1f156a392be40cb5f72a424de9a7c165df4c1677c984a963cf20ad1cbd15c6f\"\n}\n","content_type":"application/json; charset=utf-8","language":"json","size":269,"content_sha256":"90cc0f05af31068fb8d49d84226b4fc4f2a69f1cf451b77f1f9e02c88fc514b9"},{"filename":"prompt.md","content":"# crank\n\nExecute epics hands-free with Codex-native wave progression.\n\n## Codex Execution Profile\n\n1. Treat `skills/crank/SKILL.md` as canonical execution contract.\n2. Accept either an epic id or `.agents/rpi/execution-packet.json` as the execution handoff.\n3. In execution-packet mode, preserve the packet objective instead of inventing an epic or narrowing to one slice.\n4. Run waves from beads dependencies when tracker mode is beads, and from the execution packet or plan file otherwise.\n5. Keep retries bounded and report blockers with exact issue ids or file-backed task refs.\n6. In Codex hookless mode, run `ao codex ensure-start` before the first wave; the CLI records startup once per thread and skips duplicates automatically.\n\n## Guardrails\n\n1. Prefer direct Codex session-agent orchestration for parallel issue execution; do not reintroduce `$swarm` as a required wrapper.\n2. Do not blur done/partial/blocked status boundaries.\n3. Include validation metadata checks in worker instructions when available.\n4. Leave `ao codex ensure-stop` to closeout skills after the execution loop completes.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":1104,"content_sha256":"839b270d99bf6562de86200612ff1174a2f8f93853424658388d09344d15d883"},{"filename":"references/branch-isolation.md","content":"# Branch Isolation Gate\n\nCut a fresh branch named after the epic ID **before any wave-1 commit**. Parallel sessions targeting `main` (or the same operator branch) can `git reset --hard` each other mid-cycle. This destroyed agentops-zm8 Wave 1 — a sibling session reset `main` while wave 1 was committing, losing the wave's work.\n\n## Gate\n\n```bash\nEPIC_ID=\"\u003cepic-id-from-step-1>\"\nCURRENT_BRANCH=\"$(git branch --show-current)\"\nEXPECTED_BRANCH=\"crank/${EPIC_ID}\"\n\nif [ \"$CURRENT_BRANCH\" = \"main\" ] || [ \"$CURRENT_BRANCH\" = \"master\" ]; then\n echo \"FAIL: refusing to crank on $CURRENT_BRANCH; cut a dedicated branch\"\n echo \" git checkout -b $EXPECTED_BRANCH\"\n exit 1\nfi\n\nif [ \"$CURRENT_BRANCH\" != \"$EXPECTED_BRANCH\" ] && \\\n [[ \"$CURRENT_BRANCH\" != crank/${EPIC_ID}-* ]]; then\n echo \"WARN: current branch ($CURRENT_BRANCH) does not match crank/${EPIC_ID}*\"\n echo \" Set --allow-foreign-branch to suppress, or\"\n echo \" git checkout -b $EXPECTED_BRANCH\"\nfi\n```\n\n## When to skip\n\n- `--allow-foreign-branch`: operator already cut a branch with a different name (e.g., `evolve/\u003cdate>`, an integration branch)\n- **Never skip on `main`/`master`** — that path is unsafe regardless of flags\n\n## Naming convention\n\n- Primary: `crank/\u003cepic-id>` (e.g., `crank/agentops-zm8`)\n- Sub-waves: `crank/\u003cepic-id>-\u003cwave>` (e.g., `crank/agentops-zm8-w2`)\n\nThe convention exists so sibling sessions can detect each other via branch name without coordination.\n\n## Source\n\nagentops-zm8 post-mortem: parallel-session reset clobber.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":1514,"content_sha256":"040acf070777bb42a92cebe246c06c80aca232fe69adbff3f082c6233f1bef97"},{"filename":"references/commit-strategies.md","content":"# Commit Strategies\n\nCrank supports two commit strategies for how changes are committed after task completion.\n\n## wave-batch (default)\n\nThe team lead commits once after all workers in a wave have completed and passed validation.\n\n**Pros:**\n- No merge conflicts (single committer)\n- Clean git history (one commit per wave)\n- Proven pattern across 7+ epics\n\n**Cons:**\n- Coarse bisectability (entire wave in one commit)\n- Harder to attribute changes to specific issues\n\n**Commit message format:** `feat(\u003cepic-id>): wave N - \u003csummary of changes>`\n\n## per-task (opt-in via `--per-task-commits`)\n\nWorkers commit after their individual task passes validation.\n\n**Pros:**\n- Fine-grained git bisect (one commit per issue)\n- Per-issue traceability in git history\n- Better attribution\n\n**Cons:**\n- Merge conflict risk when multiple workers modify overlapping files\n- Requires parallel-wave guard for safety\n\n**Commit message format:** `feat(\u003cissue-id>): \u003cissue-title>`\n\n## Parallel-Wave Guard (mandatory for per-task)\n\nWhen a wave has 2+ workers modifying overlapping files, per-task commits are automatically disabled for that wave:\n\n1. Before wave start, check file boundaries from plan/task metadata\n2. **If file boundaries are absent** for any worker in a multi-worker wave → fall back to wave-batch (safe default). Only allow per-task when ALL workers have explicit boundary declarations.\n3. If any file appears in 2+ workers' boundaries → fall back to wave-batch\n3. Log: \"Per-task commits disabled for wave N (overlapping file boundaries: \u003cfiles>). Using wave-batch.\"\n4. Record fallback in wave checkpoint JSON: `\"commit_strategy\": \"wave-batch-fallback\"`\n\nSingle-worker waves are always safe for per-task commits (no conflict possible).\n\n## State Tracking\n\nWhen `--per-task-commits` is active:\n- `crank_state.per_task_commits = true`\n- Each wave checkpoint includes: `\"commit_strategy\": \"per-task\" | \"wave-batch\" | \"wave-batch-fallback\"`\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":1938,"content_sha256":"2dadc6dba5c89d147a34fae539b57a333b8a7952b924b93ec5bc00d1c45cb897"},{"filename":"references/contract-template.md","content":"# Contract Template\n\n> One contract per issue. Spec workers fill this out before implementation begins.\n\n---\n\n```yaml\n# --- Contract Frontmatter ---\nissue: # e.g., ag-abc.3\nframework: # go | python | typescript | rust | shell\ncategory: # feature | bugfix | refactor | docs | chore | ci\n```\n\n---\n\n## Problem\n\n\u003c!-- 1-2 sentences. What is broken, missing, or suboptimal? -->\n\n## Inputs\n\n\u003c!-- Bullet list: name, type, description -->\n\n- `inputName` (type) — description\n\n## Outputs\n\n\u003c!-- Bullet list: name, type, description -->\n\n- `outputName` (type) — description\n\n## Invariants\n\n\u003c!-- Numbered list. Minimum 3. These are properties that must ALWAYS hold. -->\n\n1. ...\n2. ...\n3. ...\n\n## Failure Modes\n\n\u003c!-- Numbered list: what could go wrong → expected behavior -->\n\n1. **Condition** → expected behavior\n2. **Condition** → expected behavior\n\n## Out of Scope\n\n\u003c!-- Explicitly excluded items — prevents scope creep -->\n\n- ...\n\n## Test Cases\n\n\u003c!-- Map each test case to an invariant. Cover: boundaries, errors, success path. -->\n\n| # | Input | Expected | Validates Invariant |\n|---|-------|----------|---------------------|\n| 1 | ... | ... | #1 |\n| 2 | ... | ... | #2 |\n| 3 | ... | ... | #3 |\n\n## Contract Granularity\n\n- **1 contract per issue.** Do not combine multiple issues into one contract.\n- **Test boundaries, errors, and success paths.** Every contract must have at least one test case for each category.\n- **Acceptance criteria are user-facing.** Invariants describe system properties; acceptance criteria describe what the user sees. Keep them separate — invariants go here, acceptance criteria go in the issue.\n\n---\n\n# EXAMPLE: Add Rate Limiting Middleware\n\n```yaml\nissue: ag-xyz.5\nframework: go\ncategory: feature\n```\n\n## Problem\n\nAPI endpoints accept unlimited requests per client, enabling abuse and risking resource exhaustion under load.\n\n## Inputs\n\n- `request` (*http.Request) — incoming HTTP request with client IP in RemoteAddr\n- `config.RateLimit` (int) — max requests per window per client (default: 100)\n- `config.RateWindow` (time.Duration) — sliding window duration (default: 1 minute)\n\n## Outputs\n\n- **Pass-through** — request forwarded to next handler with `X-RateLimit-Remaining` header\n- **429 response** — JSON error body `{\"error\": \"rate limit exceeded\", \"retry_after\": \u003cseconds>}` with `Retry-After` header\n\n## Invariants\n\n1. A client sending ≤ `RateLimit` requests within `RateWindow` is never rejected.\n2. A client exceeding `RateLimit` within `RateWindow` receives HTTP 429 for every subsequent request until the window expires.\n3. Rate limit state for one client never affects another client's quota.\n4. The middleware adds \u003c 1ms p99 latency to the request path.\n5. If the rate limit store is unavailable, requests pass through (fail-open) and an error is logged.\n\n## Failure Modes\n\n1. **Rate store unreachable** → fail-open, log error, increment `ratelimit_store_errors_total` metric.\n2. **Malformed RemoteAddr** → treat as unknown client, apply default limit, log warning.\n3. **Clock skew between instances** → accept up to 2× burst during window overlap (documented trade-off).\n\n## Out of Scope\n\n- Distributed rate limiting across multiple instances (future work).\n- Per-endpoint rate limits (all endpoints share the same limit).\n- Authentication-aware rate limiting (keyed by IP only).\n\n## Test Cases\n\n| # | Input | Expected | Validates Invariant |\n|---|-------|----------|---------------------|\n| 1 | 100 requests from same IP in 60s | All 100 return 200 | #1 — at-limit success |\n| 2 | 101st request from same IP in 60s | Returns 429 with `Retry-After` header | #2 — over-limit rejection |\n| 3 | 100 requests from IP-A, 100 from IP-B | All 200 return 200 | #3 — client isolation |\n| 4 | Request when rate store returns error | Returns 200, error logged | #5 — fail-open behavior |\n| 5 | Wait for window expiry after 429 | Next request returns 200 | #2 — window reset |\n| 6 | Benchmark 10k requests | p99 \u003c 1ms overhead | #4 — latency bound |\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4037,"content_sha256":"d15a8b98657fd785bb42c7cdafb2a56d047ce673a4a06ac03d29a72b5f267720"},{"filename":"references/de-sloppify.md","content":"# De-Sloppify Pattern\n\n> Separate cleanup pass after implementation. Two focused agents > one constrained agent.\n\n## Problem\n\nImplementation agents optimize for completeness — they over-generate:\n- Unnecessary type-system tests (testing Go's type system, not business logic)\n- Redundant nil checks on values that can't be nil\n- Console/debug logging left behind\n- Commented-out code \"just in case\"\n- Over-defensive error handling for impossible scenarios\n- Coverage-padding tests that don't assert behavior\n\nTelling the implementer \"don't do X\" makes it slower and worse at the main job.\n\n## Solution: Two-Phase Execution\n\n### Phase 1: Implement (no constraints)\nThe implementation worker focuses purely on making the feature work with full TDD:\n```\nImplement \u003cissue-description>.\nWrite tests that verify behavioral correctness.\n```\n\n### Phase 2: De-Sloppify (cleanup only)\nA separate cleanup worker reviews the implementation output:\n```\nReview the changes from the previous implementation wave.\nRemove ONLY:\n- Tests that assert type-system behavior (e.g., \"field is not empty string\")\n- Redundant nil/error checks on values guaranteed by the caller\n- Console.log / fmt.Println debugging statements\n- Commented-out code blocks\n- Coverage-padding tests (trivial != nil or != \"\" assertions)\n- Unused imports or variables\n\nDO NOT:\n- Change business logic\n- Remove error handling at system boundaries\n- Remove tests that assert behavioral correctness\n- Add new functionality\n```\n\n## Integration with /crank\n\n### Automatic Mode (recommended)\nAfter each implementation wave, crank can optionally run a de-sloppify pass:\n\n```\nWave N: Implement issues [A, B, C] → /swarm executes\nWave N.5: De-sloppify wave N output → single cleanup worker\nWave N+1: Next implementation wave\n```\n\nThe de-sloppify wave is lightweight — single worker, no parallelism needed.\n\n### Manual Mode\n```bash\n/vibe --quick recent # quick check, no agents\n# Review findings, then:\n# Apply cleanup manually or spawn cleanup worker\n```\n\n## What De-Sloppify Catches\n\n| Slop Type | Detection | Example |\n|-----------|-----------|---------|\n| Type-system tests | Test name contains \"Type\", asserts only `!= nil` or `!= \"\"` | `TestFoo_ReturnsNonNil` |\n| Debug logging | `fmt.Print`, `console.log`, `print()` in non-test code | `fmt.Println(\"DEBUG:\", value)` |\n| Commented code | Blocks of `// old implementation` | Entire functions commented out |\n| Dead imports | Imported but unused packages | `\"fmt\"` when only `log` is used |\n| Over-defensive | nil checks after guaranteed-non-nil calls | `if err != nil` after `strings.Join()` |\n| Coverage padding | `cov*_test.go` files, trivial assertions | `assert result != nil` |\n\n## Metrics\n\nTrack de-sloppify effectiveness:\n- Lines removed per wave (target: 5-15% of implementation output)\n- False positives (removed something that was needed) — should be \u003c1%\n- Time cost (should be \u003c20% of implementation wave time)\n\nIf de-sloppify consistently removes >20% of implementation output, the implementation prompt needs tightening.\nIf it removes \u003c2%, skip de-sloppify for efficiency.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3097,"content_sha256":"d4540092dca21551db747d49b26038caa9167a87761bf4a5d4a78897003fbc67"},{"filename":"references/external-gate-protocol.md","content":"# External Gate Protocol\n\n> Workers must use external gates, not self-assessment. From Ralph Loop pattern and 124 council FAIL analyses.\n\n## The Rule\n\nWorkers MUST NOT declare their own work complete. Every wave completion requires an external gate — a runnable command that returns 0 (pass) or non-zero (fail), executed by the orchestrator, not the worker.\n\n## Why This Matters\n\n- Unit tests found zero production bugs across 14,753 sessions analyzed\n- L3+ tests (integration, E2E) found all real bugs\n- Zero-context smoke tests find 3–5x more issues than self-review\n- Self-grading is confirmation bias — the worker who wrote the code is biased toward \"looks good\"\n\n## Gate Hierarchy\n\n| Gate Level | What It Checks | Who Runs It |\n|------------|---------------|-------------|\n| L0: Build | Code compiles | CI / orchestrator |\n| L1: Unit | Function-level correctness | CI / orchestrator |\n| L2: Integration | Component interaction | CI / orchestrator |\n| L3: E2E | Full workflow | CI / orchestrator |\n| L4: Smoke | Production-like behavior | Fresh-context validator |\n\n**Minimum for wave completion:** L0 + L1 + L2 must pass. L3 recommended.\n\n## Ralph Loop Back-Pressure\n\nWhen a gate fails 3+ times consecutively on the same issue:\n\n1. **STOP** — do not retry the same approach\n2. **Escalate** — mark the issue as BLOCKED\n3. **Diagnose** — read the error, check assumptions\n4. **Rollback** if needed — auto-commits from prior passing gates provide rollback points\n\n## Wave Validation Sequence\n\n```\nWorker completes issue\n → Orchestrator runs gate command (NOT worker self-report)\n → Gate passes? → Mark issue DONE, proceed to next\n → Gate fails? → Increment failure counter\n → 3+ failures? → BLOCK issue, move to next or escalate\n → \u003c 3 failures? → Worker retries with error context\n```\n\n## Anti-Patterns\n\n- ❌ Worker runs tests and reports \"all pass\" → orchestrator trusts\n- ❌ Acceptance criteria: \"verify it works\" (no runnable command)\n- ❌ Wave advances without any gate execution\n- ✅ Orchestrator runs `make test` after worker signals completion\n- ✅ Each issue has a specific gate command in its acceptance criteria\n- ✅ Failed gates increment a counter visible to the orchestrator\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":2240,"content_sha256":"5b19fcd77e90c895747d32167f1fb933bdb6c014c7b5a1717734500b28fc2188"},{"filename":"references/failure-recovery.md","content":"# Failure Recovery\n\n## Validation Failure Handling\n\n**On swarm validation failure:**\n\n1. Do NOT close the beads issue\n2. Add failure context:\n ```bash\n bd comments add \u003cissue-id> \"Validation failed: \u003creason>. Retrying...\" 2>/dev/null\n ```\n3. Re-add to next wave\n4. After 3 failures, escalate:\n ```bash\n bd update \u003cissue-id> --labels BLOCKER 2>/dev/null\n bd comments add \u003cissue-id> \"ESCALATED: 3 validation failures. Human review required.\" 2>/dev/null\n ```\n\n## Wave Limit Enforcement\n\n```bash\n# CHECK GLOBAL LIMIT before each wave\nif [[ $wave -ge 50 ]]; then\n echo \"\u003cpromise>BLOCKED\u003c/promise>\"\n echo \"Global wave limit (50) reached. Remaining issues:\"\n # Beads mode: bd children \u003cepic-id> --status open\n # STOP - do not continue\nfi\n```\n\n## Pre-flight Check: Issues Exist\n\n**Verify there are issues to work on:**\n\n```\nSTOP and return error:\n \"No ready issues found for this epic. Either:\n - All issues are blocked (check dependencies)\n - Epic has no child issues (run $plan first)\n - All issues already completed\"\n```\n\nAlso verify: epic has at least 1 child issue total. An epic with 0 children means $plan was not run.\n\nDo NOT proceed with empty issue list - this produces false \"epic complete\" status.\n\n## Final Batched Validation\n\nWhen all issues complete, check whether a full $vibe is needed:\n\n```bash\n# Check wave checkpoint verdicts — skip final vibe if ALL waves passed clean\nALL_PASS=true\nfor checkpoint in .agents/crank/wave-*-checkpoint.json; do\n verdict=$(jq -r '.acceptance_verdict // \"UNKNOWN\"' \"$checkpoint\" 2>/dev/null)\n if [[ \"$verdict\" != \"PASS\" ]]; then\n ALL_PASS=false\n break\n fi\ndone\n```\n\n**If ALL waves passed acceptance check with PASS verdict (no WARNs, no retries):**\nSkip the final $vibe — per-wave acceptance checks already validated acceptance criteria. Proceed directly to Step 8 (learnings extraction).\n\n**If ANY wave had WARN, FAIL, or missing verdicts:**\nRun ONE comprehensive vibe on recent changes:\n\n```bash\n# Get list of changed files from recent commits\ngit diff --name-only HEAD~10 2>/dev/null | sort -u\n```\n\n```\nTool: Skill\nParameters:\n skill: \"agentops:vibe\"\n args: \"recent\"\n```\n\n**If CRITICAL issues found:**\n1. Fix them\n2. Re-run vibe on affected files\n3. Only proceed to completion when clean\n\n## Retry Strategy\n\n| Failure Type | Action |\n|--------------|--------|\n| Validation failure | Re-add to next wave (max 3 attempts) |\n| Blocked dependencies | Escalate after 3 checks |\n| Context exhaustion (distributed) | Checkpoint + spawn replacement |\n| Build failure | Re-add to retry queue |\n| Spec impossible | Mark blocked, escalate immediately |\n\n## Escalation\n\nWhen issues cannot be resolved automatically:\n- Mark with BLOCKER label (beads mode)\n- Output `\u003cpromise>BLOCKED\u003c/promise>` with reason\n- List remaining issues for human review\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":2842,"content_sha256":"384bcb94e6cd8e917180e95925e4fe89394f83fb1c1f349c692e8b77ffdc3432"},{"filename":"references/failure-taxonomy.md","content":"# Failure Taxonomy\n\n> **Classification and handling of failures in autonomous execution.**\n\n## Overview\n\nFailures in crank execution fall into distinct categories, each with specific detection methods and remediation strategies. The goal is always: **continue the epic, escalate what can't be fixed**.\n\n## Failure Categories\n\n### 1. Polecat Stuck\n\n**Symptoms**:\n- No status change for 5+ poll intervals (2.5 min)\n- Convoy shows `running` but no progress\n- gc session shows no progress\n\n**Detection**:\n\n```bash\n# Check session status\ngc session list --json | jq '.[] | select(.state == \"active\")'\n\n# Peek at agent output\ngc session peek \u003cagent> --lines 30\n```\n\n**Causes**:\n- Waiting for user input\n- Infinite loop in code\n- External service timeout\n- Claude usage limit hit\n\n**Remediation**:\n\n```bash\n# Step 1: Nudge the agent\ngc session nudge \u003cagent> \"continue with your assigned task\"\n\n# Step 2: Wait one poll interval (30s)\n\n# Step 3: If still stuck, check for usage limit\ngc session peek \u003cagent> --lines 50 | grep -i \"limit\"\n\n# Step 4: If usage limit, nuke and re-sling after cooldown\n# WARNING: This destroys the polecat session. Ensure work is saved.\ngt polecat nuke \u003crig>/\u003cname> --force\n# Wait for limit reset, then:\ngt sling \u003cissue> \u003crig>\n\n# Step 5: If other cause, nuke and re-sling immediately\n# WARNING: This destroys the polecat session. Ensure work is saved.\ngt polecat nuke \u003crig>/\u003cname> --force\ngt sling \u003cissue> \u003crig>\n```\n\n**Escalation trigger**: 3 consecutive nudge failures\n\n---\n\n### 2. Validation Failure\n\n**Symptoms**:\n- Polecat completes but issue not closed\n- `.agents/validations/` contains failure artifacts\n- Commit exists but tests/lint failing\n\n**Detection**:\n\n```bash\n# Check polecat output\ngc session peek \u003cagent> --lines 50 | grep -i \"fail\\|error\"\n\n# Check validation artifacts\nls ./polecats/\u003cpolecat>/.agents/validations/\n\n# Check CI if applicable\ngit -C ./polecats/\u003cpolecat> log -1 --format=\"%H\" | xargs gh run list --commit\n```\n\n**Causes**:\n- Tests failing\n- Lint errors\n- Type check failures\n- Security scan findings\n- Build failures\n\n**Remediation**:\n\n```bash\n# Step 1: Add failure context to issue\nbd comments add \u003cissue> \"Validation failed: $(cat validation-output.txt | head -50)\"\n\n# Step 2: Re-sling with hint\nbd comments add \u003cissue> \"HINT: Focus on fixing \u003cspecific failure>\"\ngt sling \u003cissue> \u003crig>\n\n# Step 3: If second failure, be more specific\nbd comments add \u003cissue> \"EXPLICIT: The test_auth_flow test fails because X. Fix by Y.\"\ngt sling \u003cissue> \u003crig>\n```\n\n**Escalation trigger**: 3 validation failures (may need human insight)\n\n---\n\n### 3. Dependency Deadlock\n\n**Symptoms**:\n- Multiple issues show as `blocked`\n- No issues in `ready` state\n- Circular dependency detected\n\n**Detection**:\n\n```bash\n# Check for circular deps\nbd blocked --parent=\u003cepic> --show-deps\n\n# Manual trace\nbd show \u003cissue-a> | grep \"blocked by\"\nbd show \u003cissue-b> | grep \"blocked by\"\n# If A -> B -> A, deadlock exists\n```\n\n**Causes**:\n- Incorrectly specified dependencies\n- Missing issue that should break the cycle\n- Overly aggressive blocking\n\n**Remediation**:\n\n```bash\n# Step 1: Identify the cycle\nbd dep graph \u003cepic> # Visual if available\n\n# Step 2: Remove weakest dependency\nbd dep remove \u003cissue> \u003cblocking-issue>\n\n# Step 3: Add comment explaining\nbd comments add \u003cissue> \"Removed dep on \u003cblocking> to break deadlock.\nMay need manual integration after both complete.\"\n\n# Step 4: Continue cranking\n# Issues should now become ready\n```\n\n**Escalation trigger**: Immediate if auto-resolution fails\n\n---\n\n### 4. Context Limit\n\n**Symptoms**:\n- Polecat stops mid-work\n- Message about \"context limit\" or \"token limit\"\n- Partial work committed\n\n**Detection**:\n\n```bash\ngc session peek \u003cagent> --lines 50 | grep -i \"context\\|token\\|limit\"\n```\n\n**Causes**:\n- Large files read into context\n- Long conversation history\n- Complex multi-file changes\n\n**Remediation**:\n\n```bash\n# Step 1: Checkpoint current progress\ngit -C ./polecats/\u003cpolecat> stash # If uncommitted work\n\n# Step 2: Check what was accomplished\ngit -C ./polecats/\u003cpolecat> log --oneline -5\n\n# Step 3: Update issue with progress\nbd comments add \u003cissue> \"Partial progress: \u003cwhat was done>. Remaining: \u003cwhat's left>\"\n\n# Step 4: Fresh polecat\ngt polecat nuke \u003crig>/\u003cname> --force\ngt sling \u003cissue> \u003crig>\n\n# The new polecat reads the comment and continues from there\n```\n\n**Escalation trigger**: 2 context limit failures (may need issue decomposition)\n\n---\n\n### 5. Git Conflict\n\n**Symptoms**:\n- Merge/rebase fails\n- `.beads/` conflicts\n- Branch divergence\n\n**Detection**:\n\n```bash\ngit -C ./polecats/\u003cpolecat> status | grep -i \"conflict\\|diverged\"\n```\n\n**Causes**:\n- Parallel work on same files\n- Stale branch\n- Beads sync race\n\n**Remediation**:\n\n```bash\n# For beads conflicts (most common)\ngit -C ./polecats/\u003cpolecat> checkout --theirs .beads/issues.jsonl\ngit -C ./polecats/\u003cpolecat> add .beads/issues.jsonl\ngit -C ./polecats/\u003cpolecat> commit -m \"merge: resolve beads conflict\"\n\n# For code conflicts\n# Step 1: Check if conflict is trivial\ngit -C ./polecats/\u003cpolecat> diff --name-only --diff-filter=U\n\n# Step 2: If simple, nudge polecat to resolve\ntmux send-keys -t gt-\u003crig>-\u003cpolecat> \"resolve the git conflicts and continue\" Enter\n\n# Step 3: If complex, abort and re-sling with fresh base\ngit -C ./polecats/\u003cpolecat> merge --abort\ngit -C ./polecats/\u003cpolecat> fetch origin\ngit -C ./polecats/\u003cpolecat> reset --hard origin/main\ngt sling \u003cissue> \u003crig>\n```\n\n**Escalation trigger**: 2 conflict failures on same files (architectural issue)\n\n---\n\n### 6. External Service Failure\n\n**Symptoms**:\n- Timeouts in polecat output\n- API errors (429, 500, etc.)\n- Network connectivity issues\n\n**Detection**:\n\n```bash\ngc session peek \u003cagent> --lines 50 | grep -i \"timeout\\|429\\|500\\|network\\|connection\"\n```\n\n**Causes**:\n- Rate limiting\n- Service outage\n- Network partition\n- API credential expiry\n\n**Remediation**:\n\n```bash\n# Step 1: Identify the service\n# (from polecat output)\n\n# Step 2: Check service status\n# (manual or via status page)\n\n# Step 3: If rate limit, apply backoff\n# Wait BACKOFF_BASE * 2^attempt before retry\n\n# Step 4: If outage, pause affected issues\nbd update \u003cissue> --labels=WAITING_EXTERNAL\nbd comments add \u003cissue> \"Paused: \u003cservice> outage. Resume when service recovers.\"\n\n# Step 5: Continue other issues\n# External failures shouldn't block entire epic\n```\n\n**Escalation trigger**: Immediate for credential issues, after recovery for outages\n\n---\n\n### 7. Polecat Crash\n\n**Symptoms**:\n- gc session disappeared from session list\n- Agent not in `gc status --json`\n- Issue still shows `in_progress`\n\n**Detection**:\n\n```bash\ngc session list --json | jq '.[] | select(.alias == \"\u003cagent>\")'\ngc status --json | jq '.agents[] | select(.name == \"\u003cagent>\")'\n```\n\n**Causes**:\n- OOM kill\n- Segfault in tooling\n- System restart\n- Manual termination\n\n**Remediation**:\n\n```bash\n# Step 1: Clean up orphaned state\ngt polecat nuke \u003crig>/\u003cname> --force 2>/dev/null || true\n\n# Step 2: Reset issue status\nbd update \u003cissue> --status=open\n\n# Step 3: Add crash context\nbd comments add \u003cissue> \"Previous polecat crashed. No partial work recovered.\"\n\n# Step 4: Re-sling\ngt sling \u003cissue> \u003crig>\n```\n\n**Escalation trigger**: 2 crashes (may indicate systemic issue)\n\n---\n\n## Failure Handling Matrix\n\n| Failure Type | Detection Cost | Auto-Recovery | Retry Limit | Escalation Action |\n|--------------|----------------|---------------|-------------|-------------------|\n| Polecat Stuck | ~200 tokens | Nudge, nuke | 3 | BLOCKER + mail |\n| Validation Fail | ~150 tokens | Hints | 3 | BLOCKER + mail |\n| Dependency Deadlock | ~100 tokens | Remove dep | 1 | Immediate mail |\n| Context Limit | ~50 tokens | Checkpoint, re-sling | 2 | Decompose issue |\n| Git Conflict | ~100 tokens | Auto-resolve | 2 | BLOCKER + mail |\n| External Service | ~50 tokens | Backoff | 5 | WAITING label |\n| Polecat Crash | ~50 tokens | Clean re-sling | 2 | Check system |\n\n## Escalation Protocol\n\nWhen MAX_RETRIES exhausted:\n\n```bash\n# 1. Mark issue as BLOCKER\nbd update \u003cissue> --labels=BLOCKER\n\n# 2. Add detailed failure report\nbd comments add \u003cissue> \"$(cat \u003c\u003c'EOF'\n## AUTO-ESCALATION REPORT\n\n**Issue**: \u003cissue-id>\n**Epic**: \u003cepic-id>\n**Failure Type**: \u003ctype>\n**Attempts**: 3/3\n\n### Attempt 1\n- Polecat: \u003cname>\n- Duration: \u003ctime>\n- Failure: \u003creason>\n\n### Attempt 2\n- Polecat: \u003cname>\n- Duration: \u003ctime>\n- Failure: \u003creason>\n\n### Attempt 3\n- Polecat: \u003cname>\n- Duration: \u003ctime>\n- Failure: \u003creason>\n\n### Recommendation\n\u003cwhat human should investigate>\nEOF\n)\"\n\n# 3. Mail human (--human, not mayor/ since we ARE mayor)\ngt mail send --human -s \"BLOCKER: \u003cissue> - \u003cfailure-type>\" -m \"See issue for details\"\n\n# 4. Continue epic (don't halt for one blocker)\n# Other issues can still proceed\n```\n\n## Post-Failure Analysis\n\nAfter epic completion (or major milestone), analyze failures:\n\n```bash\n# List all issues that required retries\nbd list --parent=\u003cepic> --has-label=BLOCKER\nbd list --parent=\u003cepic> --has-label=WAITING_EXTERNAL\n\n# Check retry patterns\n# (requires custom tooling or log analysis)\n\n# Feed into retrospective\n/retro --topic=\"crank failures on \u003cepic>\"\n```\n\n## Prevention Strategies\n\nBased on failure patterns:\n\n| Pattern | Prevention |\n|---------|------------|\n| Frequent context limits | Decompose large issues |\n| Repeated validation fails | Add pre-validation to issues |\n| Git conflicts | Smaller, focused changes |\n| External service issues | Add circuit breaker patterns |\n| Polecat crashes | Monitor system resources |\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":9443,"content_sha256":"4fa698f54052048563dd9c025f9f261a53ab40f0ad10c52071a32d25fe5811fa"},{"filename":"references/fire.md","content":"# FIRE Loop Specification\n\n> **Find-Ignite-Reap-Escalate**: The Brownian Ratchet engine powering autonomous execution.\n\n## Overview\n\nFIRE is the reconciliation loop that extracts progress from chaos. Like a forge that transforms raw ore into refined steel, FIRE continuously drives an epic toward completion through parallel attempts filtered by validation.\n\n**Design philosophy**: Chaos + Filter + Ratchet = Progress.\n\n```\n ┌──────────────────────────────────────────────────────────┐\n │ FIRE LOOP │\n │ │\n │ FIND ────► IGNITE ────► REAP ────► ESCALATE │\n │ (state) (chaos) (ratchet) (recovery) │\n │ │ │ │\n │ └───────────────────────────────────┘ │\n │ (loop) │\n │ │\n │ EXIT when: all children closed │\n └──────────────────────────────────────────────────────────┘\n```\n\n## The Brownian Ratchet\n\n| Phase | Ratchet Role | Description |\n|-------|--------------|-------------|\n| **FIND** | Observe | Read current state, identify ready work |\n| **IGNITE** | **Chaos** | Spark parallel polecats, embrace variance |\n| **REAP** | **Filter + Ratchet** | Harvest results, validate, merge (permanent) |\n| **ESCALATE** | Recovery | Handle failures, retry or escalate to human |\n\n**Key insight**: Polecats can fail independently. Each successful merge ratchets forward. The system extracts progress from parallel attempts, filtering failures automatically.\n\n---\n\n## Loop Phases\n\n### FIND Phase\n\n**Purpose**: Build current state snapshot. What's ready? What's burning? What's done?\n\n**Commands**:\n\n```bash\nbd ready --parent=\u003cepic> # Ready to ignite\nbd list --parent=\u003cepic> --status=in_progress # Currently burning\nbd list --parent=\u003cepic> --status=closed # Reaped\nbd blocked --parent=\u003cepic> # Waiting on deps\ngt convoy list # Active convoys \u003c!-- FUTURE: gt convoy not yet implemented -->\n```\n\n**State object**:\n\n```yaml\nfire_state:\n epic_id: gt-0100\n total_children: 8\n\n # Work pools\n ready: [gt-0101, gt-0102] # Can ignite\n burning: [gt-0103, gt-0104] # In-flight\n reaped: [gt-0105, gt-0106] # Completed\n blocked: [gt-0107, gt-0108] # Waiting\n\n # Derived\n remaining: 6 # total - reaped\n capacity: 2 # MAX_POLECATS - burning\n complete: false # remaining == 0\n```\n\n**Token cost**: ~200-300 tokens\n\n---\n\n### IGNITE Phase\n\n**Purpose**: Spark parallel polecats. This is the CHAOS - multiple independent attempts.\n\n**Decision logic**:\n\n```python\ndef ignite_phase(state, retry_queue):\n to_ignite = []\n\n # Priority 1: Scheduled retries that are due\n for issue, scheduled_time in retry_queue:\n if now() >= scheduled_time:\n to_ignite.append(issue)\n retry_queue.remove(issue)\n\n # Priority 2: Fresh ready issues\n for issue in state.ready:\n if issue not in to_ignite:\n to_ignite.append(issue)\n\n # Respect capacity\n to_ignite = to_ignite[:state.capacity]\n\n # IGNITE - spark the chaos\n for issue in to_ignite:\n gt_sling(issue, rig)\n\n return to_ignite\n```\n\n**Commands**:\n\n```bash\n# Batch ignite - preferred (each issue gets own polecat)\ngt sling \u003cissue1> \u003cissue2> \u003cissue3> \u003crig>\n\n# Single ignite\ngt sling \u003cissue> \u003crig>\n\n# Find stranded convoys (ready work, no workers)\ngt convoy stranded # FUTURE: gt convoy not yet implemented\n```\n\n**Token cost**: ~50 tokens per dispatch\n\n---\n\n### REAP Phase\n\n**Purpose**: Harvest results. This is the FILTER + RATCHET - validate completions, merge permanently.\n\nThe REAP phase combines monitoring and collection into a single harvest operation:\n\n1. **Monitor** - Poll for completion\n2. **Validate** - Verify work quality (the FILTER)\n3. **Merge** - Lock progress (the RATCHET)\n\n**Monitoring**:\n\n```bash\n# Primary: Convoy dashboard (lowest token cost)\ngt convoy status \u003cconvoy-id> # FUTURE: gt convoy not yet implemented\n\n# Secondary: Individual polecat check\ngt polecat status \u003crig>/\u003cname>\n\n# Tertiary: Peek at work (debugging only)\ngc session peek \u003cagent> --lines 20\n```\n\n**Poll interval**: 30 seconds\n\n| Convoy Status | Meaning | Action |\n|---------------|---------|--------|\n| `running` | Polecats burning | Continue monitoring |\n| `partial` | Some done | Reap completed, continue |\n| `complete` | All done | Reap all |\n| `failed` | Some failed | Reap successes, escalate failures |\n| `stalled` | No progress 5+ polls | Investigate |\n\n**Validation (the FILTER)**:\n\n```python\ndef validate_completion(issue, polecat):\n \"\"\"Filter: only valid completions ratchet forward.\"\"\"\n\n # Check beads status\n status = bd_show(issue).status\n if status != 'closed':\n return False, \"Status not closed\"\n\n # Check git work exists\n commits = git_log(polecat_path, count=1)\n if not commits:\n return False, \"No commits found\"\n\n # Check commit references issue\n if issue not in commits[0].message:\n return False, \"Commit doesn't reference issue\"\n\n return True, \"Validated\"\n```\n\n**Merge (the RATCHET)**:\n\n```bash\n# Polecats self-merge via gt done:\n# push → submit to merge queue → exit\n\n# Post-merge cleanup\ngt polecat gc \u003crig> # Clean merged branches\n```\n\n**Key property**: Once merged, work is PERMANENT. The ratchet doesn't go backward.\n\n**Token cost**: ~250 tokens per reap cycle\n\n---\n\n### ESCALATE Phase\n\n**Purpose**: Handle failures with backoff and human escalation. Failed attempts re-enter the chaos pool or get escalated.\n\n**Retry policy**:\n\n| Attempt | Backoff | Action |\n|---------|---------|--------|\n| 1 | 30s | Re-ignite fresh polecat |\n| 2 | 60s | Re-ignite with context |\n| 3 | 120s | Re-ignite with explicit hints |\n| 4+ | - | **ESCALATE**: BLOCKER + mail human |\n\n**Backoff calculation**:\n\n```python\ndef calculate_backoff(attempt):\n \"\"\"Exponential backoff: 30s * 2^(attempt-1)\"\"\"\n return 30 * (2 ** (attempt - 1))\n```\n\n**Retry (back to chaos pool)**:\n\n```bash\n# Re-ignite with failure context\nbd comments add \u003cissue> \"Previous attempt failed: \u003creason>. Try: \u003chint>\"\ngt sling \u003cissue> \u003crig>\n```\n\n**Escalation (exit chaos pool)**:\n\n```bash\n# Mark as blocker\nbd update \u003cissue> --labels=BLOCKER\n\n# Document failure history\nbd comments add \u003cissue> \"AUTO-ESCALATED: Failed 3 attempts.\nReasons: 1) \u003creason1> 2) \u003creason2> 3) \u003creason3>\nHuman review required.\"\n\n# Mail human\ngt mail send --human -s \"BLOCKER: \u003cissue> failed 3 attempts\" -m \"...\"\n\n# Continue with other issues (don't halt epic)\n```\n\n**Token cost**: ~100 tokens per escalation\n\n---\n\n## State Machine\n\n```\n ┌─────────────────────────────────┐\n │ │\n ▼ │\n┌────────┐ ┌─────────┐ ┌────────┐ ┌──────────┐\n│ FIND │───►│ IGNITE │───►│ REAP │───►│ ESCALATE │\n└────────┘ └─────────┘ └────────┘ └──────────┘\n │ chaos ratchet │\n │ │\n │ (all reaped) │\n ▼ │\n┌────────┐ │\n│ EXIT │◄────────────────────────────────────┘\n└────────┘ (retry scheduled)\n```\n\n---\n\n## Loop Invariants\n\n1. **Progress**: Each iteration must make progress OR escalate\n2. **Bounded**: Retry counts are bounded, escalation is guaranteed\n3. **Idempotent**: Re-running FIND produces same state for same beads\n4. **Recoverable**: State can be reconstructed from beads alone\n5. **Ratchet**: Merged work never goes backward\n\n---\n\n## Concurrency Model\n\n**Single Mayor, Ephemeral Polecats**:\n\n```\nMayor (FIRE Loop)\n │\n ├── Polecat 1 (burning gt-0101) → reaped → nuked\n ├── Polecat 2 (burning gt-0102) → reaped → nuked\n ├── Polecat 3 (burning gt-0103) → failed → escalated\n └── Polecat 4 (burning gt-0104) → reaped → nuked\n```\n\n**Polecat lifecycle**:\n1. `gt sling` ignites polecat with hooked work\n2. Polecat executes via `/implement`\n3. On completion: `gt done` → push → merge queue → exit\n4. Witness nukes sandbox after merge\n5. No idle state - polecats don't wait\n\n**Coordination via beads**:\n- Mayor updates status via `bd update`\n- Polecats work independently\n- Issue state auto-syncs via JSONL; use `bd vc status` only to inspect Dolt state\n\n---\n\n## Token Budget\n\nPer FIRE iteration (30s):\n\n| Phase | Tokens | Notes |\n|-------|--------|-------|\n| FIND | ~300 | bd queries |\n| IGNITE | ~100 | gt sling commands |\n| REAP | ~250 | monitoring + validation |\n| ESCALATE | ~100 | if failures |\n| **Total** | ~750 | per iteration |\n\n**Per hour**: ~90,000 tokens (120 iterations)\n**Per 8-hour run**: ~720,000 tokens\n\nSustainable for long-running autonomous execution.\n\n---\n\n## Error Recovery\n\n**Mayor session crash**:\n```bash\n# State is in beads, not memory\n/crank \u003cepic> \u003crig> # Resumes from beads state\n```\n\n**Polecat stalled**:\n```bash\ngt polecat stale \u003crig> # Find stale\ngt polecat check-recovery \u003crig>/\u003cname> # Decide: recover | nuke\ngt polecat nuke \u003crig>/\u003cname> --force # Destroy\ngt sling \u003cissue> \u003crig> # Re-ignite\n```\n\n**Beads sync conflict**:\n```bash\ngit checkout --theirs .beads/issues.jsonl\ngit add .beads/issues.jsonl\nbd vc status # Optional: inspect Dolt state after resolving the JSONL file\n```\n\n---\n\n## Tuning Parameters\n\n| Parameter | Default | Tuning Guidance |\n|-----------|---------|-----------------|\n| `MAX_POLECATS` | 4 | Increase for large epics, decrease for complex issues |\n| `POLL_INTERVAL` | 30s | Decrease for fast issues, increase to save tokens |\n| `MAX_RETRIES` | 3 | Increase for flaky tests, decrease for clean codebases |\n| `BACKOFF_BASE` | 30s | Increase for rate-limited APIs |\n| `STALL_THRESHOLD` | 5 polls | Decrease for tight deadlines |\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":10962,"content_sha256":"3296bb74740c77a743acfafc87f826eacbff281890aef3c346d8fa5747ee20c2"},{"filename":"references/gc-pool-dispatch.md","content":"# gc Pool Dispatch\n\nWhen `GC_POOL_AVAILABLE=true`, replace `/swarm` invocation with gc pool dispatch:\n- Workers are pre-started by gc pool (no spawn overhead)\n- Assign work via `gc session nudge \u003cworker> \"\u003cissue prompt>\"`\n- Poll completion via `gc status --json` + `bd show \u003cid>` (check issue closed)\n- gc handles crash recovery and session restart automatically\n\n```bash\nif [[ \"$GC_POOL_AVAILABLE\" == \"true\" ]]; then\n for issue in $READY_ISSUES; do\n ISSUE_DETAIL=$(bd show \"$issue\" 2>/dev/null)\n WORKER=$(gc status --json 2>/dev/null | jq -r '.pool.agents[] | select(.state == \"idle\") | .name' | head -1)\n if [[ -n \"$WORKER\" ]]; then\n gc session nudge \"$WORKER\" \"Implement issue $issue: $ISSUE_DETAIL\"\n else\n echo \"No idle gc pool workers — waiting for pool auto-scale\"\n gc pool wait --min-idle 1 --timeout 300\n WORKER=$(gc status --json 2>/dev/null | jq -r '.pool.agents[] | select(.state == \"idle\") | .name' | head -1)\n gc session nudge \"$WORKER\" \"Implement issue $issue: $ISSUE_DETAIL\"\n fi\n done\n # Poll until all wave issues are closed\n while true; do\n OPEN=$(bd ready 2>/dev/null | wc -l)\n [[ \"$OPEN\" -eq 0 ]] && break\n sleep 30\n done\nelse\n # Standard /swarm invocation (existing behavior)\n # Invoke /swarm with task creation for each issue in the wave\nfi\n```\n\nWhen `GC_POOL_AVAILABLE=false`, the existing `/swarm` path is used unchanged.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":1479,"content_sha256":"725ecbcfe52d5b452b579d9e3da13103b7c248b1ad4cd0f7fe78b37a47acabbd"},{"filename":"references/parallel-wave-isolation.md","content":"# Parallel-Wave Isolation (wave size ≥ 2)\n\n## Problem\n\nWhen `/crank` dispatches 2+ parallel workers in a shared clone, sibling workers can clobber each other's staged files. The proximate cause is `git checkout` mutating the shared working tree mid-task — worker A stages files, worker B runs `git checkout` to switch to its branch, worker A's stage is gone.\n\nObserved 2026-04-30 (soc-lrwk crank): 2 of 3 parallel workers lost staged work and recovered via stash + ephemeral worktrees, costing ~30% wall-time per affected worker.\n\n## Why three tiers, not just \"always use worktrees\"\n\nThe user already invested in worktree-sprawl prevention:\n- Commit `83bea6bd` enforces canonical-root worktree hygiene.\n- `scripts/check-worktree-disposition.sh` flags stray worktrees in CI.\n- `git worktree prune` cleans up stale ones.\n- AGENTS.md documents the policy.\n\nDefaulting to per-worker worktrees regresses that investment. The right answer is conditional escalation, gated on the actual signal (`scripts/preflight-swarm.sh`).\n\nCouncil brainstorm + judge verdicts: `.agents/council/2026-04-30-brainstorm-crank-parallel-wave.md`.\n\n## Tier 1 — Branch isolation prompt rule (every parallel wave ≥ 2)\n\nInject this rule verbatim at the top of every worker's `spawn_agent(message=...)` text, before the issue body:\n\n```\nWORKER GIT DISCIPLINE (parallel wave — read first):\n- Your first git op is: git checkout -b feat/\u003cepic-id>-\u003ctask-slug> origin/main\n- You MUST NOT run any of these on the shared working tree:\n - git checkout \u003cexisting-branch>\n - git switch\n - git stash pop\n - git reset --hard\n- Stay on your branch for the entire task. To inspect another branch's\n content, use: git show \u003cbranch>:\u003cpath> (read-only, no checkout).\n```\n\nThis is the load-bearing default. It prevents the proximate failure (sibling worker's `git checkout` mutates your staged files in the shared tree) at zero infrastructure cost. Workers' tooling (`gh pr merge`, `git stash pop` in recovery flows, etc.) is the typical violator — the rule must be in-context, not just in doctrine.\n\n## Tier 2 — Pre-flight + conditional escalation to ephemeral worktrees\n\nBefore spawning workers, run:\n\n```bash\nbash scripts/preflight-swarm.sh \"$WAVE_TASK_FILES\" || PREFLIGHT_RC=$?\n```\n\n- **Exit 0:** Tier 1 alone is sufficient. Spawn workers in the shared clone.\n- **Non-zero (conflict risk detected):** Escalate this wave to per-worker ephemeral worktrees per [worktree-per-worker.md](worktree-per-worker.md):\n\n ```bash\n for task in $WAVE_TASKS; do\n worktree=\"${REPO_ROOT}-worktrees/wave-${wave}-${task}\"\n git worktree add \"$worktree\" -b \"feat/\u003cepic>-${task}\" origin/main\n # Inject \"WORKING DIRECTORY: $worktree\" into the worker prompt\n done\n ```\n\n Workers in escalated mode operate in their own worktree. Orchestrator removes the worktree at wave-end after the worker's commit + push lands:\n\n ```bash\n for task in $WAVE_TASKS; do\n git worktree remove \"${REPO_ROOT}-worktrees/wave-${wave}-${task}\"\n done\n ```\n\nThe escalation criterion is **owned by `preflight-swarm.sh`**, not duplicated here. Tune heuristics there if needed.\n\n## Tier 3 — Wave-end disposition gate\n\nAfter every wave (Tier 1 OR Tier 2), run:\n\n```bash\nbash scripts/check-worktree-disposition.sh\n```\n\nThis catches stragglers — worktrees that should have been removed but weren't. **The script is a blocking gate**: it exits non-zero on *any* unexpected branch-attached worktree, dirty canonical-root status, or missing preserved ref. The orchestrator MUST treat a non-zero exit as a wave failure and surface the flagged worktrees in the wave summary before halting. There is no \"advisory\" or \">N stragglers\" threshold — zero tolerance.\n\n## Why this layering\n\n| Tier | Cost | Fires When | Solves |\n|---|---|---|---|\n| 1 | $0 (prompt only) | Every parallel wave ≥ 2 | Sibling-worker `git checkout` clobber (the proximate failure) |\n| 2 | One worktree per worker, ephemeral | `preflight-swarm.sh` flags overlap | Same-file collisions, generated-artifact races |\n| 3 | One script call | Every wave-end | Sprawl regression — leftover worktrees |\n\nReuses existing tooling: `scripts/preflight-swarm.sh`, `scripts/check-worktree-disposition.sh`, [worktree-per-worker.md](worktree-per-worker.md), `git worktree prune`. No new scripts.\n\n## See Also\n\n- [worktree-per-worker.md](worktree-per-worker.md) — when ephemeral per-worker worktrees ARE warranted (the \"USE/DON'T USE\" matrix Tier 2 routes through)\n- `.agents/learnings/2026-04-30-branch-isolation-for-multi-session-crank.md` — branch-isolation pattern that Tier 1 codifies\n- `.agents/council/2026-04-30-brainstorm-crank-parallel-wave.md` — full council judgment behind this design\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4709,"content_sha256":"f24bae90c4fe3b0e0c58d58be1a86077e0fac22f7b28bd2bf7f328647e17d088"},{"filename":"references/plan-mutations.md","content":"# Plan Mutation Audit Trail\n\n> Crank logs every plan mutation to `.agents/rpi/plan-mutations.jsonl` so post-mortem can assess plan drift.\n\n## JSONL Format\n\nEach line is a self-contained JSON object:\n\n```jsonl\n{\"timestamp\":\"2026-03-21T10:15:00Z\",\"wave\":3,\"task_id\":\"ag-123\",\"mutation_type\":\"task_added\",\"before\":null,\"after\":{\"subject\":\"Add rate limiting\",\"reason\":\"Security review gap\"}}\n{\"timestamp\":\"2026-03-21T10:20:00Z\",\"wave\":3,\"task_id\":\"ag-124\",\"mutation_type\":\"task_removed\",\"before\":{\"subject\":\"Migrate legacy tokens\",\"status\":\"pending\"},\"after\":null}\n{\"timestamp\":\"2026-03-21T11:00:00Z\",\"wave\":4,\"task_id\":\"ag-125\",\"mutation_type\":\"task_reordered\",\"before\":{\"wave\":5},\"after\":{\"wave\":3,\"reason\":\"Frontend needs docs earlier\"}}\n{\"timestamp\":\"2026-03-21T11:05:00Z\",\"wave\":4,\"task_id\":\"ag-123\",\"mutation_type\":\"scope_changed\",\"before\":{\"files\":[\"auth.go\"]},\"after\":{\"files\":[\"auth.go\",\"auth_test.go\"],\"reason\":\"Tests required per review\"}}\n{\"timestamp\":\"2026-03-21T11:10:00Z\",\"wave\":4,\"task_id\":\"ag-126\",\"mutation_type\":\"dependency_changed\",\"before\":{\"blocked_by\":[\"ag-120\"]},\"after\":{\"blocked_by\":[\"ag-120\",\"ag-121\"],\"reason\":\"Config dependency discovered\"}}\n```\n\n## Field Reference\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `timestamp` | ISO 8601 | yes | When the mutation occurred |\n| `wave` | integer | yes | Current wave number when mutation was logged |\n| `task_id` | string | yes | Issue/task ID affected |\n| `mutation_type` | enum | yes | One of the five mutation types below |\n| `before` | object/null | yes | State before mutation (null for additions) |\n| `after` | object/null | yes | State after mutation (null for removals) |\n\n## Mutation Types\n\n| Type | Trigger | Before | After |\n|------|---------|--------|-------|\n| `task_added` | New task inserted mid-epic (insert/split) | `null` | Task subject, reason, origin task if split |\n| `task_removed` | Task skipped or pruned | Task subject, status | `null` |\n| `task_reordered` | Wave assignment changed | Original wave | New wave, reason |\n| `scope_changed` | File manifest or acceptance criteria changed | Original files/criteria | Updated files/criteria, reason |\n| `dependency_changed` | Blocked-by list modified | Original dependencies | Updated dependencies, reason |\n\n## Mutation Budget\n\nCrank enforces budgets to prevent runaway plan drift:\n\n| Type | Limit | Rationale |\n|------|-------|-----------|\n| `task_added` | 5 per epic | Prevents scope creep |\n| `task_removed` | unlimited | Pruning is healthy |\n| `task_reordered` | 3 per epic | Excessive reordering = bad initial plan |\n| `scope_changed` | unlimited | Refinement is expected |\n| `dependency_changed` | unlimited | Discovery is expected |\n\nWhen `task_added` budget is exceeded, log a warning and suggest re-running `/plan`.\n\n## Integration Points\n\n### Crank (writer)\n\nCrank appends to the JSONL file at these points in the execution loop:\n\n1. **Epic start (Step 1a.2):** Initialize the file with a header comment (empty file).\n2. **Worker failure classified as DECOMPOSE:** Log `task_added` for each new sub-task.\n3. **Task skipped or pruned:** Log `task_removed`.\n4. **Cross-wave dependency discovered:** Log `task_reordered` and/or `dependency_changed`.\n5. **Task validation reveals new requirement:** Log `task_added` for the new task.\n6. **File manifest updated after exploration:** Log `scope_changed`.\n7. **Wave checkpoint (Step 5.7):** Include `mutations_this_wave` count in checkpoint JSON.\n\n### Post-mortem (reader)\n\nPost-mortem reads the JSONL file to assess plan quality:\n\n- **High mutation count** indicates the plan was underspecified\n- **Many task_added** indicates requirements were unclear\n- **Many task_reordered** indicates poor dependency analysis\n- **Mutations clustered in early waves** indicates insufficient research phase\n- **scope_changed on most tasks** indicates the plan lacked file-level specificity\n\nPost-mortem includes a mutation summary table in its report.\n\n### Wave Checkpoint Integration\n\nEach wave checkpoint (Step 5.7) includes mutation counts:\n\n```json\n{\n \"wave\": 3,\n \"mutations_this_wave\": 2,\n \"total_mutations\": 5,\n \"mutation_budget\": {\n \"task_added\": {\"used\": 2, \"limit\": 5},\n \"task_reordered\": {\"used\": 1, \"limit\": 3}\n }\n}\n```\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":4264,"content_sha256":"a41f2fd5016d968ca66dd1b3586bb0929ec7fb8b387a4ff431f31408215f2e59"},{"filename":"references/ralph-loop-contract.md","content":"# Ralph Loop Contract (Reverse-Engineered)\n\nThis contract captures the operational Ralph mechanics reverse-engineered from:\n- `https://github.com/ghuntley/how-to-ralph-wiggum`\n- `.tmp/how-to-ralph-wiggum/README.md`\n- `.tmp/how-to-ralph-wiggum/files/loop.sh`\n- `.tmp/how-to-ralph-wiggum/files/PROMPT_plan.md`\n- `.tmp/how-to-ralph-wiggum/files/PROMPT_build.md`\n\nUse this as the source-of-truth for Ralph alignment in AgentOps orchestration skills.\n\n## Core Contract\n\n1. Fresh context every iteration/wave.\n- Each execution unit starts clean; no carryover worker memory.\n\n2. Scheduler-heavy, worker-light.\n- The lead/orchestrator schedules and reconciles.\n- Workers perform one scoped unit of work.\n\n3. Disk-backed shared state.\n- Loop continuity comes from filesystem state, not accumulated chat context.\n- In classic Ralph: `IMPLEMENTATION_PLAN.md` and `AGENTS.md`.\n\n4. One-task atomicity.\n- Select one important task, execute, validate, persist state, then restart fresh.\n\n5. Backpressure before completion.\n- Build/tests/lint/gates must reject bad output before task completion/commit.\n\n6. Observe and tune outside the loop.\n- Humans (or lead agents) monitor outcomes and adjust prompts/constraints/contracts.\n\n## AgentOps Mapping\n\n| Ralph concept | AgentOps implementation |\n|---|---|\n| Fresh context per loop | New workers/teams per wave in `$swarm`; fresh phase context in `ao rpi phased` |\n| Main context as scheduler | Mayor/lead orchestration in `$swarm` and `$crank` |\n| One task per pass | One issue per worker assignment in swarm/crank waves |\n| Backpressure | `$vibe`, task validation hooks, tests/lint gates, push/pre-mortem gates |\n| Outer loop restart | Wave loop in `$crank`; phase loop in `ao rpi phased` |\n\n## Implementation Notes\n\n- Keep worker prompts concise and operational.\n- Keep state in files/issue trackers, not long conversational memory.\n- Prefer deterministic checks over subjective completion.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":1924,"content_sha256":"20999f4507ebb1bc22853d0b805064668328ce58bcf8b5c083e6817f39c83f11"},{"filename":"references/shared-task-notes.md","content":"# SHARED_TASK_NOTES Bridge Pattern\n\n> Persist context across iterations when workers spawn fresh (Ralph Wiggum pattern).\n\n## Problem\n\nEach crank wave spawns fresh workers with no memory of previous waves. Critical context gets lost:\n- \"Wave 1 tried approach X and it failed because of Y\"\n- \"The auth module has a quirk where Z must happen before W\"\n- \"Wave 2 discovered that file F needs special handling\"\n\nWorkers rediscover the same issues or make the same mistakes.\n\n## Solution: SHARED_TASK_NOTES.md\n\nA persistent file that the crank orchestrator maintains between waves. Workers READ it at start and the orchestrator APPENDS to it after each wave.\n\n### File Location\n```\n.agents/crank/SHARED_TASK_NOTES.md\n```\n\n### Format\n```markdown\n# Shared Task Notes — Epic \u003cepic-id>\n\n## Wave 1 (2026-03-21T10:00:00)\n- Auth middleware requires `ctx.WithTimeout` wrapping (discovered by worker #2)\n- `config.yaml` has a race condition when read concurrently — use sync.Once\n- Test fixtures in `testdata/` must be copied, not symlinked (CI rejects symlinks)\n\n## Wave 2 (2026-03-21T10:15:00)\n- Rate limiter uses token bucket, not sliding window — don't assume sliding\n- The `internal/store` package has unexported helpers that can be reused\n```\n\n### Orchestrator Responsibilities\n\n**Before each wave:**\n```bash\n# Read shared notes and include in every worker prompt\nif [ -f .agents/crank/SHARED_TASK_NOTES.md ]; then\n SHARED_NOTES=$(cat .agents/crank/SHARED_TASK_NOTES.md)\n # Include in worker prompt (spawn_agent description):\n # \"Context from prior waves:\\n${SHARED_NOTES}\"\nfi\n```\n\n**After each wave:**\n```bash\n# Append new discoveries from wave results\ncat >> .agents/crank/SHARED_TASK_NOTES.md \u003c\u003cEOF\n\n## Wave ${wave} ($(date -Iseconds))\n$(extract_discoveries_from_wave_results)\nEOF\n```\n\n### What to Capture\n\n| Category | Example | Source |\n|----------|---------|--------|\n| Failed approaches | \"Approach X failed because Y\" | Worker error output |\n| Codebase quirks | \"Module Z requires special handling\" | Worker discoveries |\n| Convention discoveries | \"Tests must follow pattern P\" | Worker observations |\n| Dependency notes | \"Task A must complete before B\" | Orchestrator analysis |\n| Fix patterns | \"When you see error E, apply fix F\" | Worker solutions |\n\n### What NOT to Capture\n\n- Full error logs (too verbose, pollutes context)\n- Implementation details (workers should read code directly)\n- Task status (tracked by beads or issue tracker)\n- Anything already in the issue description\n\n### Size Management\n\nCap at ~50 lines. When exceeding:\n1. Summarize older waves into a \"## Prior Waves Summary\" section\n2. Keep last 3 waves in full detail\n3. Preserve any entries marked with `[CRITICAL]` regardless of age\n\n### Integration with Worker Prompts\n\nInclude shared notes in the worker's prompt (via `spawn_agent` description), after the issue body:\n\n```\n# Worker prompt includes:\n# \u003cissue body>\n# ---\n# Context from prior waves (read before starting):\n# \u003cshared notes content>\n```\n\nWorkers should read shared notes before starting implementation and add their own discoveries to their task output for the orchestrator to harvest.\n\n## Anti-Patterns\n\n| Anti-Pattern | Why It Fails | Fix |\n|-------------|-------------|-----|\n| Workers write directly to SHARED_TASK_NOTES | Parallel writes corrupt file | Only orchestrator writes; workers report in task output |\n| Including full error logs | Context pollution, token waste | Summarize: \"Error E in file F, caused by C\" |\n| Not capping size | Old notes dominate context window | Summarize waves older than 3 |\n| Skipping for small epics | Even 2-wave epics benefit | Always maintain; overhead is minimal |\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3666,"content_sha256":"acf3cfb5ecb6ac4e3076b7bde1f21691813ca32aefd53a20c825c92ec908495a"},{"filename":"references/taskcreate-examples.md","content":"\n\n---\n\n\nUse when `--test-first` is set and issue is spec-eligible (`feature`/`bug`/`task`).\n\n```\n subject=\"SPEC: \u003cissue-title>\",\n description=\"Generate contract for beads issue \u003cissue-id>.\n\nDetails from beads:\n\u003cpaste issue details from bd show>\n\nYou are a spec writer. Generate a contract for this issue.\n\nFIRST: Explore the codebase to understand existing patterns, types, and interfaces\nrelevant to this issue. Use Glob and Read to examine the code.\n\nTHEN: Read the contract template at skills/crank/references/contract-template.md.\n\nGenerate a contract following the template. Include:\n- At least 3 invariants\n- At least 3 test cases mapped to invariants\n- Concrete types and interfaces from the actual codebase\n\nIf inputs are missing or the issue is underspecified, write BLOCKED with reason.\n\nOutput: .agents/specs/contract-\u003cissue-id>.md\n\n```validation\nfiles_exist:\n - .agents/specs/contract-\u003cissue-id>.md\ncontent_check:\n - file: .agents/specs/contract-\u003cissue-id>.md\n pattern: \"## Invariants\"\n - file: .agents/specs/contract-\u003cissue-id>.md\n pattern: \"## Test Cases\"\n```\n\nMark task complete when contract is written and validation passes.\",\n activeForm=\"Writing spec for \u003cissue-id>\"\n)\n```\n\n---\n\n\nUse when `--test-first` is set, SPEC WAVE is complete, and issue is spec-eligible.\n\n```\n subject=\"TEST: \u003cissue-title>\",\n description=\"Generate FAILING tests for beads issue \u003cissue-id>.\n\nDetails from beads:\n\u003cpaste issue details from bd show>\n\nYou are a test writer. Generate FAILING tests from the contract.\n\nRead ONLY the contract at .agents/specs/contract-\u003cissue-id>.md.\nYou may read codebase structure (imports, types, interfaces) but NOT existing\nimplementation details.\n\nGenerate tests that:\n- Cover ALL test cases from the contract's Test Cases table\n- Cover ALL invariants (at least one test per invariant)\n- All tests MUST FAIL when run (RED state)\n- Follow existing test patterns in the codebase\n\nDo NOT read or reference existing implementation code.\nDo NOT write implementation code.\n\nOutput: test files in the appropriate location for the project's test framework.\n\n```validation\nfiles_exist:\n - \u003ctest-file-path-1>\n - \u003ctest-file-path-2>\n```\n\n> **RED verification note:** The validation gate runs commands directly (no shell wrappers).\n> To confirm tests FAIL, the worker must run the test command manually and verify non-zero\n> exit before marking complete. Do NOT put negated commands in validation metadata — the\n> gate would treat test failure as a validation failure. Workers self-verify RED state.\n\nMark task complete when tests are written and ALL tests FAIL.\",\n activeForm=\"Writing tests for \u003cissue-id>\"\n)\n```\n\n---\n\n\nUse when `--test-first` is set, SPEC and TEST waves are complete, and issue is spec-eligible.\n\n```\n subject=\"\u003cissue-id>: \u003cissue-title>\",\n description=\"Implement beads issue \u003cissue-id> (GREEN mode).\n\nDetails from beads:\n\u003cpaste issue details from bd show>\n\n**GREEN Mode:** Failing tests exist. Make them pass. Do NOT modify test files.\n\nFailing tests are at:\n- \u003ctest-file-path-1>\n- \u003ctest-file-path-2>\n\nContract is at: .agents/specs/contract-\u003cissue-id>.md\n\nFollow GREEN Mode rules from $implement SKILL.md:\n1. Read failing tests and contract FIRST\n2. Write minimal implementation to pass tests\n3. Do NOT modify test files\n4. Do NOT add tests (already written)\n5. Validate by running test suite\n\nExecute using $implement \u003cissue-id>. Mark complete when all tests pass.\",\n activeForm=\"Implementing \u003cissue-id> (GREEN)\"\n)\n```\n\n---\n\n\nUse when `--test-first` is NOT set for implementation issues. `metadata.validation` is required and MUST include:\n- `tests`\n- At least one structural check: `files_exist` or `content_check`\n\n```\n subject=\"\u003cissue-id>: \u003cissue-title>\",\n description=\"Implement beads issue \u003cissue-id>.\n\nDetails from beads:\n\u003cpaste issue details from bd show>\n\nExecute using $implement \u003cissue-id>. Mark complete when done.\n\n```validation\ntests: \"\u003ctest-command>\"\nfiles_exist:\n - \u003cexpected-output-file-1>\ncontent_check:\n - file: \u003cexpected-output-file-1>\n pattern: \"\u003crequired-structure-pattern>\"\ncommand: \"\u003coptional-build-or-smoke-command>\"\n```\n\n> **Allowlist-safe commands:** Validation commands run via `run_restricted()` which only\n> permits: `go`, `pytest`, `npm`, `make`. No shell wrappers (`bash -c`), no compound\n> operators (`&&`, `||`), no pipes or redirects. One command per field.\n>\n> Examples by language:\n> - Go: `\"tests\": \"go test ./...\"`, `\"command\": \"go vet ./...\"`\n> - Python: `\"tests\": \"pytest tests/\"`\n> - Node: `\"tests\": \"npm test\"`\n> - Multi-step: `\"tests\": \"make test\"` (put compound logic in Makefile)\n\",\n activeForm=\"Implementing \u003cissue-id>\",\n metadata={\n \"issue_type\": \"feature\",\n \"files\": [\"\u003cexpected-modified-file-1>\", \"\u003cexpected-modified-file-2>\"],\n \"validation\": {\n \"tests\": \"\u003ctest-command>\",\n \"files_exist\": [\"\u003cexpected-output-file-1>\"],\n \"content_check\": [\n {\"file\": \"\u003cexpected-output-file-1>\", \"pattern\": \"\u003crequired-structure-pattern>\"}\n ],\n \"command\": \"\u003coptional-build-or-smoke-command>\"\n }\n }\n)\n```\n\n---\n\n\nUse for non-spec-eligible issues (`docs`/`chore`/`ci`). `tests` is optional for this category; keep structural or command/lint checks.\n\n```\n subject=\"\u003cissue-id>: \u003cissue-title>\",\n description=\"Implement beads issue \u003cissue-id> (`docs`/`chore`/`ci` path).\",\n activeForm=\"Implementing \u003cissue-id>\",\n metadata={\n \"issue_type\": \"docs\",\n \"files\": [\"\u003cexpected-modified-file-1>\"],\n \"validation\": {\n \"files_exist\": [\"\u003cexpected-output-file-1>\"],\n \"content_check\": {\n \"file\": \"\u003cexpected-output-file-1>\",\n \"pattern\": \"\u003crequired-doc-or-config-pattern>\"\n },\n \"command\": \"\u003coptional-smoke-command>\",\n \"lint\": \"\u003coptional-lint-command>\"\n }\n }\n)\n```\n\n> **Allowlist reminder:** `command` and `lint` fields are also subject to `run_restricted()`.\n> Use bare allowlisted binaries only: `go`, `pytest`, `npm`, `make`. Example:\n> `\"command\": \"make lint\"`, `\"lint\": \"npm run lint\"`.\n\n---\n\n## Notes\n\n- **Subject patterns:**\n - SPEC WAVE: `SPEC: \u003cissue-title>` (no issue ID)\n - TEST WAVE: `TEST: \u003cissue-title>` (no issue ID)\n - GREEN/IMPL: `\u003cissue-id>: \u003cissue-title>` (with issue ID)\n\n- **Validation blocks:**\n - Fenced with triple backticks and `validation` language tag\n - Always include for SPEC and TEST waves\n - For `feature`/`bug`/`task` IMPL tasks: required `tests` + structural checks\n - For `docs`/`chore`/`ci` IMPL tasks: `tests` optional (explicit exemption path)\n - Consumed by lead during wave validation\n - **Allowlist constraint:** `tests`, `command`, and `lint` fields execute via `run_restricted()` in `task-validation-gate.sh`. Only bare allowlisted binaries are permitted: `go`, `pytest`, `npm`, `make`. Shell wrappers (`bash -c`), compound operators (`&&`, `||`, `;`), pipes (`|`), and redirects (`>`, `\u003c`) are blocked. Use `make` targets for multi-step validation.\n\n- **activeForm:**\n - Keep concise (3-5 words)\n - Include issue ID for easy tracking\n\n- **Worker context:**\n - SPEC: codebase read access, contract template\n - TEST: contract only, codebase structure (not implementations)\n - GREEN: failing tests (immutable), contract, issue description\n - IMPL: full codebase access, issue description\n\n- **File manifests (`metadata.files`):**\n- **Issue typing (`metadata.issue_type`):**\n - Task validation uses this to decide when active constraints apply and whether test metadata is mandatory\n - Swarm uses manifests for pre-spawn conflict detection (overlapping files = serialize or isolate)\n - Workers receive the manifest in their prompt and must stay within it\n - Derive from issue description, plan, or codebase exploration during planning\n\n- **Category-based skipping:**\n - docs/chore/ci issues bypass SPEC and TEST waves\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":7747,"content_sha256":"46acb763e786fe856e5a413aefa395ded201b9a0cea8c75fa78cb9c2bc8008b3"},{"filename":"references/team-coordination.md","content":"# Team Coordination\n\n## Wave Execution via Swarm\n\n### Beads Mode\n\n1. **Get ready issues from current wave**\n\n```\n subject=\"\u003cissue-id>: \u003cissue-title>\",\n description=\"Implement beads issue \u003cissue-id>.\n\nDetails from beads:\n\u003cpaste issue details from bd show>\n\nExecute using $implement \u003cissue-id>. Mark complete when done.\",\n activeForm=\"Implementing \u003cissue-id>\"\n)\n```\n\n3. **Add dependencies if issues have beads blockedBy:**\n```\n```\n\n4. **Invoke swarm to execute the wave:**\n```\nTool: Skill\nParameters:\n skill: \"agentops:swarm\"\n```\n\n5. **After swarm completes, verify and close beads with evidence:**\n```bash\nCOMMIT_SHA=$(git rev-parse --short HEAD 2>/dev/null || echo \"unknown\")\nbd close \u003cissue-id> --reason \"crank-sync wave:${wave} commit:${COMMIT_SHA}\" 2>/dev/null\n```\n\n\n\n```\nTool: Skill\nParameters:\n skill: \"agentops:swarm\"\n```\n\n\n### Both Modes — Swarm Will:\n\n- Spawn workers with fresh context (Ralph pattern)\n\n## Verify and Sync to Beads (MANDATORY)\n\n> Swarm executes per-task validation (see `skills/shared/validation-contract.md`). Crank trusts swarm validation and focuses on beads sync.\n\n**For each issue reported complete by swarm:**\n\n1. **Verify swarm task completed:**\n ```\n ```\n If task is still pending/blocked, swarm validation failed — add to retry queue.\n\n2. **Sync to beads with evidence:**\n ```bash\n COMMIT_SHA=$(git rev-parse --short HEAD 2>/dev/null || echo \"unknown\")\n CHANGED_FILES=$(git diff --name-only HEAD~1 2>/dev/null | head -10 | tr '\\n' ' ' | sed 's/ $//')\n bd close \u003cissue-id> --reason \"commit:${COMMIT_SHA} files:[${CHANGED_FILES}]\" 2>/dev/null\n ```\n\n3. **On sync failure** (bd unavailable or error):\n - Log warning but do NOT block the wave\n - Track for manual sync after epic completes\n\n4. **Record ratchet progress (ao integration):**\n ```bash\n if command -v ao &>/dev/null; then\n ao ratchet record implement 2>/dev/null\n fi\n ```\n\n**Note:** Per-issue review is handled by swarm validation. Wave-level semantic review happens in the Wave Acceptance Check.\n\n## Check for More Work\n\nAfter completing a wave:\n\n### Beads Mode\n2. Check if new beads issues are now unblocked: `bd ready`\n4. If no more issues after 3 retry attempts, proceed to final validation\n\n2. If yes, loop back to wave execution\n3. If all completed, proceed to final validation\n\n### Both Modes\n- **Max retries:** If issues remain blocked after 3 checks, escalate: \"Epic blocked - cannot unblock remaining issues\"\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":2453,"content_sha256":"99c723f6edba38935a57dc410c52e9dc3ad6efa1f728e912d34490dbdd7a91f9"},{"filename":"references/test-first-mode.md","content":"# Test-First Mode (--test-first)\n\n> Reference for crank's `--test-first` flag. Covers SPEC WAVE, TEST WAVE, and RED Gate enforcement.\n\n## SPEC WAVE\n\n> **Purpose:** Generate contracts that ground implementation in verified requirements.\n\n**Skip this step if `--test-first` is NOT set or if no spec-eligible issues exist.**\n\nFor each **spec-eligible** issue (feature/bugfix/refactor):\n\n2. **Worker prompt:**\n ```\n You are a spec writer. Generate a contract for this issue.\n\n FIRST: Explore the codebase to understand existing patterns, types, and interfaces\n relevant to this issue. Use Glob and Read to examine the code.\n\n THEN: Read the contract template at:\n skills/crank/references/contract-template.md\n\n Generate a contract following the template. Include:\n - At least 3 invariants\n - At least 3 test cases mapped to invariants\n - Concrete types and interfaces from the actual codebase\n\n If inputs are missing or the issue is underspecified, write BLOCKED with reason.\n\n Output: .agents/specs/contract-\u003cissue-id>.md\n ```\n3. **Worker receives:** Issue description, plan boundaries, contract template, codebase access (read-only)\n4. **Validation:** files_exist + content_check for `## Invariants` AND `## Test Cases`\n5. **Lead commits** all specs after validation: `git add .agents/specs/ && git commit -m \"spec: contracts for \u003cissue-ids>\"`\n6. **Wave 1 consistency checklist (MANDATORY):** run `skills/crank/references/wave1-spec-consistency-checklist.md` across the full SPEC wave set before advancing to TEST WAVE.\n\n**Category-based skip:** Issues categorized as docs/chore/ci bypass SPEC and TEST waves entirely and proceed directly to standard implementation waves.\n\n### Wave 1 Consistency Gate\n\nRun the checklist once per SPEC wave:\n\n```bash\n# Mechanical gate: all contracts in this wave satisfy checklist criteria\n# (frontmatter completeness, invariant/test-case minimums, and consistency checks)\ncat skills/crank/references/wave1-spec-consistency-checklist.md\n```\n\nIf any checklist item fails:\n1. Re-run SPEC worker(s) for affected issue(s)\n2. Re-validate the full SPEC wave\n3. Do not start TEST WAVE until checklist passes\n\n### SPEC WAVE BLOCKED Recovery\n\nIf a spec worker writes `BLOCKED` instead of a contract:\n\n1. **Read the BLOCKED reason** from the worker output\n2. **Add context to the issue:**\n ```bash\n bd comments add \u003cissue-id> \"SPEC BLOCKED: \u003creason>. Retrying with additional context...\" 2>/dev/null\n ```\n3. **Retry once** with enriched prompt (include the BLOCKED reason + additional codebase context)\n4. **If still BLOCKED after 2 attempts**, escalate:\n ```bash\n bd update \u003cissue-id> --labels BLOCKER 2>/dev/null\n bd comments add \u003cissue-id> \"ESCALATED: Spec generation failed 2x. Reason: \u003creason>. Human review required.\" 2>/dev/null\n ```\n Remove the issue from spec-eligible list and continue with remaining issues. Do NOT block the entire wave.\n\n## TEST WAVE\n\n> **Purpose:** Generate failing tests from contracts. Tests must FAIL (RED confirmation).\n\n**Skip this step if `--test-first` is NOT set or if no spec-eligible issues exist.**\n\nFor each **spec-eligible** issue:\n\n2. **Worker prompt:**\n ```\n You are a test writer. Generate FAILING tests from the contract.\n\n Read ONLY the contract at .agents/specs/contract-\u003cissue-id>.md.\n You may read codebase structure (imports, types, interfaces) but NOT existing\n implementation details.\n\n Generate tests that:\n - Cover ALL test cases from the contract's Test Cases table\n - Cover ALL invariants (at least one test per invariant)\n - All tests MUST FAIL when run (RED state)\n - Follow existing test patterns in the codebase\n\n Do NOT read or reference existing implementation code.\n Do NOT write implementation code.\n\n Output: test files in the appropriate location for the project's test framework.\n ```\n3. **Worker receives:** contract-\u003cissue-id>.md + codebase structure (imports, types) but NOT existing implementations\n4. **Validation:** test files exist + RED confirmation (lead runs test suite, all new tests must fail)\n5. **RED Gate:** Lead runs the test suite. ALL new tests must FAIL:\n ```bash\n # Run tests — expect failures for new tests\n # If any new test PASSES, the test is not meaningful (validates existing behavior, not new)\n ```\n6. **Lead commits** test harness: `git add \u003ctest-files> && git commit -m \"test: failing tests for \u003cissue-ids> (RED)\"`\n\n## RED Gate Enforcement\n\nAfter TEST WAVE, the lead **must** verify RED state before proceeding:\n\n```bash\n# Run the test suite and capture results\nTEST_OUTPUT=$(\u003ctest-command> 2>&1) || true\nTEST_EXIT=$?\n\n# Parse for unexpected passes among new test files\nUNEXPECTED_PASSES=()\nfor test_file in $NEW_TEST_FILES; do\n # Check if tests in this file passed (framework-specific detection)\n if echo \"$TEST_OUTPUT\" | grep -q \"PASS.*$(basename $test_file)\"; then\n UNEXPECTED_PASSES+=(\"$test_file\")\n fi\ndone\n\nif [[ ${#UNEXPECTED_PASSES[@]} -gt 0 ]]; then\n echo \"RED GATE FAILED: ${#UNEXPECTED_PASSES[@]} test file(s) passed unexpectedly:\"\n printf ' - %s\\n' \"${UNEXPECTED_PASSES[@]}\"\nfi\n```\n\n**Decision tree for unexpected passes:**\n\n| Condition | Action |\n|-----------|--------|\n| All new tests FAIL | PASS — proceed to IMPL wave |\n| Some tests pass, some fail | Retry: re-generate passing tests with explicit \"must fail\" constraint |\n| All new tests PASS | BLOCKED — tests validate existing behavior, not new requirements. Escalate to human. |\n\n**On retry (max 2 attempts):**\n1. Add the unexpected-pass context to the worker prompt\n2. Re-spawn test writer with: \"These tests passed unexpectedly: \u003clist>. They must fail against current code. Rewrite them to test NEW behavior described in the contract.\"\n3. If still passing after 2 retries, mark issue as BLOCKER and skip to standard IMPL\n\n## Test Framework Detection\n\n> Spec workers use this heuristic when the issue doesn't specify a test framework. First match wins.\n\n**Detection priority (check in order, first match wins):**\n\n| Priority | File Present | Check | Framework | Test Command | Contract `framework:` |\n|----------|-------------|-------|-----------|-------------|----------------------|\n| 1 | `Cargo.toml` | file exists | Rust | `cargo test` | `rust` |\n| 2 | `go.mod` | file exists | Go | `go test ./...` | `go` |\n| 3 | `pyproject.toml` or `pytest.ini` | file exists | pytest | `pytest` | `python` |\n| 4 | `package.json` | `devDependencies.vitest` key exists | Vitest | `npx vitest run` | `typescript` |\n| 5 | `package.json` | `devDependencies.jest` key exists | Jest | `npx jest` | `typescript` |\n| 6 | `package.json` | file exists (no jest/vitest) | Node | `npm test` | `typescript` |\n| 7 | `*.test.sh` or `tests/*.sh` | glob match | Shell | `bash \u003ctest-file>` | `shell` |\n\n**For SPEC WAVE workers:** Detect the project framework using the heuristic above. Set `framework:` in the contract YAML frontmatter.\n\n**For TEST WAVE workers:** Read the `framework:` field from the contract to determine which test runner to use. Generate tests following the project's existing test patterns.\n\n**Fallback:** If no framework detected, spec worker writes `framework: unknown` and TEST WAVE skips that issue (falls back to standard IMPL without TDD).\n\n**Polyglot repos:** If multiple frameworks match (e.g., Go backend + Node tooling), use the framework that matches the issue's target files. If ambiguous, use the highest-priority match.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":7424,"content_sha256":"eadca0126bfb1d278b8d8524c9ead3202a77dfbe359fb60550295bd455fdde2f"},{"filename":"references/troubleshooting.md","content":"# Crank Troubleshooting\n\n| Problem | Cause | Solution |\n|---------|-------|----------|\n| \"No ready issues found for this epic\" | Epic has no child issues or all blocked | Run `$plan \u003cepic-id>` first to decompose epic into issues. Check dependencies with `bd show \u003cid>`. |\n| \"Global wave limit (50) reached\" | Excessive retries or circular dependencies | Review failed waves in `.agents/crank/wave-N-checkpoint.json`. Fix blocking issues manually or break circular deps with `bd dep remove`. |\n| Wave vibe gate fails repeatedly | Workers producing non-conforming code | Check `.agents/council/YYYY-MM-DD-vibe-wave-N.md` for specific findings. Add cross-cutting constraints to task metadata or refine worker prompts. |\n| Workers report completion but files missing | Permission errors or workers writing to wrong paths | Check `.agents/swarm/\u003cteam>/worker-N-output.json` for file paths. Verify write permissions with `ls -ld`. |\n| RED Gate passes (tests don't fail) | Test wave workers wrote implementation code | Re-run TEST WAVE with explicit \"no implementation code access\" in worker prompts. Tests must fail before GREEN waves start. |\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":1138,"content_sha256":"751a80640e8f4029a7ed85a900e22b0764570e6992a3465187cc08b494c48d5d"},{"filename":"references/uat-integration-wave.md","content":"# UAT Integration Wave Template\n\nCross-cutting validation wave added after all feature implementation waves complete.\n\n## When to Add\n\nAdd a UAT integration wave when:\n- An epic spans 3+ features that interact at runtime\n- Features share state (filesystem, config, CLI flags)\n- Pipeline flows cross feature boundaries (e.g., inject → mine → defrag)\n- The epic's pre-mortem identified cross-feature risk\n\n## Read-Only Wave Concept\n\nIntegration workers **validate but don't modify code**. They run scenarios that exercise multi-feature pipelines and report pass/fail. If a scenario fails, the lead creates a targeted fix issue for the next wave rather than having the integration worker attempt a fix.\n\nThis prevents integration workers from making conflicting edits to files owned by feature workers.\n\n## Pre-flight: Verify Binary Version\n\nBefore running any UAT scenario, confirm the `ao` binary in PATH matches the\nexpected release. Stale binaries are the #1 cause of false UAT failures.\n\n```bash\n# Run the pre-flight check (exits non-zero on mismatch):\nbash scripts/preflight-uat-binary.sh\n\n# Or inline:\nao version # confirm output matches the release under test\n```\n\nRecord the version string below. If it does not match the target version for\nthis UAT, **STOP** — rebuild or reinstall before proceeding:\n\n```bash\ncd cli && make build && cp bin/ao \"$(command -v ao)\"\n```\n\n- **Expected version:** _fill in before UAT starts_\n- **Observed version:** _paste `ao version` output_\n\nThis is **Scenario 0** in every UAT integration wave — it must pass before any\nfunctional scenarios execute.\n\n## Example Integration Scenarios\n\n### Pipeline Flow Test\n```bash\n# Lookup knowledge → mine signals → defrag cleanup\nao lookup --query \"research\" --no-cite\nao mine --sources git --since 1d --quiet\nao defrag --dedup --quiet\n```\n\n### Cross-Feature State Test\n```bash\n# Handoff creates artifact → lookup reads it\nao handoff --dry-run \"integration test\"\nao lookup --query \"integration test\" --no-cite\n```\n\n### CLI Flag Interaction Test\n```bash\n# Global flags (--json, --dry-run) work across all subcommands\nao defrag --dry-run --json\nao mine --quiet --sources git\nao lookup --query \"integration test\" --json --no-cite\n```\n\n## Worker Prompt Template\n\n```\nYou are a read-only integration validator. Do NOT modify any source files.\n\nRun each scenario below and report:\n- PASS: scenario completed without error\n- FAIL: scenario failed (include error message and stderr)\n- SKIP: scenario prerequisites not met (explain why)\n\nScenarios:\n1. [description]\n2. [description]\n\nAfter running all scenarios, write results to:\n .agents/crank/integration-wave-results.json\n\nFormat:\n{\n \"wave\": N,\n \"scenarios\": [\n {\"id\": 1, \"status\": \"PASS|FAIL|SKIP\", \"detail\": \"...\"}\n ],\n \"verdict\": \"PASS|FAIL\"\n}\n```\n\n## When to Skip\n\nSkip the integration wave when:\n- All issues are independent (no shared state or pipeline flows)\n- Epic is pure documentation or process changes\n- Epic has fewer than 3 issues\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":2990,"content_sha256":"4b17b7e184fe186bb068fb22c2effbed4d0297812a995b3db45d73bae7600a4e"},{"filename":"references/wave-patterns.md","content":"# Wave Patterns\n\n## The FIRE Loop\n\nCrank follows FIRE for each wave:\n\n|-------|-----------|--------------|\n| **CHECK** | Wave acceptance check (2 inline judges) → PASS/WARN/FAIL | Same |\n| **ESCALATE** | `bd comments add` + retry | Update task description + retry |\n\n**With `--test-first` flag, FIRE extends with two pre-implementation phases:**\n\n| Phase | Description |\n|-------|-------------|\n| **SPEC** | Generate contracts per issue → `.agents/specs/contract-\u003cid>.md` |\n| **TEST** | Generate failing tests from contracts → RED gate (all must fail) |\n\n## Parallel Wave Model\n\n### Beads Mode\n\n```\nWave 1: bd ready → [issue-1, issue-2, issue-3]\n ↓\n ↓\n $swarm → spawns 3 fresh-context agents\n ↓ ↓ ↓\n DONE DONE BLOCKED\n ↓\n (retry in next wave)\n ↓\n bd update --status closed for completed\n\nWave 2: bd ready → [issue-4, issue-3-retry]\n ↓\n ↓\n $swarm → spawns 2 fresh-context agents\n ↓\n bd update for completed\n\nFinal vibe on all changes → Epic DONE\n```\n\n\n```\n ↓\n $swarm → spawns 3 fresh-context agents\n ↓ ↓ ↓\n DONE DONE BLOCKED\n ↓\n (reset to pending, retry next wave)\n\n ↓\n $swarm → spawns 2 fresh-context agents\n ↓\n\nFinal vibe on all changes → All tasks DONE\n```\n\n\n## Spec-First Wave Model (--test-first)\n\nWhen `--test-first` is enabled, crank runs 4 wave types instead of 1:\n\n```\nSPEC WAVE (conditional on --test-first)\n Workers: 1 per spec-eligible issue\n Input: issue description + plan boundaries + codebase (read-only)\n Output: .agents/specs/contract-{issue-id}.md\n Gate: Lead validates completeness (all issues have contracts)\n ↓\nTEST WAVE (conditional on --test-first)\n Workers: 1 per spec-eligible issue\n Input: contract-{issue-id}.md + codebase types (NOT implementation code)\n Output: test files committed to repo\n Gate: RED confirmation — ALL new tests must FAIL\n ↓\nIMPL WAVE (standard, enhanced with GREEN mode)\n Workers: 1 per issue (full access)\n Input: failing tests + contract + issue description\n Output: implementation code\n Gate: GREEN confirmation — ALL tests must PASS + wave acceptance check\n ↓\n[Optional] REFACTOR WAVE\n Workers: 1 per changed file group\n Input: passing tests + implementation\n Output: diff-only cleanup\n Gate: All tests still PASS\n```\n\n### Category-Based Skip\n\nIssues categorized as docs, chore, or ci skip SPEC and TEST waves entirely:\n- **feature / bugfix / refactor** → full pipeline (SPEC → TEST → IMPL)\n- **docs / chore / ci** → standard implementation waves only\n\n### RED Confirmation Gate\n\nAfter TEST WAVE, the lead runs the test suite. ALL new tests must FAIL:\n- If a new test passes → the test validates existing behavior, not new requirements\n- Tests that pass are removed or flagged for rewrite\n- Only proceed to IMPL when all new tests are confirmed RED\n\n### RED Gate Failure Recovery\n\nWhen the RED gate detects unexpected test passes:\n\n1. **Identify cause:** Tests that pass against current code validate existing behavior, not new requirements from the contract\n2. **Retry:** Re-spawn test writer with the unexpected-pass list and \"must fail\" constraint (max 2 retries)\n3. **Escalate:** After 2 retries, mark the issue as BLOCKER and fall back to standard IMPL (no TDD for that issue)\n4. **Log:** Record RED gate failure in wave checkpoint for post-mortem analysis\n\n```bash\n# RED gate failure tracking\nif [[ ${#UNEXPECTED_PASSES[@]} -gt 0 ]]; then\n bd comments add \u003cissue-id> \"RED GATE: ${#UNEXPECTED_PASSES[@]} tests passed unexpectedly. Retry $RETRY_COUNT/2.\" 2>/dev/null\nfi\n```\n\n### GREEN Confirmation Gate\n\nAfter IMPL WAVE, the lead runs the test suite. ALL tests must PASS:\n- New tests (from TEST WAVE) must now pass\n- Existing tests must still pass (no regressions)\n- Standard wave acceptance check also applies\n\n### Contract Validation\n\nSPEC WAVE workers explore the codebase before writing contracts (not fully isolated). This prevents generic, ungrounded specs. Workers read:\n- Existing types, interfaces, and patterns\n- Related test files for style reference\n- Module structure and dependencies\n\nBut do NOT read implementation details of the specific feature being specified.\n\n## Wave Acceptance Check (MANDATORY)\n\n> **Principle:** Verify each wave meets acceptance criteria before advancing. Uses lightweight inline judges — no skill invocations, no context explosion.\n\n**After closing all beads in a wave, before advancing to the next wave:**\n\n**Note:** SPEC WAVE has its own validation (contract completeness check) and TEST WAVE has the RED gate. The Wave Acceptance Check applies only to IMPL and REFACTOR waves.\n\n1. **Compute wave diff** (WAVE_START_SHA recorded in Step 4):\n ```bash\n git diff $WAVE_START_SHA HEAD --name-only\n WAVE_DIFF=$(git diff $WAVE_START_SHA HEAD)\n ```\n\n2. **Load acceptance criteria** for all issues closed in this wave:\n ```bash\n # For each closed issue in the wave:\n bd show \u003cissue-id> # extract ACCEPTANCE CRITERIA section\n ```\n\n3. **Validate worker result evidence (FAIL-CLOSED):**\n\n For each issue closed in the wave, read `.agents/swarm/results/\u003cissue-id>.json` and validate against:\n `docs/contracts/swarm-worker-result.schema.json`.\n\n Required evidence policy for IMPL/REFACTOR acceptance:\n - `full_suite` evidence is mandatory for every completed implementation issue.\n - `red_green` evidence is mandatory for issues that ran through TEST WAVE (`--test-first` path).\n - Every check listed in `evidence.required_checks` must exist in `evidence.checks` and have `verdict: PASS`.\n\n Any one of the following sets the wave verdict to **FAIL** immediately:\n - missing result file\n - schema validation failure\n - missing required evidence\n - required evidence check with `FAIL` verdict\n\n4. **Spawn 2 inline judges** (Task agents, NOT skill invocations):\n\n ```\n # Judge 1: Spec compliance\n Parameters:\n subagent_type: \"general-purpose\"\n model: \"haiku\"\n description: \"Wave N spec-compliance check\"\n prompt: |\n Review this git diff against the acceptance criteria below.\n Does the implementation satisfy all acceptance criteria?\n Return: PASS, WARN (minor gaps), or FAIL (criteria not met) with brief justification.\n\n ## Acceptance Criteria\n \u003cacceptance criteria from step 2>\n\n ## Git Diff\n \u003cwave diff>\n\n # Judge 2: Error paths\n Parameters:\n subagent_type: \"general-purpose\"\n model: \"haiku\"\n description: \"Wave N error-paths check\"\n prompt: |\n Review this git diff for error handling and edge cases.\n Are error paths handled? Any unhandled exceptions or missing validations?\n Return: PASS, WARN (minor gaps), or FAIL (critical gaps) with brief justification.\n\n ## Git Diff\n \u003cwave diff>\n ```\n\n **Dispatch both judges in parallel** (single message, 2 Task tool calls).\n\n5. **Aggregate verdicts:**\n - If Step 3 fails evidence validation → **FAIL**\n - Else, both judges PASS → **PASS**\n - Else, any judge FAIL → **FAIL**\n - Otherwise → **WARN**\n\n6. **Gate on verdict:**\n\n | Verdict | Action |\n |---------|--------|\n | **PASS** | Record verdict in epic notes. Advance to next wave. |\n | **WARN** | Create fix beads as children of the epic (`bd create`). Execute fixes inline (small) or as wave N.5 via swarm. Re-run acceptance check. If PASS on re-check, advance. If still WARN after 2 attempts, treat as FAIL. WARN is only for non-critical review gaps after evidence is complete. |\n | **FAIL** | Record verdict in epic notes. Output `\u003cpromise>BLOCKED\u003c/promise>` and exit. Human review required. Includes missing mandatory evidence. |\n\n ```bash\n # Record verdict in epic notes\n bd update \u003cepic-id> --append-notes \"CRANK_ACCEPT: wave=$wave verdict=\u003cPASS|WARN|FAIL> at $(date -Iseconds)\"\n ```\n\n## CI-Policy Parity Gate\n\n> **Principle:** When a wave touches GitHub Actions workflows, the AGENTS.md CI table and the workflow's `summary.needs:` / `summary.if:` fail-set MUST stay in three-way sync. A drift means the docs lie about which jobs are blocking — exactly the failure mode that produced commit `c587b361` (manual fix codex-team applied AFTER soc-lmww1 added `factory-claim-ledger-strict (advisory)` to validate.yml without updating AGENTS.md or `summary.needs:`).\n\nThe crank orchestrator runs `scripts/validate-ci-policy-parity.sh` as a conditional acceptance gate inside Step 5.5.\n\n### Trigger detection\n\n```bash\n# Only trigger when wave actually touches a workflow YAML file.\n# CODEOWNERS-only or markdown-only changes do NOT trigger this gate.\nif git diff --name-only \"$WAVE_START_SHA\" HEAD -- | grep -qE '^\\.github/workflows/.*\\.ya?ml

$crank - Autonomous Epic Execution (Codex Native) Quick Ref: Execute every open issue in an epic via wave-based workers using , , , and . Output: closed issues + final validation. You must execute this workflow. Do not just describe it. Architecture Backend Rules 1. Prefer Codex session agents when is available. 2. Use for implementation agents and for discovery agents when the runtime exposes roles. 3. Use only for short steering or retry prompts. 4. Use for stalled or unnecessary agents. 5. Never depend on legacy CSV fan-out or host-task result polling. Use , , , and instead. Codex Lifecycl…

; then\n bash scripts/validate-ci-policy-parity.sh || exit 1\nfi\n```\n\nThe grep pattern is intentionally narrow:\n- `^\\.github/workflows/` anchors the trigger to the workflows directory (not `.github/CODEOWNERS`, not action templates elsewhere).\n- `\\.ya?ml crank — Skillopedia matches `.yml` and `.yaml` only.\n\n### Pre-fix state (simulating the c587b361 bug)\n\nA worker adds `factory-claim-ledger-strict` as a new advisory job in `validate.yml` but does NOT add it to `summary.needs:` and does NOT add a row to the `### CI Jobs and What They Check` table in AGENTS.md.\n\nThe orchestrator's gate fires:\n\n```\n$ bash scripts/validate-ci-policy-parity.sh\nCI_POLICY_PARITY: Job list drift detected (AGENTS table vs validate.yml summary.needs).\n--- AGENTS jobs\n+++ Workflow summary.needs jobs\n+factory-claim-ledger-strict\nAction: align AGENTS CI table entries or summary.needs job list.\nCI_POLICY_PARITY: FAILED (1 drift group(s) detected)\n$ echo $?\n1\n```\n\nWave verdict → **FAIL**.\n\n### Post-fix state\n\nAdd the job to `summary.needs:` and add a row to AGENTS.md (mark `(non-blocking)` when the job has `continue-on-error: true`). The gate then passes:\n\n```\n$ bash scripts/validate-ci-policy-parity.sh\nCI_POLICY_PARITY: PASS (47 jobs; 7 non-blocking)\n$ echo $?\n0\n```\n\n### Fix-it message format\n\nWhen the gate fails, surface a concise summary to the operator:\n\n```\n[wave-acceptance] CI-policy parity drift detected (validate-ci-policy-parity exit 1).\n Drift kind: \u003cJob list | Non-blocking policy | Blocking policy>\n Required edits:\n - \u003calign AGENTS.md ### CI Jobs and What They Check table>\n - \u003calign .github/workflows/validate.yml summary.needs and/or summary.if fail set>\n Re-run after fix:\n bash scripts/validate-ci-policy-parity.sh\n```\n\n### Why this gate exists\n\n- Commit `c587b361 ci(reconcile): wire factory-claim-ledger-strict into summary + AGENTS parity` is the manual fix that motivated this gate (soc-lmww1 drift). PR-F (this gate) is the formalization of `finding-2026-05-07-ci-parity-as-wave-acceptance`.\n- The validator (`scripts/validate-ci-policy-parity.sh`) is also wired into `scripts/pre-push-gate.sh`. Wave acceptance hits the same gate earlier — at wave-close time — so drift never escapes a wave.\n- Narrow trigger keeps the gate cheap and prevents false positives from CODEOWNERS, README, or non-workflow YAML changes.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":11357,"content_sha256":"ff197fc32910d261f4b4b287787c769897ef99f11e7efa0a02233835a3fba10b"},{"filename":"references/wave1-spec-consistency-checklist.md","content":"# Wave 1 Spec Consistency Checklist\n\nUse this checklist after SPEC WAVE and before TEST WAVE.\n\n## Required Per-Contract Checks\n\nFor every `contract-\u003cissue-id>.md` produced in the current SPEC wave:\n\n1. Frontmatter completeness:\n- [ ] `issue` is present and matches the issue being implemented.\n- [ ] `framework` is present (`go|python|typescript|rust|shell|unknown`).\n- [ ] `category` is present (`feature|bugfix|refactor|docs|chore|ci`).\n\n2. Structural completeness:\n- [ ] `## Invariants` exists with at least 3 numbered invariants.\n- [ ] `## Test Cases` exists with at least 3 rows.\n- [ ] Every test case has a non-empty `Validates Invariant` value.\n\n3. Implementability:\n- [ ] Inputs/outputs reference concrete codebase concepts (not placeholders).\n- [ ] Failure modes describe expected behavior, not only symptoms.\n\n## Wave-Level Consistency Checks\n\nAcross all contracts in the wave:\n\n1. Scope consistency:\n- [ ] No contract combines multiple issue IDs.\n- [ ] Each spec-eligible issue has exactly one contract.\n\n2. Terminology consistency:\n- [ ] Shared domain terms are used consistently between contracts.\n- [ ] Conflicting invariants are resolved before TEST WAVE starts.\n\n3. Test readiness:\n- [ ] Every contract includes at least one success-path and one error-path test case.\n- [ ] No contract is marked `BLOCKED` without a corresponding issue comment/escalation.\n\n## Gate Rule\n\nIf any required item fails:\n1. Re-run SPEC worker(s) for affected issue(s).\n2. Re-run this checklist across the full wave.\n3. Do NOT proceed to TEST WAVE until all required checks pass.\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":1573,"content_sha256":"bf8d5f72f67853b84c9c3347cdbb9cb9c98ecd933fabd766f3e75b8525d802c8"},{"filename":"references/worker-specs.md","content":"# Worker Specs\n\n> Per-worker model, tool, and prompt isolation for `/crank` and `/swarm`. Schema: `schemas/worker-spec.v1.schema.json`.\n\n## Why\n\nAnthropic's Managed Agents launch (May 2026) gives each specialist its own model, prompt, and tool set. AgentOps workers currently inherit the lead agent's tools — fine for most cases but limits the \"haiku-lead delegates to opus-implementer\" pattern that smaller managed-agent setups exploit.\n\nA worker spec is a small YAML/JSON file declaring which model, tool subset, and prompt template a worker uses. `/crank` reads the spec at spawn time, the worker inherits only the declared surface.\n\n## When to use a spec\n\n| Situation | Use a spec? |\n|---|---|\n| All workers in the wave do the same thing (e.g. all docs edits) | No — inherit lead defaults |\n| Different roles in the wave (spec-author, test-writer, impl) | Yes — one spec per role |\n| Mixing models (cheap lead, opus implementer) | Yes |\n| Restricting tool surface (worker that should only Read+Edit, not Bash) | Yes |\n| One-off task | Probably not — specs are for repeated patterns |\n\n## Schema\n\nSee `schemas/worker-spec.v1.schema.json`. Minimal example:\n\n```yaml\nversion: 1\nname: spec-author\nmodel: claude-sonnet-4-6\ntools: [Read, Write, Grep, Glob]\neffort: medium\ntimeout_seconds: 300\n```\n\nTool list of `[]` means no tools (read-only reasoning). Omitting `tools` means inherit lead's tool set. `model: inherit` uses the lead's model.\n\n## Storage convention\n\nReusable specs live at `skills/\u003cskill>/worker-specs/\u003crole>.yaml` (e.g. `skills/crank/worker-specs/spec-author.yaml`). One-off specs can be inlined in plan documents under a `worker_specs` section.\n\n## How `/crank` consumes specs\n\n```\nplan/\u003cepic>/issues.json:\n - id: epic-1\n worker_spec: skills/crank/worker-specs/spec-author.yaml\n metadata:\n validation: { ... }\n files: [...]\n```\n\nWhen crank dispatches `epic-1`, it:\n1. Loads `worker_spec`, validates against `schemas/worker-spec.v1.schema.json`\n2. Resolves `model: inherit` to the lead's model\n3. Builds the spawn payload using ONLY tools from `tools` (cross-checked against tool registry)\n4. Prepends the prompt file (if any) to the per-task instructions\n5. Spawns with `effort` mapped to the runtime's effort tier\n\n## Anti-patterns\n\n**Don't ladder model overrides in plan files.** If the same role is used by multiple issues, write one spec file and reference it from each. Inline specs are fine for one-offs but become a maintenance hazard at scale.\n\n**Don't use specs to gate access to dangerous tools.** Specs reduce surface for the worker's convenience and cost; security comes from the runtime's permission model, not the spec.\n\n**Don't mix `model: inherit` with `effort: high` if the lead is on Haiku.** The runtime will warn and fail the spawn. Pick a concrete model when overriding effort.\n\n## Validation\n\n`scripts/validate-worker-specs.sh` (to be added with the implementation) walks all `**/worker-specs/*.{yaml,json}` and validates against the schema. CI gate to be added at implementation time.\n\n## See also\n\n- Schema: [schemas/worker-spec.v1.schema.json](../../../schemas/worker-spec.v1.schema.json)\n- Spec issue: soc-yjzp.8\n- Pre-mortem fix 6: enum strictness on the `model` field (applied — see schema)\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":3262,"content_sha256":"1cf209481ef2b5a728e3c391d86127dd3aeb83526a2c85ce1d29d3cdceebe948"},{"filename":"references/worktree-per-worker.md","content":"# Worktree-Per-Worker Isolation Pattern\n\n## Problem\n\nParallel workers in a shared worktree collide when touching the same files, producing build breaks and merge conflicts. Even workers on different files can conflict on generated artifacts (go.sum, lock files).\n\n## When to Use\n\n- **Refactoring epics** — workers modify different functions in different files\n- **Multi-epic dispatch** — workers from different epics touch different packages\n- **Wave has 3+ workers** — higher collision probability\n\n## When NOT to Use\n\n- **Workers share files** — serialize instead (worktrees can't solve same-file conflicts)\n- **Single worker per wave** — no collision risk\n- **Pure doc changes** — no build artifacts to conflict on\n\n## Implementation\n\n### 1. Create worktrees before spawning\n\n```bash\nfor epic_id in $WAVE_EPICS; do\n git worktree add \"/tmp/swarm-${epic_id}\" -b \"swarm/${epic_id}\"\ndone\n```\n\n### 2. Inject path into worker prompt\n\n```\nWORKING DIRECTORY: /tmp/swarm-\u003cepic-id>\nAll file operations MUST use paths rooted at this directory.\n```\n\n### 3. Validate in worktree\n\nRun tests inside each worktree before merging:\n```bash\ncd /tmp/swarm-${epic_id} && go test ./... && go build ./...\n```\n\n### 4. Merge and cleanup\n\n```bash\ngit merge --no-ff \"swarm/${epic_id}\" -m \"chore: merge swarm/${epic_id}\"\ngit worktree remove \"/tmp/swarm-${epic_id}\"\ngit branch -d \"swarm/${epic_id}\"\n```\n\n## CC Estimation Heuristic\n\nEach extract-method refactoring saves approximately 3-5 CC points. For CC 30+, plan 6-10 extractions to reach CC \u003c15. See `skills/plan/references/complexity-estimation.md`.\n\n## Evidence\n\n- **ag-atu**: 3 parallel workers refactoring 3 Go files (rpi_parallel.go, dedup.go, markdown.go). Zero merge conflicts. All CC targets met.\n- **Swarm SKILL.md**: 4 parallel agents in shared worktree produced 1 build break and 1 algorithm duplication.\n\n## Related\n\n- `skills/swarm/SKILL.md` — Worktree Isolation section (execution detail)\n- `skills/swarm/references/local-mode.md` — Step 2b worktree setup\n- `skills/crank/references/wave-patterns.md` — FIRE loop and wave planning\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":2092,"content_sha256":"0dc6d8688455d6dfe167da4f803e0abd48c3dbb8d947b4e7d0e303721bc80b8e"},{"filename":"scripts/validate-wave-checkpoint.sh","content":"#!/usr/bin/env bash\nset -euo pipefail\n\nusage() {\n echo \"Usage: bash skills-codex/crank/scripts/validate-wave-checkpoint.sh \u003ccheckpoint-json> [repo-root]\" >&2\n}\n\nfail() {\n echo \"FAIL: $*\" >&2\n exit 1\n}\n\ncheckpoint=\"${1:-}\"\nrepo_root=\"${2:-}\"\n\nif [[ -z \"$checkpoint\" ]]; then\n usage\n exit 1\nfi\n\n[[ -f \"$checkpoint\" ]] || fail \"checkpoint not found: $checkpoint\"\ncommand -v jq >/dev/null 2>&1 || fail \"jq required\"\n\nif [[ -z \"$repo_root\" ]]; then\n repo_root=\"$(git rev-parse --show-toplevel 2>/dev/null || pwd)\"\nfi\n\nfor field in \\\n schema_version \\\n wave \\\n timestamp \\\n tasks_completed \\\n tasks_failed \\\n files_changed \\\n git_sha \\\n acceptance_verdict \\\n commit_strategy \\\n mutations_this_wave \\\n total_mutations \\\n mutation_budget; do\n jq -e --arg field \"$field\" 'has($field)' \"$checkpoint\" >/dev/null \\\n || fail \"checkpoint missing required field: $field\"\ndone\n\njq -e '\n (.schema_version == 1) and\n (.wave | type == \"number\" and . >= 1 and . == floor) and\n (.timestamp | type == \"string\" and length > 0) and\n (.tasks_completed | type == \"array\") and\n (.tasks_failed | type == \"array\") and\n (.files_changed | type == \"array\") and\n all(.tasks_completed[]; type == \"string\") and\n all(.tasks_failed[]; type == \"string\") and\n all(.files_changed[]; type == \"string\") and\n (.git_sha | type == \"string\" and length > 0) and\n (.acceptance_verdict as $v | [\"PASS\", \"WARN\", \"FAIL\"] | index($v) != null) and\n (.commit_strategy | type == \"string\" and length > 0) and\n (.mutations_this_wave | type == \"number\" and . >= 0 and . == floor) and\n (.total_mutations | type == \"number\" and . >= 0 and . == floor) and\n (.mutation_budget | type == \"object\")\n' \"$checkpoint\" >/dev/null || fail \"checkpoint has invalid field types or values\"\n\ntimestamp_epoch=\"$(jq -er '.timestamp | fromdateiso8601' \"$checkpoint\" 2>/dev/null)\" \\\n || fail \"timestamp is not valid ISO-8601 UTC: $(jq -r '.timestamp' \"$checkpoint\" 2>/dev/null || echo '\u003cunreadable>')\"\nnow_epoch=\"$(date -u +%s)\"\nif (( timestamp_epoch > now_epoch + 300 )); then\n fail \"timestamp is more than 5 minutes in the future: $(jq -r '.timestamp' \"$checkpoint\")\"\nfi\n\ngit_sha=\"$(jq -er '.git_sha' \"$checkpoint\")\"\ngit -C \"$repo_root\" cat-file -e \"${git_sha}^{commit}\" 2>/dev/null \\\n || fail \"git_sha does not resolve to a commit in $repo_root: $git_sha\"\n\necho \"PASS: crank wave checkpoint valid: $checkpoint\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":2375,"content_sha256":"53e7032f71347690c17a52b4dc8b86b8241ad9d7cdd67fc9c6d2c1899d6bed4a"},{"filename":"scripts/validate.sh","content":"#!/usr/bin/env bash\nset -euo pipefail\nSKILL_DIR=\"$(cd \"$(dirname \"$0\")/..\" && pwd)\"\nPASS=0; FAIL=0\n\ncheck() { if bash -c \"$2\"; then echo \"PASS: $1\"; PASS=$((PASS + 1)); else echo \"FAIL: $1\"; FAIL=$((FAIL + 1)); fi; }\n\ncheck \"SKILL.md exists\" \"[ -f '$SKILL_DIR/SKILL.md' ]\"\ncheck \"SKILL.md has YAML frontmatter\" \"head -1 '$SKILL_DIR/SKILL.md' | grep -q '^---

$crank - Autonomous Epic Execution (Codex Native) Quick Ref: Execute every open issue in an epic via wave-based workers using , , , and . Output: closed issues + final validation. You must execute this workflow. Do not just describe it. Architecture Backend Rules 1. Prefer Codex session agents when is available. 2. Use for implementation agents and for discovery agents when the runtime exposes roles. 3. Use only for short steering or retry prompts. 4. Use for stalled or unnecessary agents. 5. Never depend on legacy CSV fan-out or host-task result polling. Use , , , and instead. Codex Lifecycl…

\"\ncheck \"SKILL.md has name: crank\" \"grep -q '^name: crank' '$SKILL_DIR/SKILL.md'\"\ncheck \"references/ directory exists\" \"[ -d '$SKILL_DIR/references' ]\"\ncheck \"SKILL.md mentions wave concept\" \"grep -qi 'wave' '$SKILL_DIR/SKILL.md'\"\ncheck \"SKILL.md mentions worker concept\" \"grep -qi 'worker' '$SKILL_DIR/SKILL.md'\"\ncheck \"SKILL.md requires metadata.issue_type\" \"grep -q 'metadata.issue_type' '$SKILL_DIR/SKILL.md'\"\ncheck \"Lead-only commit pattern documented\" \"grep -rqi 'lead.*commit\\|lead-only' '$SKILL_DIR/'\"\ncheck \"FIRE loop documented\" \"grep -q 'FIRE' '$SKILL_DIR/SKILL.md'\"\ncheck \"wave checkpoint validator exists\" \"[ -x '$SKILL_DIR/scripts/validate-wave-checkpoint.sh' ]\"\ncheck \"SKILL.md runs wave checkpoint validator\" \"grep -q 'validate-wave-checkpoint.sh' '$SKILL_DIR/SKILL.md'\"\ncheck \"No phantom bd cook refs\" \"! grep -q 'bd cook' '$SKILL_DIR/SKILL.md'\"\ncheck \"No phantom gt convoy refs\" \"! grep -q 'gt convoy' '$SKILL_DIR/SKILL.md'\"\n\necho \"\"; echo \"Results: $PASS passed, $FAIL failed\"\n[ $FAIL -eq 0 ] && exit 0 || exit 1\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":1391,"content_sha256":"f51bd4b5146fd87ff7039baeabed2887819d4d2578aa4d993d2da7bb9522cc2b"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"$crank - Autonomous Epic Execution (Codex Native)","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Quick Ref:","type":"text","marks":[{"type":"strong"}]},{"text":" Execute every open issue in an epic via wave-based workers using ","type":"text"},{"text":"spawn_agent","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"wait_agent","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"send_input","type":"text","marks":[{"type":"code_inline"}]},{"text":", and ","type":"text"},{"text":"close_agent","type":"text","marks":[{"type":"code_inline"}]},{"text":". Output: closed issues + final validation.","type":"text"}]}]},{"type":"paragraph","content":[{"text":"You must execute this workflow. Do not just describe it.","type":"text","marks":[{"type":"strong"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Architecture","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"text"},"content":[{"text":"Crank (lead agent)\n |\n +-> bd ready (current wave)\n |\n +-> Build a wave task packet\n |\n +-> spawn_agent per issue (worker or explorer role)\n |\n +-> wait_agent for all worker ids\n |\n +-> Validate results + bd update\n |\n +-> Loop until epic DONE","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Backend Rules","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Prefer Codex session agents when ","type":"text"},{"text":"spawn_agent","type":"text","marks":[{"type":"code_inline"}]},{"text":" is available.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"agent_type=worker","type":"text","marks":[{"type":"code_inline"}]},{"text":" for implementation agents and ","type":"text"},{"text":"agent_type=explorer","type":"text","marks":[{"type":"code_inline"}]},{"text":" for discovery agents when the runtime exposes roles.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"send_input","type":"text","marks":[{"type":"code_inline"}]},{"text":" only for short steering or retry prompts.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"close_agent","type":"text","marks":[{"type":"code_inline"}]},{"text":" for stalled or unnecessary agents.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Never depend on legacy CSV fan-out or host-task result polling. Use ","type":"text"},{"text":"spawn_agent","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"wait_agent","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"send_input","type":"text","marks":[{"type":"code_inline"}]},{"text":", and ","type":"text"},{"text":"close_agent","type":"text","marks":[{"type":"code_inline"}]},{"text":" instead.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Codex Lifecycle Guard","type":"text"}]},{"type":"paragraph","content":[{"text":"When this skill runs in Codex hookless mode (","type":"text"},{"text":"CODEX_THREAD_ID","type":"text","marks":[{"type":"code_inline"}]},{"text":" is set or ","type":"text"},{"text":"CODEX_INTERNAL_ORIGINATOR_OVERRIDE","type":"text","marks":[{"type":"code_inline"}]},{"text":" is ","type":"text"},{"text":"Codex Desktop","type":"text","marks":[{"type":"code_inline"}]},{"text":"), ensure startup context before the first wave:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"ao codex ensure-start 2>/dev/null || true","type":"text"}]},{"type":"paragraph","content":[{"text":"ao codex ensure-start","type":"text","marks":[{"type":"code_inline"}]},{"text":" is the single startup guard for Codex skills. It records startup once per thread and skips duplicate startup automatically. Leave ","type":"text"},{"text":"ao codex ensure-stop","type":"text","marks":[{"type":"code_inline"}]},{"text":" to closeout skills after the implementation wave ends.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Flags","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Flag","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Default","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Description","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--test-first","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"off","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"SPEC -> TEST -> IMPL wave sequence. Workers classify tests by pyramid level (L0-L3) per the test pyramid standard (","type":"text"},{"text":"test-pyramid.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" in the standards skill). When ","type":"text"},{"text":"$plan","type":"text","marks":[{"type":"code_inline"}]},{"text":" includes ","type":"text"},{"text":"test_levels","type":"text","marks":[{"type":"code_inline"}]},{"text":" metadata, carry it into ","type":"text"},{"text":"metadata.validation.test_levels","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Global Limits","type":"text"}]},{"type":"paragraph","content":[{"text":"MAX_EPIC_WAVES = 50","type":"text","marks":[{"type":"strong"}]},{"text":" (hard limit). Typical epics use 5-10 waves.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Completion Enforcement (Sisyphus Rule)","type":"text"}]},{"type":"paragraph","content":[{"text":"After each wave, output one of:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\u003cpromise>DONE\u003c/promise>","type":"text","marks":[{"type":"code_inline"}]},{"text":" - epic complete, all issues closed","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\u003cpromise>BLOCKED\u003c/promise>","type":"text","marks":[{"type":"code_inline"}]},{"text":" - cannot proceed, with reason","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\u003cpromise>PARTIAL\u003c/promise>","type":"text","marks":[{"type":"code_inline"}]},{"text":" - incomplete, with remaining items","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Never claim completion without the marker.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Node Repair Operator","type":"text"}]},{"type":"paragraph","content":[{"text":"When a task fails during wave execution, classify as ","type":"text"},{"text":"RETRY","type":"text","marks":[{"type":"strong"}]},{"text":" (transient — re-add with adjustment, max 2), ","type":"text"},{"text":"DECOMPOSE","type":"text","marks":[{"type":"strong"}]},{"text":" (too complex — split into sub-issues, terminal), or ","type":"text"},{"text":"PRUNE","type":"text","marks":[{"type":"strong"}]},{"text":" (blocked — escalate immediately). Budget: 2 per task.","type":"text"}]},{"type":"paragraph","content":[{"text":"Mutation logging on failure:","type":"text","marks":[{"type":"strong"}]},{"text":" DECOMPOSE logs ","type":"text"},{"text":"task_removed","type":"text","marks":[{"type":"code_inline"}]},{"text":" + ","type":"text"},{"text":"task_added","type":"text","marks":[{"type":"code_inline"}]},{"text":" per sub-task. PRUNE logs ","type":"text"},{"text":"task_removed","type":"text","marks":[{"type":"code_inline"}]},{"text":". RETRY logs nothing (task identity unchanged).","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Execution Steps","type":"text"}]},{"type":"paragraph","content":[{"text":"Given ","type":"text"},{"text":"$crank [epic-id | .agents/rpi/execution-packet.json | plan-file.md | \"description\"]","type":"text","marks":[{"type":"code_inline"}]},{"text":":","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 0: Load Knowledge Context","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"if command -v ao &>/dev/null; then\n ao lookup --query \"\u003cepic-title>\" --limit 5 2>/dev/null || true\n ao ratchet status 2>/dev/null || true\nfi","type":"text"}]},{"type":"paragraph","content":[{"text":"Apply retrieved knowledge:","type":"text","marks":[{"type":"strong"}]},{"text":" If learnings are returned, check each for applicability to this epic. For applicable learnings, treat as implementation constraints and cite by filename. Record citations with the correct type: ","type":"text"},{"text":"ao metrics cite \"\u003cpath>\" --type applied","type":"text","marks":[{"type":"code_inline"}]},{"text":" when the learning influenced a decision, or ","type":"text"},{"text":"--type retrieved","type":"text","marks":[{"type":"code_inline"}]},{"text":" when loaded but not referenced.","type":"text"}]},{"type":"paragraph","content":[{"text":"Section evidence:","type":"text","marks":[{"type":"strong"}]},{"text":" When lookup results include ","type":"text"},{"text":"section_heading","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"matched_snippet","type":"text","marks":[{"type":"code_inline"}]},{"text":", or ","type":"text"},{"text":"match_confidence","type":"text","marks":[{"type":"code_inline"}]},{"text":" fields, prefer the matched section over the whole file — it pinpoints the relevant portion. Higher ","type":"text"},{"text":"match_confidence","type":"text","marks":[{"type":"code_inline"}]},{"text":" (>0.7) means the section is a strong match; lower values (\u003c0.4) are weaker signals. Use the ","type":"text"},{"text":"matched_snippet","type":"text","marks":[{"type":"code_inline"}]},{"text":" as the primary context rather than reading the full file.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 0.5: Detect Tracking Mode","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"if bd ready --json >/dev/null 2>&1 && bd list --type epic --status open --json >/dev/null 2>&1; then\n TRACKING_MODE=\"beads\"\nelse\n TRACKING_MODE=\"tasklist\"\nfi","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 0.6: Initialize Shared Task Notes","type":"text"}]},{"type":"paragraph","content":[{"text":"Create the shared notes file for cross-wave context persistence. See ","type":"text"},{"text":"references/shared-task-notes.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for the full pattern.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"mkdir -p .agents/crank\ncat > .agents/crank/SHARED_TASK_NOTES.md \u003c\u003cEOF\n# Shared Task Notes — Epic ${EPIC_ID:-unknown}\n\n> Cross-wave context for workers. Read before starting. Report discoveries in task output.\n> Maintained by the crank orchestrator — workers do NOT write to this file directly.\n\nEOF","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 0.7: Initialize Plan Mutation Audit Trail","type":"text"}]},{"type":"paragraph","content":[{"text":"Create the JSONL file that tracks every plan mutation during execution. See ","type":"text"},{"text":"references/plan-mutations.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for the full schema and mutation budget.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"mkdir -p .agents/rpi\n: > .agents/rpi/plan-mutations.jsonl\n\n# Budget counters\nMUTATION_TASK_ADDED=0\nMUTATION_TASK_ADDED_LIMIT=5\nMUTATION_TASK_REORDERED=0\nMUTATION_TASK_REORDERED_LIMIT=3","type":"text"}]},{"type":"paragraph","content":[{"text":"Helper function:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"log_plan_mutation() {\n local mutation_type=\"$1\" task_id=\"$2\" before=\"$3\" after=\"$4\"\n local ts\n ts=$(date -Iseconds)\n\n if [[ \"$mutation_type\" == \"task_added\" ]]; then\n MUTATION_TASK_ADDED=$((MUTATION_TASK_ADDED + 1))\n if [[ $MUTATION_TASK_ADDED -gt $MUTATION_TASK_ADDED_LIMIT ]]; then\n echo \"WARN: task_added budget exceeded ($MUTATION_TASK_ADDED/$MUTATION_TASK_ADDED_LIMIT). Consider re-running $plan.\"\n fi\n elif [[ \"$mutation_type\" == \"task_reordered\" ]]; then\n MUTATION_TASK_REORDERED=$((MUTATION_TASK_REORDERED + 1))\n if [[ $MUTATION_TASK_REORDERED -gt $MUTATION_TASK_REORDERED_LIMIT ]]; then\n echo \"WARN: task_reordered budget exceeded ($MUTATION_TASK_REORDERED/$MUTATION_TASK_REORDERED_LIMIT).\"\n fi\n fi\n\n echo \"{\\\"timestamp\\\":\\\"$ts\\\",\\\"wave\\\":$wave,\\\"task_id\\\":\\\"$task_id\\\",\\\"mutation_type\\\":\\\"$mutation_type\\\",\\\"before\\\":$before,\\\"after\\\":$after}\" \\\n >> .agents/rpi/plan-mutations.jsonl\n}","type":"text"}]},{"type":"paragraph","content":[{"text":"Mutation types:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"task_added","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"task_removed","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"task_reordered","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"scope_changed","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"dependency_changed","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 1: Identify the Execution Target","type":"text"}]},{"type":"paragraph","content":[{"text":"Beads mode:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If epic ID provided: use it directly","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If no epic ID: ","type":"text"},{"text":"bd list --type epic --status open 2>/dev/null | head -5","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"paragraph","content":[{"text":"Execution-packet/file mode:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If the input is ","type":"text"},{"text":".agents/rpi/execution-packet.json","type":"text","marks":[{"type":"code_inline"}]},{"text":", read ","type":"text"},{"text":"objective","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"epic_id","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"tracker_mode","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"done_criteria","type":"text","marks":[{"type":"code_inline"}]},{"text":", and ","type":"text"},{"text":"validation_commands","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If ","type":"text"},{"text":"epic_id","type":"text","marks":[{"type":"code_inline"}]},{"text":" exists inside the execution packet, keep that epic as the execution spine","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If ","type":"text"},{"text":"epic_id","type":"text","marks":[{"type":"code_inline"}]},{"text":" is absent, keep the packet ","type":"text"},{"text":"objective","type":"text","marks":[{"type":"code_inline"}]},{"text":" as the execution spine and continue in file-backed mode instead of inventing an epic ID","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"For other plan files, read the plan file and extract tasks","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 1.5: Branch Isolation Gate","type":"text"}]},{"type":"paragraph","content":[{"text":"Before wave-1 commit, refuse to crank on ","type":"text"},{"text":"main","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"master","type":"text","marks":[{"type":"code_inline"}]},{"text":". Cut ","type":"text"},{"text":"crank/\u003cepic-id>","type":"text","marks":[{"type":"code_inline"}]},{"text":" to prevent parallel-session reset clobbers. See ","type":"text"},{"text":"references/branch-isolation.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/branch-isolation.md","title":null}}]},{"text":" for the gate script and override flag.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 2: Load Execution Details","type":"text"}]},{"type":"paragraph","content":[{"text":"Beads mode:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"bd show \u003cepic-id> 2>/dev/null","type":"text"}]},{"type":"paragraph","content":[{"text":"Execution-packet/file mode:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Read the packet or plan file into local state for the current objective","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Preserve the same objective across retries; do not narrow to one slice from ","type":"text"},{"text":"bd ready","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 3: List Ready Work for the Current Wave","type":"text"}]},{"type":"paragraph","content":[{"text":"Beads mode:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"bd ready 2>/dev/null","type":"text"}]},{"type":"paragraph","content":[{"text":"bd ready","type":"text","marks":[{"type":"code_inline"}]},{"text":" returns all unblocked issues - these can run in parallel.","type":"text"}]},{"type":"paragraph","content":[{"text":"Execution-packet/file mode:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Read remaining tasks from ","type":"text"},{"text":".agents/rpi/execution-packet.json","type":"text","marks":[{"type":"code_inline"}]},{"text":" or the plan file","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Execute against the packet objective until the plan-backed work is done, blocked, or the retry budget is exhausted","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 3a: Pre-flight Checks","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Verify there are ready issues. Empty list is an error unless the epic is already complete.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If 3+ issues are ready, check ","type":"text"},{"text":".agents/council/","type":"text","marks":[{"type":"code_inline"}]},{"text":" for pre-mortem evidence.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If tracking mode is ","type":"text"},{"text":"beads","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"scripts/bd-audit.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" exists, run the backlog audit before spawning workers.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If bd-audit flags backlog hygiene issues, stop and clean them up before continuing. Use ","type":"text"},{"text":"--skip-audit","type":"text","marks":[{"type":"code_inline"}]},{"text":" only when you intentionally want to bypass that gate.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"For every string being modified, grep the codebase for stale cross-references.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 3b: Language Standards Injection","type":"text"}]},{"type":"paragraph","content":[{"text":"Detect project language (","type":"text"},{"text":"go.mod","type":"text","marks":[{"type":"code_inline"}]},{"text":" -> Go, ","type":"text"},{"text":"pyproject.toml","type":"text","marks":[{"type":"code_inline"}]},{"text":" -> Python, etc.) and read applicable standards from ","type":"text"},{"text":"$standards","type":"text","marks":[{"type":"code_inline"}]},{"text":". Include a Testing section in worker prompts.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 4: Execute the Wave with Codex Session Agents","type":"text"}]},{"type":"paragraph","content":[{"text":"Crank follows the FIRE loop for each wave:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"FIND:","type":"text","marks":[{"type":"strong"}]},{"text":" locate the next ready set","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"IGNITE:","type":"text","marks":[{"type":"strong"}]},{"text":" spawn workers","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"REAP:","type":"text","marks":[{"type":"strong"}]},{"text":" wait, validate, and merge results","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"ESCALATE:","type":"text","marks":[{"type":"strong"}]},{"text":" retry or block when needed","type":"text"}]}]}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"4a: Load Shared Task Notes","type":"text"}]},{"type":"paragraph","content":[{"text":"Read cross-wave context to include in worker prompts:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"SHARED_NOTES=\"\"\nif [ -f .agents/crank/SHARED_TASK_NOTES.md ]; then\n SHARED_NOTES=$(cat .agents/crank/SHARED_TASK_NOTES.md)\nfi","type":"text"}]},{"type":"paragraph","content":[{"text":"If ","type":"text"},{"text":"SHARED_NOTES","type":"text","marks":[{"type":"code_inline"}]},{"text":" exceeds ~50 lines, summarize older waves (keep last 3 in full detail, preserve ","type":"text"},{"text":"[CRITICAL]","type":"text","marks":[{"type":"code_inline"}]},{"text":" entries).","type":"text"}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"4b: Build a Wave Task Packet","type":"text"}]},{"type":"paragraph","content":[{"text":"Create one packet per ready issue. Do not use CSV fan-out.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"mkdir -p .agents/crank\ncat > \".agents/crank/wave-${wave}-tasks.json\" \u003c\u003c EOF\n{\n \"wave\": $wave,\n \"epic_id\": \"$EPIC_ID\",\n \"tasks\": [\n {\n \"issue_id\": \"bd-123\",\n \"subject\": \"Short issue summary\",\n \"description\": \"Issue details and acceptance criteria\",\n \"files\": [\"path/to/file.go\"],\n \"validation_cmd\": \"go test ./...\",\n \"metadata\": {\n \"issue_type\": \"feature\"\n }\n }\n ]\n}\nEOF","type":"text"}]},{"type":"paragraph","content":[{"text":"Each task packet must include ","type":"text"},{"text":"metadata.issue_type","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"4c: Pre-spawn File Conflict Check","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"text"},"content":[{"text":"wave_tasks = [tasks from packet]\nall_files = {}\nfor task in wave_tasks:\n for f in task.files:\n if f in all_files:\n CONFLICT -> serialize into sub-waves\n all_files[f] = task.id","type":"text"}]},{"type":"paragraph","content":[{"text":"Display an ownership table before spawning workers. If conflicts exist, split into sub-waves and keep file ownership disjoint.","type":"text"}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"4c.1: Parallel-Wave Isolation (wave size ≥ 2)","type":"text"}]},{"type":"paragraph","content":[{"text":"For waves with 2+ workers, three tiers prevent sibling-worker clobber without re-introducing worktree sprawl. Read ","type":"text"},{"text":"references/parallel-wave-isolation.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/parallel-wave-isolation.md","title":null}}]},{"text":" for the full tier definitions, the worker prompt template, the ","type":"text"},{"text":"preflight-swarm.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" escalation criterion, and the ","type":"text"},{"text":"check-worktree-disposition.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" cleanup gate.","type":"text"}]},{"type":"paragraph","content":[{"text":"Tier 1 (always): inject the branch-isolation prompt rule (worker's first git op = ","type":"text"},{"text":"git checkout -b feat/\u003cepic>-\u003cslug> origin/main","type":"text","marks":[{"type":"code_inline"}]},{"text":"; never ","type":"text"},{"text":"git switch","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"stash pop","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"reset --hard","type":"text","marks":[{"type":"code_inline"}]},{"text":"). Tier 2 (escalate on ","type":"text"},{"text":"preflight-swarm.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" non-zero): ephemeral per-worker worktree. Tier 3 (wave-end): ","type":"text"},{"text":"scripts/check-worktree-disposition.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":" flags stragglers.","type":"text"}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"4d: Spawn Workers","type":"text"}]},{"type":"paragraph","content":[{"text":"Spawn one agent per issue. Prefer ","type":"text"},{"text":"worker","type":"text","marks":[{"type":"code_inline"}]},{"text":" roles for implementation and ","type":"text"},{"text":"explorer","type":"text","marks":[{"type":"code_inline"}]},{"text":" roles for file discovery when the runtime exposes ","type":"text"},{"text":"agent_type","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"text"},"content":[{"text":"spawn_agent(\n agent_type=\"worker\",\n message=\"You are worker-\u003cissue-id>.\n\nAssignment: \u003csubject>\n\n\u003cdescription>\n\n---\nContext from prior waves (read before starting):\n\u003cSHARED_NOTES content, or 'First wave — no prior context.' if empty>\n\n---\n\nFILE MANIFEST (files you are permitted to modify):\n\u003clist of files>\n\nRules:\n1. Stay within your assigned files\n2. Run validation: \u003cvalidation_cmd>\n3. Keep your response short\n4. Write any durable notes to .agents/crank/results/\u003cissue-id>.md or .agents/crank/results/\u003cissue-id>.json\n5. DISCOVERY REPORTING: If you discover codebase quirks, failed approaches,\n convention requirements, or dependency constraints, include a section in your\n output titled '## Discoveries' with one bullet per finding.\n\nUse the repo's current Codex primitives only.\"\n)","type":"text"}]},{"type":"paragraph","content":[{"text":"If a task is missing its file manifest, spawn a short-lived ","type":"text"},{"text":"explorer","type":"text","marks":[{"type":"code_inline"}]},{"text":" agent first:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"text"},"content":[{"text":"spawn_agent(\n agent_type=\"explorer\",\n message=\"You are explorer-\u003cissue-id>.\n\nTask: identify the files that must be created or modified for this issue.\nReturn a JSON array of paths only.\"\n)","type":"text"}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"4e: Wait for Workers","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"text"},"content":[{"text":"wait_agent(targets=[\"agent-id-1\", \"agent-id-2\"])","type":"text"}]},{"type":"paragraph","content":[{"text":"If a worker needs a short correction, use ","type":"text"},{"text":"send_input(target=..., message=...)","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"paragraph","content":[{"text":"If a worker stalls or is no longer needed, use ","type":"text"},{"text":"close_agent(target=...)","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 5: Verify and Sync","type":"text"}]},{"type":"paragraph","content":[{"text":"External Gate Enforcement:","type":"text","marks":[{"type":"strong"}]},{"text":" After each worker completes, the orchestrator (not the worker) runs the gate command. Workers must not declare their own completion. See ","type":"text"},{"text":"references/external-gate-protocol.md","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"paragraph","content":[{"text":"For each completed worker:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"PASS -> close the issue.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"FAIL -> log the failure, keep the issue open, and retry only if the issue is still within the retry budget.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"BLOCKED -> mark blocked with the reason and continue the wave.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Update beads with evidence:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"COMMIT_SHA=$(git rev-parse --short HEAD 2>/dev/null || echo \"unknown\")\nCHANGED_FILES=$(git diff --name-only HEAD~1 2>/dev/null | head -10 | tr '\\n' ' ' | sed 's/ $//')\nbd close \"$issue_id\" --reason \"commit:${COMMIT_SHA} files:[${CHANGED_FILES}]\" 2>/dev/null\nbd update \"$issue_id\" --status blocked --append-notes \"Wave $wave FAIL: $reason\" 2>/dev/null","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 5.5: Wave Acceptance Check","type":"text"}]},{"type":"paragraph","content":[{"text":"After all workers complete:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Compute ","type":"text"},{"text":"git diff","type":"text","marks":[{"type":"code_inline"}]},{"text":" for the wave.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Run project-level tests appropriate to the wave.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"If tests fail, identify which worker's changes broke things and requeue only that work.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CI-Policy Parity Gate (conditional).","type":"text","marks":[{"type":"strong"}]},{"text":" If the wave diff touches ","type":"text"},{"text":".github/workflows/*.yml","type":"text","marks":[{"type":"code_inline"}]},{"text":", run ","type":"text"},{"text":"bash scripts/validate-ci-policy-parity.sh","type":"text","marks":[{"type":"code_inline"}]},{"text":"; on non-zero exit treat the wave verdict as ","type":"text"},{"text":"FAIL","type":"text","marks":[{"type":"strong"}]},{"text":" and surface the drift report. Trigger pattern (narrow — workflow YAML only):","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"if git diff --name-only \"$WAVE_START_SHA\" HEAD -- | grep -qE '^\\.github/workflows/.*\\.ya?ml

$crank - Autonomous Epic Execution (Codex Native) Quick Ref: Execute every open issue in an epic via wave-based workers using , , , and . Output: closed issues + final validation. You must execute this workflow. Do not just describe it. Architecture Backend Rules 1. Prefer Codex session agents when is available. 2. Use for implementation agents and for discovery agents when the runtime exposes roles. 3. Use only for short steering or retry prompts. 4. Use for stalled or unnecessary agents. 5. Never depend on legacy CSV fan-out or host-task result polling. Use , , , and instead. Codex Lifecycl…

; then\n bash scripts/validate-ci-policy-parity.sh || exit 1\nfi","type":"text"}]},{"type":"paragraph","content":[{"text":"See ","type":"text"},{"text":"references/wave-patterns.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/wave-patterns.md","title":null}}]},{"text":" \"CI-Policy Parity Gate\" for the worked example and the soc-lmww1 / commit ","type":"text"},{"text":"c587b361","type":"text","marks":[{"type":"code_inline"}]},{"text":" motivation.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 5.7: Wave Checkpoint","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"FILES_CHANGED_JSON=\"${FILES_CHANGED_JSON:-$(git diff --name-only \"${WAVE_START_SHA:-HEAD~1}..HEAD\" | jq -R -s -c 'split(\"\\n\")[:-1]')}\"\nGIT_SHA=\"$(git rev-parse HEAD)\"\n\ncat > \".agents/crank/wave-${wave}-checkpoint.json\" \u003c\u003c EOF\n{\n \"schema_version\": 1,\n \"wave\": $wave,\n \"epic_id\": \"$EPIC_ID\",\n \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\n \"tasks_completed\": ${TASKS_COMPLETED_JSON:-[]},\n \"tasks_failed\": ${TASKS_FAILED_JSON:-[]},\n \"files_changed\": $FILES_CHANGED_JSON,\n \"git_sha\": \"$GIT_SHA\",\n \"acceptance_verdict\": \"${ACCEPTANCE_VERDICT:-WARN}\",\n \"commit_strategy\": \"${COMMIT_STRATEGY:-wave-batch}\",\n \"mutations_this_wave\": $(grep -c \"\\\"wave\\\":${wave}\" .agents/rpi/plan-mutations.jsonl 2>/dev/null || echo 0),\n \"total_mutations\": $(wc -l \u003c .agents/rpi/plan-mutations.jsonl 2>/dev/null | tr -d ' '),\n \"mutation_budget\": {\n \"task_added\": {\"used\": ${MUTATION_TASK_ADDED:-0}, \"limit\": 5},\n \"task_reordered\": {\"used\": ${MUTATION_TASK_REORDERED:-0}, \"limit\": 3}\n }\n}\nEOF\n\nbash skills-codex/crank/scripts/validate-wave-checkpoint.sh \".agents/crank/wave-${wave}-checkpoint.json\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Do not copy or consume the checkpoint downstream until validation passes. The validator fails closed when ","type":"text"},{"text":"git_sha","type":"text","marks":[{"type":"code_inline"}]},{"text":" does not resolve in the current repo, ","type":"text"},{"text":"timestamp","type":"text","marks":[{"type":"code_inline"}]},{"text":" is invalid or more than 5 minutes in the future, or required checkpoint fields are missing/malformed.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 5.8: Update Shared Task Notes","type":"text"}]},{"type":"paragraph","content":[{"text":"Harvest discoveries from completed workers and append to the shared notes file:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"WAVE_DISCOVERIES=\"\"\nfor result_file in .agents/crank/results/*; do\n if [ -f \"$result_file\" ]; then\n DISCOVERIES=$(sed -n '/^## Discoveries/,/^## /{ /^## Discoveries/d; /^## /d; p; }' \"$result_file\" 2>/dev/null)\n if [ -n \"$DISCOVERIES\" ]; then\n WAVE_DISCOVERIES=\"${WAVE_DISCOVERIES}${DISCOVERIES}\\n\"\n fi\n fi\ndone\n\nif [ -n \"$WAVE_DISCOVERIES\" ]; then\n cat >> .agents/crank/SHARED_TASK_NOTES.md \u003c\u003cEOF\n\n## Wave ${wave} ($(date -Iseconds))\n$(echo -e \"$WAVE_DISCOVERIES\")\nEOF\nfi","type":"text"}]},{"type":"paragraph","content":[{"text":"Capture:","type":"text","marks":[{"type":"strong"}]},{"text":" Failed approaches, codebase quirks, convention discoveries, dependency notes. ","type":"text"},{"text":"Skip:","type":"text","marks":[{"type":"strong"}]},{"text":" Full error logs, implementation details, task status.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 5.9: Log Plan Mutations","type":"text"}]},{"type":"paragraph","content":[{"text":"After processing wave results, log mutations for any plan changes. Call ","type":"text"},{"text":"log_plan_mutation","type":"text","marks":[{"type":"code_inline"}]},{"text":" for each:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"DECOMPOSE:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"task_removed","type":"text","marks":[{"type":"code_inline"}]},{"text":" for original, ","type":"text"},{"text":"task_added","type":"text","marks":[{"type":"code_inline"}]},{"text":" for each sub-task","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"PRUNE:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"task_removed","type":"text","marks":[{"type":"code_inline"}]},{"text":" with block reason","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Scope change:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"scope_changed","type":"text","marks":[{"type":"code_inline"}]},{"text":" when file manifest updated after exploration","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Dependency discovered:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"dependency_changed","type":"text","marks":[{"type":"code_inline"}]},{"text":" when blocked-by list modified","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Wave reassignment:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"task_reordered","type":"text","marks":[{"type":"code_inline"}]},{"text":" when task moves between waves","type":"text"}]}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Example: task decomposed into sub-tasks\nlog_plan_mutation \"task_removed\" \"$decomposed_id\" \\\n \"{\\\"subject\\\":\\\"$ORIGINAL_SUBJECT\\\",\\\"status\\\":\\\"decomposed\\\"}\" \"null\"\nlog_plan_mutation \"task_added\" \"$sub_id\" \"null\" \\\n \"{\\\"subject\\\":\\\"$SUB_SUBJECT\\\",\\\"reason\\\":\\\"Split from $decomposed_id\\\"}\"\n\n# Example: scope change after exploration\nlog_plan_mutation \"scope_changed\" \"$task_id\" \\\n \"{\\\"files\\\":$ORIGINAL_FILES}\" \\\n \"{\\\"files\\\":$UPDATED_FILES,\\\"reason\\\":\\\"$REASON\\\"}\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Mutations are append-only to ","type":"text"},{"text":".agents/rpi/plan-mutations.jsonl","type":"text","marks":[{"type":"code_inline"}]},{"text":". Read by ","type":"text"},{"text":"$post-mortem","type":"text","marks":[{"type":"code_inline"}]},{"text":" for drift analysis.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 6: Commit Wave Results","type":"text"}]},{"type":"paragraph","content":[{"text":"Lead-only commit","type":"text","marks":[{"type":"strong"}]},{"text":" - workers write files, lead validates and commits once per wave:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"for f in $WORKER_FILES_CHANGED; do\n git add -- \"$f\"\ndone\ngit commit -m \"feat(\u003cscope>): wave $wave - $COMPLETED_COUNT issues completed\"","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 7: Loop or Complete","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"wave=$((wave + 1))\n\nif [[ $wave -ge 50 ]]; then\n echo \"\u003cpromise>BLOCKED\u003c/promise>\"\n echo \"Global wave limit (50) reached.\"\n exit 1\nfi\n\nREMAINING=$(bd ready 2>/dev/null | wc -l)\nif [[ $REMAINING -eq 0 ]]; then\n ALL_CLOSED=$(bd children \"$EPIC_ID\" 2>/dev/null | grep -c \"CLOSED\" || echo 0)\n ALL_TOTAL=$(bd children \"$EPIC_ID\" 2>/dev/null | wc -l || echo 0)\n\n if [[ $ALL_CLOSED -eq $ALL_TOTAL ]]; then\n echo \"\u003cpromise>DONE\u003c/promise>\"\n else\n echo \"\u003cpromise>BLOCKED\u003c/promise>\"\n echo \"No ready issues but $((ALL_TOTAL - ALL_CLOSED)) issues remain unclosed.\"\n fi\nelse\n # Continue to next wave - return to Step 3\nfi","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 8: Final Validation","type":"text"}]},{"type":"paragraph","content":[{"text":"When the epic is DONE:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"$vibe validate the completed epic","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 8.5: Archive Shared Task Notes","type":"text"}]},{"type":"paragraph","content":[{"text":"Move the shared notes to an archive after epic completion:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"if [ -f .agents/crank/SHARED_TASK_NOTES.md ]; then\n mkdir -p .agents/crank/archives\n mv .agents/crank/SHARED_TASK_NOTES.md \\\n \".agents/crank/archives/SHARED_TASK_NOTES-${EPIC_ID:-unknown}-$(date +%Y%m%d-%H%M%S).md\"\nfi","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Retry Policy","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Max 2 retries per issue across all waves","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"On third failure: mark BLOCKED and continue with remaining issues","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Track retries with ","type":"text"},{"text":"bd comments add \"$issue_id\" \"retry $N: $reason\"","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Failure Recovery","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Scenario","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Action","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Worker timeout","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Mark BLOCKED, log reason, continue wave","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Test failure","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Identify breaking change, retry once","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"All workers fail","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003cpromise>BLOCKED\u003c/promise>","type":"text","marks":[{"type":"code_inline"}]},{"text":" with diagnostics","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"File conflict detected","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Split into sub-waves, re-run","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Reference Documents","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/de-sloppify.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/de-sloppify.md","title":null}}]},{"text":" - cleanup pass after implementation waves","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/parallel-wave-isolation.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/parallel-wave-isolation.md","title":null}}]},{"text":" - branch-isolation rule + conditional ephemeral worktrees + cleanup gate for parallel waves","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/plan-mutations.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/plan-mutations.md","title":null}}]},{"text":" - plan mutation audit trail for drift analysis","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/shared-task-notes.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/shared-task-notes.md","title":null}}]},{"text":" - cross-wave context persistence","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/commit-strategies.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/commit-strategies.md","title":null}}]},{"text":" - per-task vs wave-batch commits","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/contract-template.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/contract-template.md","title":null}}]},{"text":" - contract template for worker specs","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/failure-recovery.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/failure-recovery.md","title":null}}]},{"text":" - escalation and retry logic","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/failure-taxonomy.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/failure-taxonomy.md","title":null}}]},{"text":" - failure classification","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/fire.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/fire.md","title":null}}]},{"text":" - FIRE loop specification","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/ralph-loop-contract.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/ralph-loop-contract.md","title":null}}]},{"text":" - Ralph Wiggum loop contract","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/taskcreate-examples.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/taskcreate-examples.md","title":null}}]},{"text":" - task creation examples","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/team-coordination.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/team-coordination.md","title":null}}]},{"text":" - worker coordination details","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/worker-specs.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/worker-specs.md","title":null}}]},{"text":" - per-worker model/tool/prompt specs","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/external-gate-protocol.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/external-gate-protocol.md","title":null}}]},{"text":" - external gate protocol for wave validation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/test-first-mode.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/test-first-mode.md","title":null}}]},{"text":" - test-first wave sequence","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/troubleshooting.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/troubleshooting.md","title":null}}]},{"text":" - common issues and fixes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/uat-integration-wave.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/uat-integration-wave.md","title":null}}]},{"text":" - UAT integration wave patterns","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/wave-patterns.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/wave-patterns.md","title":null}}]},{"text":" - acceptance checks and checkpoints","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/gc-pool-dispatch.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/gc-pool-dispatch.md","title":null}}]},{"text":" - gc pool worker dispatch","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/wave1-spec-consistency-checklist.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/wave1-spec-consistency-checklist.md","title":null}}]},{"text":" - Wave 1 spec consistency checklist","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"references/worktree-per-worker.md","type":"text","marks":[{"type":"link","attrs":{"href":"references/worktree-per-worker.md","title":null}}]},{"text":" - worktree isolation pattern","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"\u003c!-- Lifecycle integration wired: 2026-03-28. See skills/crank/SKILL.md for canonical -->","type":"text"}]}]},"metadata":{"date":"2026-06-05","name":"crank","author":"@skillopedia","source":{"stars":375,"repo_name":"agentops","origin_url":"https://github.com/boshu2/agentops/blob/HEAD/skills-codex/crank/SKILL.md","repo_owner":"boshu2","body_sha256":"3b07c2bd423c09db3794a7537fc0f629cc0685f01981dba49f5463790c0b53a5","cluster_key":"62de11e80e8c852f73bd0ef497b960e6a1bd9374d0adbdd95846c54c3f7cf82f","clean_bundle":{"format":"clean-skill-bundle-v1","source":"boshu2/agentops/skills-codex/crank/SKILL.md","attachments":[{"id":"79730c2b-92bf-5764-9b15-c14f6ce5ec61","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/79730c2b-92bf-5764-9b15-c14f6ce5ec61/attachment.json","path":".agentops-generated.json","size":269,"sha256":"90cc0f05af31068fb8d49d84226b4fc4f2a69f1cf451b77f1f9e02c88fc514b9","contentType":"application/json; charset=utf-8"},{"id":"b886fc47-c00a-5913-8706-4fc46e3a019f","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/b886fc47-c00a-5913-8706-4fc46e3a019f/attachment.md","path":"prompt.md","size":1104,"sha256":"839b270d99bf6562de86200612ff1174a2f8f93853424658388d09344d15d883","contentType":"text/markdown; charset=utf-8"},{"id":"d43a8374-6cb6-5712-9dd6-bae9ef1a794d","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d43a8374-6cb6-5712-9dd6-bae9ef1a794d/attachment.md","path":"references/branch-isolation.md","size":1514,"sha256":"040acf070777bb42a92cebe246c06c80aca232fe69adbff3f082c6233f1bef97","contentType":"text/markdown; charset=utf-8"},{"id":"849173c5-3db2-5b3d-89a6-1ddf1ed43bbf","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/849173c5-3db2-5b3d-89a6-1ddf1ed43bbf/attachment.md","path":"references/commit-strategies.md","size":1938,"sha256":"2dadc6dba5c89d147a34fae539b57a333b8a7952b924b93ec5bc00d1c45cb897","contentType":"text/markdown; charset=utf-8"},{"id":"abba907a-9006-5dc5-a2c7-93132a1dd811","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/abba907a-9006-5dc5-a2c7-93132a1dd811/attachment.md","path":"references/contract-template.md","size":4037,"sha256":"d15a8b98657fd785bb42c7cdafb2a56d047ce673a4a06ac03d29a72b5f267720","contentType":"text/markdown; charset=utf-8"},{"id":"d036f5a1-455f-5b9e-ad45-f3bea58b061d","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d036f5a1-455f-5b9e-ad45-f3bea58b061d/attachment.md","path":"references/de-sloppify.md","size":3097,"sha256":"d4540092dca21551db747d49b26038caa9167a87761bf4a5d4a78897003fbc67","contentType":"text/markdown; charset=utf-8"},{"id":"55974940-b023-53bd-9a98-3eee6a0fd16c","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/55974940-b023-53bd-9a98-3eee6a0fd16c/attachment.md","path":"references/external-gate-protocol.md","size":2240,"sha256":"5b19fcd77e90c895747d32167f1fb933bdb6c014c7b5a1717734500b28fc2188","contentType":"text/markdown; charset=utf-8"},{"id":"475c58c4-cddd-5bdd-be3f-79559e848a52","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/475c58c4-cddd-5bdd-be3f-79559e848a52/attachment.md","path":"references/failure-recovery.md","size":2842,"sha256":"384bcb94e6cd8e917180e95925e4fe89394f83fb1c1f349c692e8b77ffdc3432","contentType":"text/markdown; charset=utf-8"},{"id":"6ae156e6-27cc-5d9f-88a7-7fcb72b1d95a","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6ae156e6-27cc-5d9f-88a7-7fcb72b1d95a/attachment.md","path":"references/failure-taxonomy.md","size":9443,"sha256":"4fa698f54052048563dd9c025f9f261a53ab40f0ad10c52071a32d25fe5811fa","contentType":"text/markdown; charset=utf-8"},{"id":"29a18d0f-5775-5499-9436-f4a98ce53c40","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/29a18d0f-5775-5499-9436-f4a98ce53c40/attachment.md","path":"references/fire.md","size":10962,"sha256":"3296bb74740c77a743acfafc87f826eacbff281890aef3c346d8fa5747ee20c2","contentType":"text/markdown; charset=utf-8"},{"id":"e1e543b4-771e-5460-a57c-311e5eebc3cc","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/e1e543b4-771e-5460-a57c-311e5eebc3cc/attachment.md","path":"references/gc-pool-dispatch.md","size":1479,"sha256":"725ecbcfe52d5b452b579d9e3da13103b7c248b1ad4cd0f7fe78b37a47acabbd","contentType":"text/markdown; charset=utf-8"},{"id":"c925d718-282d-5cba-9e49-c4e9a251931a","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/c925d718-282d-5cba-9e49-c4e9a251931a/attachment.md","path":"references/parallel-wave-isolation.md","size":4709,"sha256":"f24bae90c4fe3b0e0c58d58be1a86077e0fac22f7b28bd2bf7f328647e17d088","contentType":"text/markdown; charset=utf-8"},{"id":"0a74a21d-5d65-5183-86fe-a576b72fd0bb","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/0a74a21d-5d65-5183-86fe-a576b72fd0bb/attachment.md","path":"references/plan-mutations.md","size":4264,"sha256":"a41f2fd5016d968ca66dd1b3586bb0929ec7fb8b387a4ff431f31408215f2e59","contentType":"text/markdown; charset=utf-8"},{"id":"57960bb4-a59a-55a9-a4a8-0570c7cd6a92","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/57960bb4-a59a-55a9-a4a8-0570c7cd6a92/attachment.md","path":"references/ralph-loop-contract.md","size":1924,"sha256":"20999f4507ebb1bc22853d0b805064668328ce58bcf8b5c083e6817f39c83f11","contentType":"text/markdown; charset=utf-8"},{"id":"7d474cf4-95c4-55c5-8975-e4bd3a823d2e","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/7d474cf4-95c4-55c5-8975-e4bd3a823d2e/attachment.md","path":"references/shared-task-notes.md","size":3666,"sha256":"acf3cfb5ecb6ac4e3076b7bde1f21691813ca32aefd53a20c825c92ec908495a","contentType":"text/markdown; charset=utf-8"},{"id":"edb8a7cd-5390-5bc0-b439-2d3282ee93ad","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/edb8a7cd-5390-5bc0-b439-2d3282ee93ad/attachment.md","path":"references/taskcreate-examples.md","size":7747,"sha256":"46acb763e786fe856e5a413aefa395ded201b9a0cea8c75fa78cb9c2bc8008b3","contentType":"text/markdown; charset=utf-8"},{"id":"10f539df-b69e-5914-8730-462ca4ba0586","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/10f539df-b69e-5914-8730-462ca4ba0586/attachment.md","path":"references/team-coordination.md","size":2453,"sha256":"99c723f6edba38935a57dc410c52e9dc3ad6efa1f728e912d34490dbdd7a91f9","contentType":"text/markdown; charset=utf-8"},{"id":"40aef7ef-acbb-5ec2-8d4c-063dd3c11ebe","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/40aef7ef-acbb-5ec2-8d4c-063dd3c11ebe/attachment.md","path":"references/test-first-mode.md","size":7424,"sha256":"eadca0126bfb1d278b8d8524c9ead3202a77dfbe359fb60550295bd455fdde2f","contentType":"text/markdown; charset=utf-8"},{"id":"784b0aab-91ed-5fb3-9300-3a385128d238","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/784b0aab-91ed-5fb3-9300-3a385128d238/attachment.md","path":"references/troubleshooting.md","size":1138,"sha256":"751a80640e8f4029a7ed85a900e22b0764570e6992a3465187cc08b494c48d5d","contentType":"text/markdown; charset=utf-8"},{"id":"39dcc279-78b3-50f2-9527-b5088eaf53bc","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/39dcc279-78b3-50f2-9527-b5088eaf53bc/attachment.md","path":"references/uat-integration-wave.md","size":2990,"sha256":"4b17b7e184fe186bb068fb22c2effbed4d0297812a995b3db45d73bae7600a4e","contentType":"text/markdown; charset=utf-8"},{"id":"0dcc3385-10b3-5940-8721-6af7d7ef80ee","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/0dcc3385-10b3-5940-8721-6af7d7ef80ee/attachment.md","path":"references/wave-patterns.md","size":11357,"sha256":"ff197fc32910d261f4b4b287787c769897ef99f11e7efa0a02233835a3fba10b","contentType":"text/markdown; charset=utf-8"},{"id":"92b4edeb-d830-5da0-9ebf-23957d55680c","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/92b4edeb-d830-5da0-9ebf-23957d55680c/attachment.md","path":"references/wave1-spec-consistency-checklist.md","size":1573,"sha256":"bf8d5f72f67853b84c9c3347cdbb9cb9c98ecd933fabd766f3e75b8525d802c8","contentType":"text/markdown; charset=utf-8"},{"id":"b65b5838-bdb6-54d2-9202-4e6967dfb451","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/b65b5838-bdb6-54d2-9202-4e6967dfb451/attachment.md","path":"references/worker-specs.md","size":3262,"sha256":"1cf209481ef2b5a728e3c391d86127dd3aeb83526a2c85ce1d29d3cdceebe948","contentType":"text/markdown; charset=utf-8"},{"id":"8dd1bd62-5a3a-54a8-b714-7893d72e7489","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/8dd1bd62-5a3a-54a8-b714-7893d72e7489/attachment.md","path":"references/worktree-per-worker.md","size":2092,"sha256":"0dc6d8688455d6dfe167da4f803e0abd48c3dbb8d947b4e7d0e303721bc80b8e","contentType":"text/markdown; charset=utf-8"},{"id":"2196972f-2c0b-553a-a0d7-add92a89e419","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/2196972f-2c0b-553a-a0d7-add92a89e419/attachment.sh","path":"scripts/validate-wave-checkpoint.sh","size":2375,"sha256":"53e7032f71347690c17a52b4dc8b86b8241ad9d7cdd67fc9c6d2c1899d6bed4a","contentType":"application/x-sh; charset=utf-8"},{"id":"c36d2ce9-4585-5935-b979-19d65f22d2a3","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/c36d2ce9-4585-5935-b979-19d65f22d2a3/attachment.sh","path":"scripts/validate.sh","size":1391,"sha256":"f51bd4b5146fd87ff7039baeabed2887819d4d2578aa4d993d2da7bb9522cc2b","contentType":"application/x-sh; charset=utf-8"}],"bundle_sha256":"51f23a88dcd29b41d47e5d238a34b5eb285da4b5e53ca0ff0d8c29e3c0b7c3f5","attachment_count":26,"text_attachments":26,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills-codex/crank/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"general","category_label":"General"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"general","import_tag":"clean-skills-v1","description":"Execute epics through waves."}},"renderedAt":1782980246352}

$crank - Autonomous Epic Execution (Codex Native) Quick Ref: Execute every open issue in an epic via wave-based workers using , , , and . Output: closed issues + final validation. You must execute this workflow. Do not just describe it. Architecture Backend Rules 1. Prefer Codex session agents when is available. 2. Use for implementation agents and for discovery agents when the runtime exposes roles. 3. Use only for short steering or retry prompts. 4. Use for stalled or unnecessary agents. 5. Never depend on legacy CSV fan-out or host-task result polling. Use , , , and instead. Codex Lifecycl…