Loading...
Loading...
Fully autonomous epic execution. Runs until ALL children are CLOSED. Local mode uses /swarm with runtime-native spawning (Codex sub-agents or Claude teams). Distributed mode uses /swarm --mode=distributed (tmux + Agent Mail) for persistence and coordination. NO human prompts, NO stopping.
npx skill4agent add boshu2/agentops crankQuick Ref: Autonomous epic execution. Local mode:for each wave with runtime-native spawning. Distributed mode:/swarm(tmux + Agent Mail). Output: closed issues + final vibe./swarm --mode=distributed
skills/shared/SKILL.mdCrank (orchestrator) Swarm (executor)
| |
+-> bd ready (wave issues) |
| |
+-> TaskCreate from beads --->+-> Select spawn backend (codex sub-agents | claude teams | fallback)
| |
+-> /swarm --->+-> Spawn workers per backend
| | (fresh context per wave)
+-> Verify + bd update <---+-> Workers report via backend channel
| |
+-> Loop until epic DONE <---+-> Cleanup backend resources after waveCrank (orchestrator, TaskList mode) Swarm (executor)
| |
+-> TaskList() (wave tasks) |
| |
+-> /swarm --->+-> Select spawn backend per wave
| |
+-> Verify via TaskList() <---+-> Workers report via backend channel
| |
+-> Loop until all completed <---+-> Cleanup backend resources after wave<promise>DONE</promise><promise>BLOCKED</promise><promise>PARTIAL</promise>/crank [epic-id | plan-file.md | "description"]# If ao CLI available, inject prior knowledge about epic execution
if command -v ao &>/dev/null; then
# Search for relevant learnings
ao search "epic execution implementation patterns" 2>/dev/null | head -20
# Check flywheel status
ao flywheel status 2>/dev/null
# Get current ratchet state
ao ratchet status 2>/dev/null
fiif 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| Beads Mode | TaskList Mode | |
|---|---|---|
| Source of truth | | TaskList (Claude-native) |
| Find work | | |
| Get details | | |
| Mark complete | | |
| Track retries | | Task description update |
| Epic tracking | | In-memory wave counter |
bd list --type epic --status open 2>/dev/null | head -5.mdTaskCreateTaskUpdate(addBlockedBy)TaskList()TaskCreate# Initialize crank tracking in epic notes
bd update <epic-id> --append-notes "CRANK_START: wave=0 at $(date -Iseconds)" 2>/dev/nullwave=0bd show <epic-id> 2>/dev/nullTaskList()bd ready 2>/dev/nullbd readyTaskList()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"wave=$((wave + 1))
WAVE_START_SHA=$(git rev-parse HEAD)
if [[ "$TRACKING_MODE" == "beads" ]]; then
bd update <epic-id> --append-notes "CRANK_WAVE: $wave at $(date -Iseconds)" 2>/dev/null
fi
# CHECK GLOBAL LIMIT
if [[ $wave -ge 50 ]]; then
echo "<promise>BLOCKED</promise>"
echo "Global wave limit (50) reached."
# STOP - do not continue
fi# Guard clause: skip if plan has no boundaries (backward compat)
PLAN_FILE=$(ls -t .agents/plans/*.md 2>/dev/null | head -1)
if [[ -n "$PLAN_FILE" ]] && grep -q "## Boundaries" "$PLAN_FILE"; then
# Extract "Always" boundaries and convert to cross_cutting checks
# Read the plan's ## Cross-Cutting Constraints section or derive from ## Boundaries
# Inject into every TaskCreate's metadata.validation.cross_cutting
fi
# "Ask First" boundaries: in auto mode, log as annotation only (no blocking)
# In --interactive mode, prompt before proceeding{
"validation": {
"files_exist": [...],
"content_check": {...},
"cross_cutting": [
{"name": "...", "type": "content_check", "file": "...", "pattern": "..."}
]
}
}skills/crank/references/team-coordination.md# Only if cross_cutting constraints were injected
if [[ -n "$CROSS_CUTTING_CHECKS" ]]; then
WAVE_FILES=$(git diff --name-only "${WAVE_START_SHA}..HEAD")
for check in $CROSS_CUTTING_CHECKS; do
run_validation_check "$check" "$WAVE_FILES"
done
fiSwarm executes per-task validation (see). Crank trusts swarm validation and focuses on beads sync.skills/shared/validation-contract.md
skills/crank/references/team-coordination.mdskills/crank/references/failure-recovery.mdPrinciple: Fresh context catches what saturated context misses. No self-grading.
skills/crank/references/wave-patterns.mdmkdir -p .agents/crank
cat > ".agents/crank/wave-${wave}-checkpoint.json" <<EOF
{
"wave": ${wave},
"timestamp": "$(date -Iseconds)",
"tasks_completed": $(echo "$COMPLETED_IDS" | jq -R 'split(" ")'),
"tasks_failed": $(echo "$FAILED_IDS" | jq -R 'split(" ")'),
"files_changed": $(git diff --name-only "${WAVE_START_SHA}..HEAD" | jq -R . | jq -s .),
"git_sha": "$(git rev-parse HEAD)"
}
EOFCOMPLETED_IDSFAILED_IDSbd readyTaskList()skills/crank/references/team-coordination.mdskills/crank/references/failure-recovery.mdao forge transcriptao flywheel statusao pool list --tier=pending/post-mortem/post-mortem<promise>DONE</promise>
Epic: <epic-id>
Issues completed: N
Iterations: M/50
Flywheel: <status from ao flywheel status><promise>BLOCKED</promise>
Reason: <global limit reached | unresolvable blockers>
Issues remaining: N
Iterations: M/50skills/crank/references/wave-patterns.mdbd/crank plan.mdStatus: Experimental. Local mode (TaskList + swarm) is the recommended execution method.
skills/crank/references/distributed-mode.mdskills/crank/references/wave-patterns.mdskills/crank/references/team-coordination.mdskills/crank/references/failure-recovery.mdskills/crank/references/distributed-mode.mdskills/shared/agent-mail-protocol.mdcli/internal/agentmail/