Appearance
Warp-Drive State Reference
The warp-drive state machine, exhaustively. State file shape, the state-machine CLI, and the full phase-transition table. Extracted from the warp-drive guide's internals section.
Internals Reference
For contributors and power users.
State File
Location: <project>/.claude/.warp-drive-state.json
This is what state-machine.js init produces (with a few rows populated after the first transitions). Keep this in sync with the state object literal at the bottom of init() in scripts/warp-drive/state-machine.js.
json
{
"version": 1,
"session": {
"started_at": "2026-05-08T15:56:59.401Z",
"started_at_epoch": 1778255819402,
"pid": 51506,
"level": 3,
"github_user": "paulirv"
},
"phase": "coding",
"requirement": "42",
"branch": "feature/issue-42-title",
"chunk": { "index": 1, "total": 5, "acs": [["AC-01","AC-02"],["AC-03"]] },
"checklist": {
"docs_updated": false,
"tests_passed": false,
"committed": false,
"report_filed": false
},
"budgets": {
"phase_started_at": "2026-05-08T15:57:53.487Z",
"retry_count": 0,
"coding_cycles": 0
},
"aborted": false,
"edit_counts": { "src/file.ts": 3 },
"doom_loop_events": [],
"gates": {
"code_complete": { "semantic": "diff_relevance_check" },
"docs_updated": { "semantic": "ac_count_check" }
},
"completed_chunks": [],
"history": [
{ "phase": "prerequisites", "at": "..." },
{ "phase": "discovering", "at": "...", "from": "prerequisites", "event": "prerequisites_ok" }
],
"metrics": {
"commits": 0,
"reports_filed": 0,
"tests_run": 0,
"chunks_completed": 0,
"session_duration_minutes": 0
},
"token_usage": {
"session_total": null,
"chunk_snapshots": [],
"current_chunk_started_at": null
},
"main_branch": "master",
"session_branch": null,
"merge_target": "master",
"merge_strategy": "ff-only"
}Fields appear roughly in this order in the file. Notes on the less-obvious ones:
session.started_at_epochandsession.github_userare populated atinit; the latter comes fromgh api user -q .login(empty string ifghis unauthenticated, which silently disables@mentionnotifications).aborted: falseflips totruewhen the engine routes through theabortedphase. Cleanup messaging keys off this flag.gatesis seeded with the two semantic gates (diff_relevance_check,ac_count_check) plus anyverification_gatesfrom_workflowconfig. Thetargetsarrays from config land alongsidesemanticon the matching event keys.metrics.session_duration_minutesis updated when the engine writes the state — useful when reporting fromwarp status.main_branch/session_branch/merge_target/merge_strategyare populated from~/.claude/scripts/branch-detect.shatinitand consulted duringmerging.- After
budget_exceeded,budgetsgainsexceeded_reasons,exceeded_at, andexceeded_from_phaseto record the trip.
State Machine CLI
bash
node ~/.claude/scripts/warp-drive/state-machine.js <action> <project-root> [args]| Action | Purpose |
|---|---|
init | Create new session: init <root> --level 2 --issue 42 --pid $PPID |
status | Show current state (exit 2 if no session) |
transition | Move phases: transition <root> <event> [--data '{"key":"val"}'] |
inject | Get phase context for SessionStart hook |
gate | Check if an operation is allowed: gate <root> git_commit |
verify | Run verification gates: verify <root> code_complete |
abort | Shorthand for transition <root> abort |
reset | Delete state file immediately |
Transition Table
Every phase lists its valid events and where they lead. This matches the TRANSITIONS object in scripts/warp-drive/state-machine.js.
| Phase | Event | Next Phase |
|---|---|---|
| idle | start | prerequisites |
| idle | abort | aborted |
| prerequisites | prerequisites_ok | discovering |
| prerequisites | abort | aborted |
| discovering | work_selected | planning |
| discovering | no_work | session_ending |
| discovering | abort | aborted |
| planning | plan_ready | chunking |
| planning | abort | aborted |
| chunking | chunks_defined | coding |
| chunking | abort | aborted |
| coding | code_complete | updating_docs |
| coding | abort | aborted |
| updating_docs | docs_updated | testing |
| updating_docs | abort | aborted |
| testing | tests_passed | committing |
| testing | tests_failed | coding |
| testing | abort | aborted |
| committing | committed | reporting |
| committing | commit_with_doc_gate | doc_drift_check |
| committing | abort | aborted |
| doc_drift_check | drift_clean | reporting |
| doc_drift_check | drift_blocked | coding |
| doc_drift_check | abort | aborted |
| reporting | report_filed | chunk_complete |
| reporting | abort | aborted |
| chunk_complete | next_chunk | coding |
| chunk_complete | requirement_done | requirement_complete |
| chunk_complete | abort | aborted |
| requirement_complete | merge_ready | merging |
| requirement_complete | abort | aborted |
| merging | merged | awaiting_continue |
| merging | merge_failed | merging |
| merging | push_failed | merging |
| merging | abort | aborted |
| awaiting_continue | continue_yes | discovering |
| awaiting_continue | continue_no | session_ending |
| awaiting_continue | abort | aborted |
| session_ending | session_ended | completed |
| session_ending | abort | aborted |
| budget_exceeded | budget_continue | coding |
| budget_exceeded | budget_abort | aborted |
| budget_exceeded | abort | aborted |
| aborted | abort_resolved | completed |
| aborted | abort_cleanup_failed | completed |
| aborted | restart | idle |
Budget-trigger reasons. When an enforced budget trips, the engine routes the current phase into budget_exceeded and records the reason on state.budgets.exceeded_reasons. The reasons are:
| Reason | Source | Default Threshold | Config Key |
|---|---|---|---|
phase_timeout | Phase elapsed too long | 30 min | max_phase_minutes (+ phase_timeout_enforcement) |
retry_exceeded | Per-chunk retry counter exceeded | 5 retries | max_retries_per_chunk |
coding_cycles_exceeded | Code/test cycles for this chunk exceeded | 3 cycles | max_coding_cycles |
no_progress | Consecutive identical failed attempts — same failure signature AND no new diff (stagnation, not raw attempts) | 3 attempts | max_no_progress |
total_chunks_exceeded | Chunks completed in this session exceeded hard limit | 20 chunks | max_total_chunks |
session_timeout | Total session duration exceeded hard limit | 480 min | max_session_minutes |
phase_timeout is only enforced (rather than a soft warning) when phase_timeout_enforcement is block or abort — see Configuration. The other five are always enforced.