Crank Skill
Quick Ref: Autonomous epic execution. /swarm for each wave with runtime-native spawning. Output: closed issues + phase-2 handoff for /validation.
YOU MUST EXECUTE THIS WORKFLOW. Do not just describe it.
Autonomous execution: implement all issues until the epic is DONE.
CLI dependencies: bd (issue tracking), ao (knowledge flywheel). Both optional β see skills/shared/SKILL.md for fallback table. If bd is unavailable, use TaskList for issue tracking and skip beads sync. If ao is unavailable, skip knowledge injection/extraction.
For Claude runtime feature coverage (agents/hooks/worktree/settings), the shared source of truth is skills/shared/references/claude-code-latest-features.md, mirrored locally at references/claude-code-latest-features.md.
Architecture: Crank + Swarm
Crank owns orchestration, epic/task lifecycle, and knowledge-flywheel steps. Swarm owns runtime-native worker spawning, fresh-context isolation, per-wave execution, and cleanup. In beads mode Crank gets each wave from bd ready, bridges issues into worker tasks, verifies results, and syncs status back to beads. In TaskList mode the same loop runs over pending unblocked tasks instead of beads issues.
Read references/team-coordination.md for the full per-wave execution model and references/ralph-loop-contract.md for the fresh-context worker contract.
Flags
| Flag |
Default |
Description |
--test-first |
off |
Enable spec-first TDD: SPEC WAVE generates contracts, TEST WAVE generates failing tests, IMPL WAVES make tests pass |
--per-task-commits |
off |
Opt-in per-task commit strategy. Falls back to wave-batch when file boundaries overlap. See references/commit-strategies.md. |
--tier=<name> |
(auto) |
Force a specific cost tier (quality/balanced/budget) for all council calls. Overrides effort-to-tier auto-mapping. |
--no-lifecycle |
off |
Skip ALL lifecycle skill auto-invocations (test delegation in TEST WAVE, pre-vibe deps/test checks) |
--lifecycle=<tier> |
matches complexity |
Controls which lifecycle skills fire: minimal (test only), standard (+deps vuln), full (all) |
--no-scope-check |
off |
Skip scope-completion check before DONE marker (Step 8.7) |
--skip-audit |
off |
Skip bd-audit pre-flight gate (Step 3a.2) |
Global Limits
MAX_EPIC_WAVES = 50 (hard limit across entire epic)
This prevents infinite loops on circular dependencies or cascading failures. Typical epics use 5β10 waves max.
Completion Enforcement (The Sisyphus Rule)
Not done until you emit an explicit completion marker after each wave:
<promise>DONE</promise> when the epic is truly complete
<promise>BLOCKED</promise> when progress cannot continue
<promise>PARTIAL</promise> when work remains
Never claim completion without one of these markers.
Node Repair Operator
When a task fails during wave execution, classify as RETRY (transient β re-add with adjustment, max 2), DECOMPOSE (too complex β split into sub-issues, terminal), or PRUNE (blocked β escalate immediately). Budget: 2 per task. Read references/failure-recovery.md for classification signals and recovery commands.
Mutation logging on failure classification:
- DECOMPOSE: Log
task_removed for the original task, then task_added for each new sub-task.
- PRUNE: Log
task_removed with the block reason.
- RETRY: No mutation (task identity unchanged).
Execution Steps
Given /crank [epic-id | .agents/rpi/execution-packet.json | plan-file.md | "description"]:
Recovery Hooks
Register a PostCompact hook: "command": "cat .agents/crank/wave-*-checkpoint.json | tail -1" to auto-recover wave state after compaction. Consider worktree.sparsePaths to reduce worktree size.
Effort levels per worker type:
| Worker Role |
Recommended Effort |
Rationale |
| SPEC wave (contracts) |
medium |
Balanced reasoning for spec generation |
| TEST wave (failing tests) |
medium |
Test scaffolding needs moderate depth |
| IMPL wave (make tests pass) |
high |
Deep reasoning for correct implementation |
| Docs/chore tasks |
low |
Fast execution for simple tasks |
Effort-to-Tier Mapping: highβopus, mediumβsonnet, lowβhaiku. Used for council calls (wave acceptance, final vibe). Override with --tier=<name> flag or models.skill_overrides.crank in .agentops/config.yaml.
Step 0: Load Knowledge Context (ao Integration)
If ao CLI available, pull relevant knowledge: ao lookup --query "<epic-title>" --limit 5, ao metrics flywheel status, ao ratchet status. Apply retrieved learnings as implementation constraints and cite with ao metrics cite "<path>" --type applied (influenced decision) or --type retrieved (loaded but not referenced). Prefer matched_snippet over full files when lookup results include section evidence. If ao unavailable, skip and proceed.
Step 0.5: Detect Tracking Mode
if command -v bd &>/dev/null; then
TRACKING_MODE="beads"
else
TRACKING_MODE="tasklist"
echo "Note: bd CLI not found. Using TaskList for issue tracking."
fi
Tracking mode determines the source of truth for the rest of the workflow:
|
Beads Mode |
TaskList Mode |
| Source of truth |
bd (beads issues) |
TaskList (Claude-native) |
| Find work |
bd ready |
TaskList() β pending, unblocked |
| Get details |
bd show <id> |
TaskGet(taskId) |
| Mark complete |
bd update <id> --status closed |
TaskUpdate(taskId, status="completed") |
| Track retries |
bd comments add |
Task description update |
| Epic tracking |
bd update <epic-id> --append-notes |
In-memory wave counter |
Step 0.6: Detect gc Pool Backend
Check gc status --json for a running controller. Set GC_POOL_AVAILABLE=true if gc is available. When true, gc pool handles worker lifecycle and auto-scales based on bd ready --count. Crank simplifies to: create issues, gc scales workers, workers close issues, crank validates. See references/gc-pool-dispatch.md for dispatch details.
Step 1: Identify the Epic / Work Source
Beads mode:
If epic ID provided: Use it directly. Do NOT ask for confirmation.
If no epic ID: Discover it:
bd list --type epic --status open 2>/dev/null | head -5
Single-Epic Scope Check (WARN):
If bd list --type epic --status open returns more than one epic, log a warning:
WARN: Multiple open epics detected. /crank operates on a single epic.
Use --allow-multi-epic to suppress this warning.
If multiple epics found, ask user which one (WARN, not FAIL).
TaskList mode:
If input is an epic ID β Error: "bd CLI required for beads epic tracking. Install bd or provide a plan file / task list."
If input is a plan file path (.md):
- Read the plan file
- Decompose into TaskList tasks (one
TaskCreate per distinct work item)
- Set up dependencies via
TaskUpdate(addBlockedBy)
- Proceed to Step 3
If no input:
- Check
TaskList() for existing pending tasks
- If tasks exist, use them as the work items
- If no tasks, ask user what to work on
If input is a description string:
- Decompose into tasks (
TaskCreate for each)
- Set up dependencies
- Proceed to Step 3
Step 1a: Initialize Wave Counter
Beads mode:
bd update <epic-id> --append-notes "CRANK_START: wave=0 at $(date -Iseconds)" 2>/dev/null
TaskList mode: Track wave counter in memory only. No external state needed.
Track in memory: wave=0
Step 1a.1: Initialize Plan Mutation Audit Trail
mkdir -p .agents/rpi
: > .agents/rpi/plan-mutations.jsonl
Initialize the log_plan_mutation helper and budget counters. See references/plan-mutations.md for the full JSONL schema, helper function, budget limits, and mutation types.
Step 1a.2: Initialize Shared Task Notes
mkdir -p .agents/crank
cat > .agents/crank/SHARED_TASK_NOTES.md <<EOF
# Shared Task Notes β Epic ${EPIC_ID:-unknown}
> Cross-wave context for workers. Read before starting.
EOF
See references/shared-task-notes.md for the full pattern, size management, and worker integration.
Step 1b: Detect Test-First Mode (--test-first only)
if [[ "$TEST_FIRST" == "true" ]]; then
SPEC_ELIGIBLE=()
SPEC_SKIP=()
if [[ "$TRACKING_MODE" == "beads" ]]; then
for issue in $READY_ISSUES; do
ISSUE_TYPE=$(bd show "$issue" 2>/dev/null | grep "Type:" | head -1 | awk '{print tolower($NF)}')
case "$ISSUE_TYPE" in
feature|bug|task) SPEC_ELIGIBLE+=("$issue") ;;
docs|chore|ci|epic) SPEC_SKIP+=("$issue") ;;
*)
echo "WARNING: Issue $issue has unknown type '$ISSUE_TYPE'. Defaulting to spec-eligible."
SPEC_ELIGIBLE+=("$issue")
;;
esac
done
else
SPEC_ELIGIBLE=($READY_ISSUES)
echo "TaskList mode: all ${#SPEC_ELIGIBLE[@]} issues defaulted to spec-eligible (no bd type info)"
fi
echo "Test-first mode: ${#SPEC_ELIGIBLE[@]} spec-eligible, ${#SPEC_SKIP[@]} skipped (docs/chore/ci/epic)"
fi
If --test-first is NOT set, skip Steps 3b and 3c entirely β behavior is unchanged.
Step 2: Get Epic Details
Beads mode:
bd show <epic-id> 2>/dev/null
TaskList mode: TaskList() to see all tasks and their status/dependencies.
Step 3: List Ready Issues (Current Wave)
Beads mode:
Find issues that can be worked on (no blockers):
bd ready 2>/dev/null
bd ready returns the current wave - all unblocked issues. These can be executed in parallel because they have no dependencies on each other.
TaskList mode:
TaskList() β filter for status=pending, no blockedBy (or all blockers completed). These are the current wave.
Step 3a: Pre-flight Check - Issues Exist
Verify there are issues to work on:
If 0 ready issues found (beads mode) or 0 pending unblocked tasks (TaskList mode):
STOP and return error:
"No ready issues found for this epic. Either:
- All issues are blocked (check dependencies)
- Epic has no child issues (run /plan first)
- All issues already completed"
Also verify: epic has at least 1 child issue total. An epic with 0 children means /plan was not run.
Do NOT proceed with empty issue list - this produces false "epic complete" status.
Step 3a.1: Pre-flight Check - Pre-Mortem Required (3+ issues)
If the epic has 3+ child issues, look for a pre-mortem report in .agents/council/*pre-mortem*. If none found, emit <promise>BLOCKED</promise> and stop β run /pre-mortem first. Pre-mortems have positive ROI for 3+ issue epics; cost (~2 min) is negligible.
Step 3a.2: Pre-flight Check - Bead Audit (Stale/Fixed/Consolidatable)
Run scripts/bd-audit.sh --json (beads mode only) before wave execution to avoid burning compute on dead work. WARNING gate β warns on any flagged beads, blocks at >50% flagged. Use --skip-audit to bypass. If blocked, clean up with scripts/bd-audit.sh --auto-close and scripts/bd-cluster.sh --auto-merge, then re-run crank.
Step 3a.3: Pre-flight Check - Changed-String Grep
Before spawning workers, grep for every string being changed by the plan.