Workflow config (_workflow)
Workflow config (_workflow)
Section titled “Workflow config (_workflow)”Every _workflow.<key> BoB reads is declared once, with its default and a comment, in WORKFLOW_DEFAULTS (scripts/warp-drive/state-machine.js, #2041). This page is generated from that table — the key list, defaults, comments and the Read by column (every hook, script, bin entrypoint or command/skill/agent instruction file that reads the key) come from the code, so the page cannot drift.
Layers
Section titled “Layers”A key resolves through four layers, lowest first (#2703). Each layer overrides the one before it key by key, so an explicit 0 or false in a higher layer still wins over a truthy default.
source |
Layer | Where it lives |
|---|---|---|
default |
WORKFLOW_DEFAULTS |
scripts/warp-drive/state-machine.js — the product floor |
fleet-manifest |
provisions/_default.json → _workflow |
the product’s fleet-wide declaration, in BOB_SOURCE |
manifest |
provisions/<project>.json → _workflow |
the project’s version-controlled declaration, in the operator repo (#2270) |
settings |
<project>/.claude/settings.local.json → _workflow |
the per-machine override, never committed |
Both manifests are reached through operatorPath() — never a joined path — and every manifest read is fail-open: no operator resolved, no manifest, an unreadable or malformed file, or a _workflow that is not an object all resolve to {}, so a warp run never fails because of this layer. A key the running BoB does not declare is ignored by the engine; it is refused at validation time instead, because the _workflow block of schemas/manifest.schema.json is generated from this same table (an undeclared key fails make check).
config get <key> --json reports the winning layer as source, config list --sources prints it per key, and bob warp config shows it as a SOURCE column.
Reading a key. The engine resolves it with node ~/.claude/scripts/warp-drive/state-machine.js config get <key> [--cwd DIR] [--json] (config list prints every key resolved, config keys the names; an undeclared key is refused with exit 2). Shell sources scripts/lib/workflow-config.sh and calls workflow_config <key> [project-root] (or workflow_config_true / workflow_config_json) — see Reading _workflow from a hook. Node requires scripts/lib/workflow-key.js and calls workflowKey(projectRoot, key, fallback) (or workflowKeys(projectRoot, {key: fallback})), which loads the engine lazily and fails open to the settings layer (#2719). No consumer reads the _workflow block off a parsed settings file itself — a reader that does sees one of the four layers above and silently disagrees with bob warp config; the gate reports it as a js-leak (shell: jq-leak).
Adding a key. Declare it in WORKFLOW_DEFAULTS with a comment, read it somewhere, then node scripts/checks/check-workflow-keys.js --write to regenerate this page and the _workflow block of schemas/manifest.schema.json. The gate fails on an undeclared read, a declared key nothing reads (dead config), a key without a comment, a jq or JS read of the _workflow block outside the two resolvers (jq-leak / js-leak), or either generated artefact going stale.
Who honours a key (#2740)
Section titled “Who honours a key (#2740)”A read is not the same as an effect. The Honoured by column below says which:
| Value | Meaning |
|---|---|
engine |
A code path — this engine, a script, a hook — reads the key and branches on it. Setting it changes what BoB does, whatever the agent reads. |
agent |
No code path reads it. The key is declared in AGENT_READ_KEYS (scripts/warp-drive/state-machine.js) because its only consumer is an instruction file the agent reads: the lever works when an agent follows its instructions, and not otherwise. Nothing enforces it. |
A key that is named only in instruction prose and is not declared agent-read fails the gate as prose-only-key — it reads as live config and is inert at runtime, which is how max_acs_per_commit came to be documented as configurable while the engine hardcoded 3 (#2740). The reverse — an AGENT_READ_KEYS entry that code does read — fails as mislabelled-agent-key. So the Read by column can never be mistaken for proof that a key has an effect: Honoured by states it.
| Key | Default | Honoured by | Read by |
|---|---|---|---|
max_acs_per_commit |
3 |
engine |
commands/warp-drive.md, scripts/warp-drive/state-machine.js |
vertical_slice_first |
true |
engine |
commands/warp-drive.md, scripts/warp-drive/state-machine.js |
max_phase_minutes |
30 |
engine |
scripts/warp-drive/state-machine.js, scripts/warp-drive/trace-mine-session.sh |
max_retries_per_chunk |
5 |
engine |
scripts/warp-drive/state-machine.js |
max_coding_cycles |
3 |
engine |
scripts/warp-drive/state-machine.js |
max_no_progress |
3 |
engine |
scripts/warp-drive/state-machine.js |
max_qa_cycles |
3 |
engine |
scripts/warp-drive/state-machine.js |
fork_max_parallel |
4 |
engine |
scripts/cdfork/fork.sh, scripts/cdfork/watch.js |
swarm_brief_max_lines |
150 |
engine |
registry/skills/graph-orchestration/SKILL.md, scripts/swarm/decompose.js |
testing_budget_minutes |
10 |
engine |
commands/warp-drive.md, scripts/warp-drive/run-checks.js, scripts/warp-drive/state-machine.js |
check_duration_limit_seconds |
0 |
engine |
commands/warp-drive.md, scripts/warp-drive/run-checks.js, scripts/warp-drive/state-machine.js |
check_duration_growth_ratio |
2 |
engine |
scripts/warp-drive/check-durations.js |
check_duration_window |
10 |
engine |
scripts/warp-drive/check-durations.js |
eval_max_cost_usd |
2 |
engine |
scripts/evals/run.js |
quarantine_bug_filing |
true |
engine |
commands/warp-drive.md, scripts/warp-drive/state-machine.js |
todo_stale_after_days |
7 |
engine |
commands/groom.md, scripts/warp-drive/todo-consume.js |
cap_in_progress_stale_days |
30 |
engine |
commands/groom.md, scripts/warp-drive/cap-status.js |
loop_note_promote_at |
3 |
engine |
commands/groom.md, scripts/warp-drive/loop-notes.js |
loop_note_review_after_days |
30 |
engine |
scripts/warp-drive/loop-notes.js |
qa_scope |
"proportionate" |
engine |
commands/warp-drive.md, scripts/warp-drive/state-machine.js |
test_policy |
"e2e-first" |
engine |
commands/warp-drive.md, scripts/warp-drive/state-machine.js |
verification_gates |
{} |
engine |
scripts/warp-drive/state-machine.js |
pre_exit_verification |
true |
engine |
hooks/lib/warp-drive-pre-exit.sh |
max_edits_per_file |
5 |
engine |
hooks/lib/warp-drive-edit-tracker.sh |
reasoning_budget |
{} |
engine |
scripts/warp-drive/state-machine.js |
reconcile_per_chunk |
true |
engine |
scripts/warp-drive/state-machine.js |
flightplan_tick_on_item_boundary |
true |
engine |
commands/flightplan.md, scripts/warp-drive/state-machine.js |
area_completion_briefs |
true |
engine |
scripts/brief/brief.js, scripts/warp-drive/state-machine.js |
brief_reconcile |
true |
engine |
scripts/brief/brief.js, scripts/tick/tick.sh |
ask_budget |
5 |
engine |
scripts/asks/asks.js |
ask_budget_portfolio |
15 |
engine |
scripts/asks/asks.js |
ask_recheck_days |
30 |
engine |
scripts/asks/recheck.js |
ask_done_check_ttl_minutes |
30 |
engine |
scripts/asks/done-check.js |
ask_moot_threshold |
0.3 |
engine |
scripts/asks/sources.js |
trace_mining_sessions |
5 |
agent |
registry/commands/trace-mining.md |
distill_decision_count |
75 |
engine |
hooks/lib/capture-decision.sh, registry/commands/trace-mining.md, scripts/decision-log/distill.sh |
distill_decision_counter |
0 |
engine |
registry/commands/trace-mining.md, scripts/decision-log/distill.sh |
decision_log_max |
5000 |
engine |
scripts/decision-log/distill.sh |
max_total_chunks |
20 |
engine |
scripts/warp-drive/state-machine.js |
max_session_minutes |
480 |
engine |
scripts/warp-drive/state-machine.js |
max_session_tokens |
0 |
engine |
scripts/warp-drive/budget-policy.js, scripts/warp-drive/kickoff.js |
max_session_usd |
0 |
engine |
scripts/warp-drive/budget-policy.js, scripts/warp-drive/kickoff.js |
segment_after_tokens |
120000 |
engine |
commands/warp-drive.md, scripts/warp-drive/segmentation.js, scripts/warp-drive/state-machine.js |
segment_after_chunks |
0 |
engine |
scripts/warp-drive/segmentation.js, scripts/warp-drive/state-machine.js |
segment_at_seam_tokens |
40000 |
engine |
scripts/warp-drive/segmentation.js, scripts/warp-drive/state-machine.js |
max_budget_auto_continues |
0 |
engine |
scripts/warp-drive/budget-policy.js |
max_auto_decisions |
10 |
engine |
scripts/warp-drive/state-machine.js |
revalidate_on_area_entry |
true |
engine |
commands/warp-drive.md, scripts/warp-drive/state-machine.js |
phase_timeout_enforcement |
"warn" |
engine |
scripts/warp-drive/state-machine.js |
doc_drift_gate |
false |
engine |
commands/warp-drive.md, scripts/warp-drive/state-machine.js |
baseline_docs_check |
true |
engine |
scripts/warp-drive/baseline-docs-check.sh |
baseline_docs |
["readme","runbook","claude"] |
engine |
commands/warp-drive.md, scripts/warp-drive/baseline-docs-check.sh |
baseline_docs_max_commits |
25 |
engine |
commands/warp-drive.md, scripts/warp-drive/baseline-docs-check.sh |
baseline_docs_auto_approve |
false |
engine |
scripts/warp-drive/baseline-docs-check.sh |
session_merge |
"local" |
engine |
scripts/warp-drive/state-machine.js |
delegate_mechanical_chunks |
false |
agent |
commands/warp-drive.md, registry/skills/llm-tiering/SKILL.md |
navmap_context |
true |
engine |
scripts/warp-drive/navmap-cache.js, scripts/warp-drive/state-machine.js |
navmap_top |
8 |
engine |
scripts/warp-drive/navmap-cache.js |
navmap_degraded_min_files |
3 |
engine |
scripts/warp-drive/navmap-cache.js |
farm_eligible |
false |
engine |
scripts/checks/check-rituals.js, scripts/rituals/ritual.js, scripts/warp-drive/eligibility.js, scripts/warp-drive/flightplan.js |
unattended |
false |
engine |
commands/finish-work.md, commands/warp-drive.md, hooks/lib/cf-destructive-guard.sh, hooks/lib/destructive-git-guard.sh, hooks/lib/promotion-ceiling-guard.sh, hooks/lib/self-modification-guard.sh, scripts/backup/ops.js, scripts/promotion/promotion.js, scripts/ready/ready.js, scripts/tick/tick.sh, scripts/warp-drive/state-machine.js |
auto_session_branch |
true |
engine |
scripts/warp-drive/state-machine.js |
ci_runner_preflight |
true |
engine |
commands/warp-drive.md, scripts/warp-drive/state-machine.js |
forge_degraded_mode |
true |
engine |
scripts/warp-drive/state-machine.js |
forge_replay_on_item_boundary |
true |
engine |
scripts/warp-drive/state-machine.js |
tick_wall_clock_minutes |
300 |
engine |
scripts/tick/tick.sh |
tick_max_issues |
3 |
engine |
scripts/tick/tick.sh |
tick_max_tokens |
0 |
engine |
scripts/tick/tick.sh |
doc_drift_blocking |
false |
engine |
hooks/lib/doc-drift-warning.sh |
suppress_doc_drift_warning |
false |
engine |
hooks/lib/doc-drift-warning.sh |
suppress_vue_safe_lint |
false |
engine |
hooks/lib/doc-drift-warning.sh |
suppress_doc_orphan_gate |
false |
engine |
hooks/lib/doc-orphan-gate.sh, scripts/doc-keeper/orphan-check.js |
self_update |
true |
engine |
registry/commands/trace-mining.md, scripts/decision-log/self-update.sh |
provision_preflight |
true |
engine |
commands/start-work.md, commands/warp-drive.md, scripts/orchestrator/provision-preflight.js |
harness_defect_filing |
true |
engine |
scripts/warp-drive/state-machine.js |
harness_defect_escalate_after |
3 |
engine |
commands/what-next.md, scripts/warp-drive/harness-defect-summary.js |
preflight_recheck |
true |
engine |
scripts/warp-drive/state-machine.js |
self_redeploy |
true |
engine |
scripts/warp-drive/state-machine.js |
gap_recurrence_count |
3 |
engine |
registry/commands/trace-mining.md, scripts/evidence/gap-analysis.js |
gap_recurrence_sessions |
2 |
engine |
registry/commands/trace-mining.md, scripts/evidence/gap-analysis.js |
ritual_release_gate |
false |
engine |
scripts/release/release.sh, scripts/rituals/ritual.js |
docs_release_gate |
false |
engine |
scripts/release/release.sh |
do_budget_minutes |
60 |
engine |
scripts/do/do.js |
reap_idle_minutes |
240 |
engine |
scripts/warp-drive/reap.js |
Details
Section titled “Details”max_acs_per_commit
Section titled “max_acs_per_commit”Chunking: max acceptance-criteria checkboxes per commit-sized chunk.
Default: 3. Honoured by: engine. Read by: commands/warp-drive.md, scripts/warp-drive/state-machine.js.
vertical_slice_first
Section titled “vertical_slice_first”Chunking (#2736): append the vertical-slice tiebreaker to the chunking instruction for a tracer item — prefer a vertical slice, keep AC order, chunk 1 is the tracer slice. false leaves the instruction byte-identical.
Default: true. Honoured by: engine. Read by: commands/warp-drive.md, scripts/warp-drive/state-machine.js.
max_phase_minutes
Section titled “max_phase_minutes”Soft per-phase wall-clock timer (minutes); what happens when it trips is phase_timeout_enforcement. Never stops a running check (see testing_budget_minutes).
Default: 30. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js, scripts/warp-drive/trace-mine-session.sh.
max_retries_per_chunk
Section titled “max_retries_per_chunk”Circuit breaker: verify attempts per chunk before retry_exceeded halts the loop.
Default: 5. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
max_coding_cycles
Section titled “max_coding_cycles”Circuit breaker: coding→testing→coding cycles per chunk before halting.
Default: 3. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
max_no_progress
Section titled “max_no_progress”No-progress / stall guard (#267): consecutive identical failed attempts (same failure signature AND no new diff) before halting the coding↔testing and coding↔doc_drift_check loops. Distinct from the raw coding_cycles count — this only fires on stagnation, not on legitimate slow progress.
Default: 3. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
max_qa_cycles
Section titled “max_qa_cycles”In-session QA loop cap (#868): max qa→coding→qa cycles before the loop halts at budget_exceeded for human review. A dedicated bound so a project that keeps surfacing E2E defects can never spin the QA loop forever, on top of the generic no-progress / total-chunks breakers.
Default: 3. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
fork_max_parallel
Section titled “fork_max_parallel”Fork concurrency cap (#3550): the most live bob fork --from-flightplan windows at once — a forked plan item still open in the plan holds a slot. It bounds the first wave and every later dispatch bob fork watch makes when an item lands; items over the cap wait for a slot.
Default: 4. Honoured by: engine. Read by: scripts/cdfork/fork.sh, scripts/cdfork/watch.js.
swarm_brief_max_lines
Section titled “swarm_brief_max_lines”Swarm brief line budget (#3557): a subtask whose rendered brief (.swarm/briefs/<id>.md, decompose.js) runs longer than this is too big for one worker — the analyze verdict names it as a candidate to split.
Default: 150. Honoured by: engine. Read by: registry/skills/graph-orchestration/SKILL.md, scripts/swarm/decompose.js.
testing_budget_minutes
Section titled “testing_budget_minutes”Testing budget (#1979): minutes for the whole testing pass, enforced by run-checks.js — once spent it stops LAUNCHING checks (each is recorded skipped: budget) and cuts a check still running; the phase then advances on the result of what ran. Separate from max_phase_minutes (a warn-mode phase timer that never stops anything). 0 = unlimited. The skipped list reaches the chunk report and the commit’s Tests-Skipped: trailer.
Default: 10. Honoured by: engine. Read by: commands/warp-drive.md, scripts/warp-drive/run-checks.js, scripts/warp-drive/state-machine.js.
check_duration_limit_seconds
Section titled “check_duration_limit_seconds”Check duration limit (#4449): seconds a passing check may take before run-checks.js records it too_slow and the testing pass fails, naming the check, its duration and the limit, and saying to speed the suite up. A check’s own max_seconds in dev.json checks wins. 0 = no limit.
Default: 0. Honoured by: engine. Read by: commands/warp-drive.md, scripts/warp-drive/run-checks.js, scripts/warp-drive/state-machine.js.
check_duration_growth_ratio
Section titled “check_duration_growth_ratio”Check duration growth (#4449): a check whose duration this pass is over this many times the median of its last check_duration_window runs (the per-project history in .claude/.check-durations.json) raises an advisory in the chunk report and bob warp status. It never blocks. 0 = off.
Default: 2. Honoured by: engine. Read by: scripts/warp-drive/check-durations.js.
check_duration_window
Section titled “check_duration_window”How many recorded runs of a check the growth median is taken over (#4449).
Default: 10. Honoured by: engine. Read by: scripts/warp-drive/check-durations.js.
eval_max_cost_usd
Section titled “eval_max_cost_usd”Skill eval cost ceiling (#2390): the –max-cost-usd scripts/evals/run.js hands claude plugin eval when no –max-cost-usd is given. Every eval run is a full claude child per case and arm on the operator’s credential, so a ceiling is mandatory: run.js refuses 0 or a negative value.
Default: 2. Honoured by: engine. Read by: scripts/evals/run.js.
quarantine_bug_filing
Section titled “quarantine_bug_filing”Flaky-on-base quarantine filing (#1979 AC-05): when the runner quarantines a check (fails on HEAD AND on the unmodified base with the same failure), file/bump a fingerprinted bug on the PROJECT repo at tests_passed / tests_failed via quarantine-report.js. Best-effort, never blocks.
Default: true. Honoured by: engine. Read by: commands/warp-drive.md, scripts/warp-drive/state-machine.js.
todo_stale_after_days
Section titled “todo_stale_after_days”Stale-todo age floor (#2034): the groom sweep (todo-consume.js stale) never flags a todo younger than this many days, and reads links that closed AFTER the todo was filed as likely-completed (surfaced, never labelled) rather than stale — #1999 was labelled stale 4.5 h after filing, mid-action. 0 disables the floor. todo-consume.js mirrors the default for its pure planner.
Default: 7. Honoured by: engine. Read by: commands/groom.md, scripts/warp-drive/todo-consume.js.
cap_in_progress_stale_days
Section titled “cap_in_progress_stale_days”Long-in-progress cap age (#2064): the groom sweep (cap-status.js audit) reports long-in-progress for an open cap labelled in-progress whose most recent child close is older than this many days — the cluster has stalled even though its label says otherwise. Report-only: the sweep never closes or relabels a cap, it prints a decide-or-park prompt. 0 disables the check. cap-status.js mirrors the default for its pure planner.
Default: 30. Honoured by: engine. Read by: commands/groom.md, scripts/warp-drive/cap-status.js.
loop_note_promote_at
Section titled “loop_note_promote_at”Loop-note promotion threshold (#2063): a recorded quirk becomes work when it keeps recurring. loop-notes.js promote files (or bumps) one fingerprinted bug per note whose count reaches this number, and writes the issue back onto the note as its defect: tag so the existing #1837 retirement closes the loop. 3 is “twice was coincidence, three times is a defect”; 0 disables promotion entirely.
Default: 3. Honoured by: engine. Read by: commands/groom.md, scripts/warp-drive/loop-notes.js.
loop_note_review_after_days
Section titled “loop_note_review_after_days”Loop-note review age (#2905): an untagged loop note has no defect whose closure retires it, so the continuing-education rituals (comprehensive- review, vision-planning) list each one recorded at least this many days ago that has not recurred inside the window (loop-notes.js review, report-only in the packet). 0 turns the untagged review off.
Default: 30. Honoured by: engine. Read by: scripts/warp-drive/loop-notes.js.
qa_scope
Section titled “qa_scope”Proportionate qa (#1979 AC-06): browser-driven verification is used only when the item changed behaviour (code) or an AC names browser verification; presentation-only changes (templates, styles, config, copy, reorders) advance with qa_skipped / presentation-only. ‘always’ keeps the pre-#1979 rule (run E2E whenever there is a browser-testable surface).
Default: "proportionate". Honoured by: engine. Read by: commands/warp-drive.md, scripts/warp-drive/state-machine.js.
test_policy
Section titled “test_policy”Test policy (#3200): what kind of test the coding and testing phases ask for — docs/reference/test-policy.md. ‘e2e-first’ is all seven rules (drive the real entry point, never unit-test after the code, no tautological or change-detector tests …); ‘balanced’ relaxes rules 1–2 so a unit test may follow the code for pure logic. Anything else reads as e2e-first.
Default: "e2e-first". Honoured by: engine. Read by: commands/warp-drive.md, scripts/warp-drive/state-machine.js.
verification_gates
Section titled “verification_gates”Per-event verification gates ({event: {semantic, targets}}) merged into state.gates at init alongside the two built-in semantic gates.
Default: {}. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
pre_exit_verification
Section titled “pre_exit_verification”Stop-hook self-verification (hooks/warp-drive-pre-exit.sh): inject a verify prompt before a phase-exit transition. false = skip the prompt.
Default: true. Honoured by: engine. Read by: hooks/lib/warp-drive-pre-exit.sh.
max_edits_per_file
Section titled “max_edits_per_file”Doom-loop detector (hooks/warp-drive-edit-tracker.sh): edits to one file in a chunk beyond this count are recorded as a doom event on state.
Default: 5. Honoured by: engine. Read by: hooks/lib/warp-drive-edit-tracker.sh.
reasoning_budget
Section titled “reasoning_budget”Per-phase overrides of DEFAULT_REASONING_BUDGET ({phase: ‘standard’|‘high’}).
Default: {}. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
reconcile_per_chunk
Section titled “reconcile_per_chunk”Reconcile the requirement issue’s checkboxes at every next_chunk / requirement_done, not only at the end of the item.
Default: true. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
flightplan_tick_on_item_boundary
Section titled “flightplan_tick_on_item_boundary”Tick the finished requirement off the run’s flight plan on the transition into awaiting_continue (#1757), rather than trusting the agent to run the #1068 check-off command. Idempotent and best-effort; false reverts to prose-only ticking plus the session_ending reconcile sweep.
Default: true. Honoured by: engine. Read by: commands/flightplan.md, scripts/warp-drive/state-machine.js.
area_completion_briefs
Section titled “area_completion_briefs”Detect area completions at the item boundary and at session end (#3169): a detached bob brief --completions --project . --apply files a briefing for each area the run drained. Never blocks the transition; false leaves detection to bob tick and bob brief –reconcile.
Default: true. Honoured by: engine. Read by: scripts/brief/brief.js, scripts/warp-drive/state-machine.js.
brief_reconcile
Section titled “brief_reconcile”The brief reconcile (#3978): bob brief --reconcile and bob tick step 9b tick resolved brief actions, close finished briefs and rebuild the index. false turns both off; the area completions they also run follow area_completion_briefs, which bob brief --completions honours too.
Default: true. Honoured by: engine. Read by: scripts/brief/brief.js, scripts/tick/tick.sh.
ask_budget
Section titled “ask_budget”The attention budget (#3805): how many open asks of the operator one project shows at once. bob asks lists the highest priority, oldest first, up to the budget; an ask beyond it waits (label ask-waiting) and sends no push and raises no banner until it is inside. 0 = no cap.
Default: 5. Honoured by: engine. Read by: scripts/asks/asks.js.
ask_budget_portfolio
Section titled “ask_budget_portfolio”The same budget across every project (#3805): the most open asks bob asks shows for the whole portfolio. Resolved at the fleet layer (provisions/_default.json), not per project. 0 = no cap.
Default: 15. Honoured by: engine. Read by: scripts/asks/asks.js.
ask_recheck_days
Section titled “ask_recheck_days”The re-check window (#3808): bob asks recheck re-checks an open to-do nobody has touched for longer than this many days. One whose named issues are all closed no longer matters and is withdrawn; any other gets one comment recording the re-check, which starts the window again. 0 = never.
Default: 30. Honoured by: engine. Read by: scripts/asks/recheck.js.
ask_done_check_ttl_minutes
Section titled “ask_done_check_ttl_minutes”The done-check cache (#3986): a to-do’s declared Done-check: probes are run before it is listed (bob asks, Control, the briefing) and on every bob tick; a result younger than this many minutes is reused rather than probed again. Resolved at the fleet layer. 0 = probe every time.
Default: 30. Honoured by: engine. Read by: scripts/asks/done-check.js.
ask_moot_threshold
Section titled “ask_moot_threshold”The moot threshold (#3810): the share of a filing path’s asks closed without completed above which the path is reported. bob asks sources marks each source above it, bob brief lists it under needs_you, and bob asks sources --file-bugs --apply files one bug for it. A share from 0 to 1, resolved at the fleet layer. 1 = never.
Default: 0.3. Honoured by: engine. Read by: scripts/asks/sources.js.
trace_mining_sessions
Section titled “trace_mining_sessions”/trace-mining: how many past sessions one run analyses.
Default: 5. Honoured by: agent (no engine path reads it — see Who honours a key). Read by: registry/commands/trace-mining.md.
distill_decision_count
Section titled “distill_decision_count”Count-triggered distillation of the decision log (#356). distill_decision_count is the fire threshold — once that many user decisions accumulate in .claude/.decisions.jsonl, /trace-mining auto-distills them (the count is illustrative, not load-bearing). distill_decision_counter mirrors the live active-log count into settings; decision_log_max is the hard safety ceiling above which the oldest records roll into the archive. Engine: scripts/decision-log/distill.sh.
Default: 75. Honoured by: engine. Read by: hooks/lib/capture-decision.sh, registry/commands/trace-mining.md, scripts/decision-log/distill.sh.
distill_decision_counter
Section titled “distill_decision_counter”Live mirror of the active decision-log count, written by distill.sh (not a user setting).
Default: 0. Honoured by: engine. Read by: registry/commands/trace-mining.md, scripts/decision-log/distill.sh.
decision_log_max
Section titled “decision_log_max”Hard ceiling on active decision-log records; the oldest roll into the archive above it.
Default: 5000. Honoured by: engine. Read by: scripts/decision-log/distill.sh.
max_total_chunks
Section titled “max_total_chunks”Circuit breaker hard limits (#76): chunks per session, then wall-clock minutes per session.
Default: 20. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
max_session_minutes
Section titled “max_session_minutes”Circuit breaker: session wall-clock minutes before budget_exceeded.
Default: 480. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
max_session_tokens
Section titled “max_session_tokens”Cost/token budget stop condition (#587). An enforced spend ceiling routed through the circuit breaker to budget_exceeded — closing the gap where a runaway loop could burn budget while staying under every count-based cap. Token count is the reliable signal; max_session_usd is optional/secondary (estimated via token-report’s shared cost model). Both default to 0 = DISABLED, so existing sessions are unaffected unless a ceiling is configured.
Default: 0. Honoured by: engine. Read by: scripts/warp-drive/budget-policy.js, scripts/warp-drive/kickoff.js.
max_session_usd
Section titled “max_session_usd”Optional dollar ceiling, estimated from tokens via token-report’s cost model (0 = off).
Default: 0. Honoured by: engine. Read by: scripts/warp-drive/budget-policy.js, scripts/warp-drive/kickoff.js.
segment_after_tokens
Section titled “segment_after_tokens”Session segmentation thresholds (#870, part of #865). A long L3/L4 run checkpoints at a clean per-requirement boundary, ends its session, and resumes in a FRESH context so output quality doesn’t degrade over hours of accumulated history. These are SOFT thresholds — distinct from the HARD max_session_tokens ceiling above (which HALTS at budget_exceeded). Crossing a segmentation threshold does not stop work: it hands the remaining queue to a fresh session (cdfork-style spawn + the existing inject hook), which keeps accumulating onto the same integration branch. Measured PER SEGMENT (delta since the last checkpoint), never whole-run cumulative — else the fresh session would re-trip immediately. segment_after_tokens defaults ON at 120000 (#959): usage analysis showed 73% of spend lands at >150k context, so segments are kept comfortably below that regime out of the box. An explicit _workflow.segment_after_tokens: 0 still fully disables it (opt-out preserved — loadConfig’s spread lets an explicit setting, including 0, win over this default). This is the SINGLE resolution point for the default. Policy: scripts/warp-drive/segmentation.js.
Default: 120000. Honoured by: engine. Read by: commands/warp-drive.md, scripts/warp-drive/segmentation.js, scripts/warp-drive/state-machine.js.
segment_after_chunks
Section titled “segment_after_chunks”Same segmentation trigger by chunks completed since the last checkpoint (0 = off).
Default: 0. Honoured by: engine. Read by: scripts/warp-drive/segmentation.js, scripts/warp-drive/state-machine.js.
segment_at_seam_tokens
Section titled “segment_at_seam_tokens”Seam-aware segmentation (#960). When the NEXT queued item crosses a cap/area boundary from the just-finished one, warm context is worth less — so the run segments at this LOWER per-segment token threshold instead of waiting for segment_after_tokens. Hybrid: the seam lowers the bar, never forces a segment (0 = seam trigger disabled). Inert under the full segmentation opt-out — the seam refines segmentation, it cannot re-enable it. Policy: seamBetween/segmentationDecision in segmentation.js.
Default: 40000. Honoured by: engine. Read by: scripts/warp-drive/segmentation.js, scripts/warp-drive/state-machine.js.
max_budget_auto_continues
Section titled “max_budget_auto_continues”Bounded budget_exceeded auto-continue under L4 (#873). 0 = DISABLED: the breaker is a mandatory human checkpoint at every level (L2/L3 always, and L4 until this is set). When > 0 AND the session is Level 4, budget_exceeded may auto-continue up to this many times for SOFT breakers (no-progress, cycle, phase-time, chunk, qa) — the hard cost/token/dollar ceiling always halts and is never auto-continued past. Every auto-continue is logged + recorded as a decision. Policy: scripts/warp-drive/budget-policy.js.
Default: 0. Honoured by: engine. Read by: scripts/warp-drive/budget-policy.js.
max_auto_decisions
Section titled “max_auto_decisions”Decision budget (#876, part of #865). Caps the number of AUTO-decisions the L4 reversibility engine may make in one session before a MANDATORY human digest checkpoint — the guard against the decision-cascade doom-loop the diff-based no-progress breaker can’t catch (dozens of individually-reasonable two-way calls that compound into an unreviewed architecture). Reaching the cap routes to budget_exceeded, which presents the accumulated decisions for review/reversal. Unlike the soft breakers, it is NEVER auto-continued past by #873’s bounded auto-continue — the whole point is a human review. Enabled by default; harmless below L4, where the engine never auto-decides so the counter stays 0. Set to 0 to disable. Counter: state.budgets.auto_decisions; digest: state.decisions[].
Default: 10. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
revalidate_on_area_entry
Section titled “revalidate_on_area_entry”Per-area approval re-validation (#1008). The approved label is stamped by /groom against a SNAPSHOT of the repo; a long multi-area run invalidates that premise by landing commits before later areas are reached. When true, selecting an item across a cap/area SEAM from the just-finished one (same seamBetween signal as #960) arms a revalidating sub-mode of planning: a deterministic movement gate (scripts/warp-drive/revalidate.js) compares HEAD against the item’s <!-- approved-at: sha --> marker, and only on movement does the lightweight AC re-check run — reversible drift is auto-adjusted, irreversible drift is surfaced (#878 classification). Never fires before the first item (freshly groomed) and never widens the kickoff scope (#992) — it re-validates only the already-selected item. false restores the trust-approval-blindly semantics.
Default: true. Honoured by: engine. Read by: commands/warp-drive.md, scripts/warp-drive/state-machine.js.
phase_timeout_enforcement
Section titled “phase_timeout_enforcement”Phase timeout enforcement: ‘warn’ (advisory), ‘block’ (reject transition), ‘abort’ (auto-abort)
Default: "warn". Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
doc_drift_gate
Section titled “doc_drift_gate”Doc-drift gate: when true, the slash command fires commit_with_doc_gate instead of committed, routing through the doc_drift_check phase before reporting. Default false to preserve historical behavior.
Default: false. Honoured by: engine. Read by: commands/warp-drive.md, scripts/warp-drive/state-machine.js.
baseline_docs_check
Section titled “baseline_docs_check”Baseline-docs check (#364): at prerequisites, detect missing scaffolding docs on greenfield projects (README/runbook/CLAUDE.md) and file unapproved req tracking issues. Never authors narrative (CAP-15 non-goal) — only surfaces the gap. Idempotent and non-blocking.
Default: true. Honoured by: engine. Read by: scripts/warp-drive/baseline-docs-check.sh.
baseline_docs
Section titled “baseline_docs”Which baseline docs the check requires: any of readme / runbook / claude.
Default: ["readme","runbook","claude"]. Honoured by: engine. Read by: commands/warp-drive.md, scripts/warp-drive/baseline-docs-check.sh.
baseline_docs_max_commits
Section titled “baseline_docs_max_commits”Greenfield gate: skip the check on repos with more than this many commits (mature repos already have these docs). Set to 0 to always run.
Default: 25. Honoured by: engine. Read by: commands/warp-drive.md, scripts/warp-drive/baseline-docs-check.sh.
baseline_docs_auto_approve
Section titled “baseline_docs_auto_approve”When true, filed tracking issues get the approved label (warp-drive would then write the doc itself in a later cycle). Default false keeps narrative human-gated.
Default: false. Honoured by: engine. Read by: scripts/warp-drive/baseline-docs-check.sh.
session_merge
Section titled “session_merge”Integration-branch merge mode (#269 / cap #268). Selects what the merging phase does when a session branch is set (merge_target != main_branch): ‘local’ — merge each requirement’s child branch into the session branch locally per merge_strategy, push the session branch, delete the child branch. Main is never touched (accumulate, ship once). ‘pr’ — preserve historical behavior (L2 PR to merge_target / L3 direct-to-main). Also the effective behavior when no session branch is set, regardless of this value.
Default: "local". Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
delegate_mechanical_chunks
Section titled “delegate_mechanical_chunks”Cheap-tier chunk delegation (#384, cap #376). When true, the coding phase MAY implement a provably-mechanical, self-contained chunk via an isolated cheap-tier Task subagent instead of the main loop, with the main loop as the fail-open backstop. Default false: every chunk runs on the main loop, an end-state identical to having no delegation. Measured saving on mechanical chunks ~10-92x — see docs/research/warp-drive-model-routing.md §8. Switched on per project, never fleet-wide (#2680, decision #2704): bigbrain declares _workflow.delegate_mechanical_chunks: true in its manifest (the #2703 layer — bob warp config reports source manifest), and seed-heavy app repos are the next candidates; provisions/_default.json stays off until the after-measurement (#2705) confirms the saving. Which tier runs a delegated chunk follows the model-assignment policy in the llm-tiering skill.
Default: false. Honoured by: agent (no engine path reads it — see Who honours a key). Read by: commands/warp-drive.md, registry/skills/llm-tiering/SKILL.md.
navmap_context
Section titled “navmap_context”Scoped navigation map (#603): inject the #601 /where “start-here” file map for the current chunk’s task into coding context, derived once per chunk and reused across sub-agents (scripts/warp-drive/navmap-cache.js). Default on but guarded — self-skips a thin/empty map; navmap_context: false opts out.
Default: true. Honoured by: engine. Read by: scripts/warp-drive/navmap-cache.js, scripts/warp-drive/state-machine.js.
navmap_top
Section titled “navmap_top”Files surfaced in the scoped nav map.
Default: 8. Honoured by: engine. Read by: scripts/warp-drive/navmap-cache.js.
navmap_degraded_min_files
Section titled “navmap_degraded_min_files”Below this file count a degraded map is skipped as noise rather than injected.
Default: 3. Honoured by: engine. Read by: scripts/warp-drive/navmap-cache.js.
farm_eligible
Section titled “farm_eligible”Unattended eligibility (#2052): when true, the farm tick may seat ANY approved req (and any verified bug) on this project without the farm label. Default false — the night shift takes only explicitly delegated work (eligibility.js).
Default: false. Honoured by: engine. Read by: scripts/checks/check-rituals.js, scripts/rituals/ritual.js, scripts/warp-drive/eligibility.js, scripts/warp-drive/flightplan.js.
unattended
Section titled “unattended”Unattended run (#2053): when true the run never pushes the main branch directly — promotion.js decide resolves merge=pr regardless of level, the merging phase opens a PR and hands it to scripts/promotion/merge-on-green.sh, which fast-forwards the base only when the runner’s CI is green. The farm tick sets it; a laptop session leaves it false (direct merge at L3).
Default: false. Honoured by: engine. Read by: commands/finish-work.md, commands/warp-drive.md, hooks/lib/cf-destructive-guard.sh, hooks/lib/destructive-git-guard.sh, hooks/lib/promotion-ceiling-guard.sh, hooks/lib/self-modification-guard.sh, scripts/backup/ops.js, scripts/promotion/promotion.js, scripts/ready/ready.js, scripts/tick/tick.sh, scripts/warp-drive/state-machine.js.
auto_session_branch
Section titled “auto_session_branch”Kickoff integration branch (#4405): a multi-item run (–flightplan, –area, or more than one –issue) on a checkout with no _branch.session pins stream/<machine-id>-<YYYY-MM-DD> itself at init, through the same path as bob warp session start, so its items accumulate there and the main branch (and its CI) moves once, at bob warp finalize — which the engine runs at session_ended at Level 3 (where finalize merges; at Level 2 and 4 it opens a PR, so the summary names it). A second checkout of the repo the same day pins <stream>-<worktree name>. A single-issue run and an unattended run keep the per-item merge. false turns it off.
Default: true. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
ci_runner_preflight
Section titled “ci_runner_preflight”CI runner preflight (#1731): on entry to merging the engine runs scripts/fleet/ci-locus.js preflight for a project that declares _meta.ci (–apply at Level 3+, dry run at Level 2) and records the verdict on state.ci_preflight. A farm runner that is offline PARKS jobs instead of failing them, so the run learns it before it waits on CI; a blocked verdict (no viable runner, hosted dead, degraded with fallback off) is a named blockable event — merge_failed + a todo — never a merge-on-green timeout. false skips the probe; an undeclared project is skipped without a call.
Default: true. Honoured by: engine. Read by: commands/warp-drive.md, scripts/warp-drive/state-machine.js.
forge_degraded_mode
Section titled “forge_degraded_mode”Forge degraded mode (#1751): every transition reads the forge signal the gh shim keeps (#1748) and enters DEGRADED MODE on a degraded/unreachable verdict — coding, testing and committing continue on cached reads and spooled writes, and entering merging parks the run until the forge answers (state-machine.js forge-check resumes it). false turns the whole mode off.
Default: true. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
forge_replay_on_item_boundary
Section titled “forge_replay_on_item_boundary”Item-boundary replay (#3191): on entry to awaiting_continue and discovering the engine replays the forge write queue (#1750) itself, each call bounded, so an agent never waits to see a queued write land and never replays by hand. With nothing queued it costs one directory read. false leaves replay to the gh shim’s drain-on-recovery alone.
Default: true. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
tick_wall_clock_minutes
Section titled “tick_wall_clock_minutes”Farm tick wall-clock budget (#2054, #2055): minutes bob tick waits for its warp-drive tmux session to end. Past it the tick stops the run gracefully (bob warp stop — the aborted phase, never a kill), reconciles, and exits 4 with budget: wall-clock.
Default: 300. Honoured by: engine. Read by: scripts/tick/tick.sh.
tick_max_issues
Section titled “tick_max_issues”Farm tick issue budget (#2055): the most req/bug items one tick’s plan may seat — bob plan build --from farm --max-items <n>; gating todos ride along.
Default: 3. Honoured by: engine. Read by: scripts/tick/tick.sh.
tick_max_tokens
Section titled “tick_max_tokens”Farm tick token budget (#2055): total tokens one tick’s run may spend, passed to the run as the kickoff --max-tokens ceiling (the session breaker) and checked against token-report.js –since after it; spent → exit 4 with budget: tokens. 0 = off.
Default: 0. Honoured by: engine. Read by: scripts/tick/tick.sh.
doc_drift_blocking
Section titled “doc_drift_blocking”Doc-drift gate policy (hooks/doc-drift-warning.sh, #151/#757): a tooling commit with no *.md change exits 2 (blocking) instead of warning.
Default: false. Honoured by: engine. Read by: hooks/lib/doc-drift-warning.sh.
suppress_doc_drift_warning
Section titled “suppress_doc_drift_warning”Doc-drift gate off entirely (silent no-op) — for projects without docs.
Default: false. Honoured by: engine. Read by: hooks/lib/doc-drift-warning.sh.
suppress_vue_safe_lint
Section titled “suppress_vue_safe_lint”Skip the vue-safe angle-bracket lint at commit time (#988) — a non-site project.
Default: false. Honoured by: engine. Read by: hooks/lib/doc-drift-warning.sh.
suppress_doc_orphan_gate
Section titled “suppress_doc_orphan_gate”Skip the doc-orphan commit gate (hooks/doc-orphan-gate.sh, #1444) — a project that does not publish its docs.
Default: false. Honoured by: engine. Read by: hooks/lib/doc-orphan-gate.sh, scripts/doc-keeper/orphan-check.js.
self_update
Section titled “self_update”Self-update opt-out gate (scripts/decision-log/self-update.sh, #358): false refuses every apply (–dry-run stays available).
Default: true. Honoured by: engine. Read by: registry/commands/trace-mining.md, scripts/decision-log/self-update.sh.
provision_preflight
Section titled “provision_preflight”Provisioning preflight gate at prerequisites (#1267): false skips the adequacy check (read from settings.local.json, then settings.json).
Default: true. Honoured by: engine. Read by: commands/start-work.md, commands/warp-drive.md, scripts/orchestrator/provision-preflight.js.
harness_defect_filing
Section titled “harness_defect_filing”Outward filing of unreported harness_defects[] as de-duplicated harness-defect bugs at chunk_complete / session_ending (#1836). Best-effort.
Default: true. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
harness_defect_escalate_after
Section titled “harness_defect_escalate_after”Recurrence count at which a filed harness-defect is bumped to p2-high with a comment (#1838); 0 disables the escalation.
Default: 3. Honoured by: engine. Read by: commands/what-next.md, scripts/warp-drive/harness-defect-summary.js.
preflight_recheck
Section titled “preflight_recheck”Cheap host-only re-run of the #1923 preflight gate at next_chunk / continue_yes; new drift routes to blocked. The kickoff gate has no opt-out.
Default: true. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
self_redeploy
Section titled “self_redeploy”Self-hosting redeploy (#2472), read only when the project IS BOB_SOURCE: at continue_yes the re-check counts this run’s own merged deploy-managed surfaces as behind, and a deployable drift checkpoints so the next segment deploys after this session exits. false keeps the #1982 in-flight exclusion.
Default: true. Honoured by: engine. Read by: scripts/warp-drive/state-machine.js.
gap_recurrence_count
Section titled “gap_recurrence_count”Gap analysis (scripts/evidence/gap-analysis.js, #1131): a capability gap counts as recurring once seen this many times across this many sessions.
Default: 3. Honoured by: engine. Read by: registry/commands/trace-mining.md, scripts/evidence/gap-analysis.js.
gap_recurrence_sessions
Section titled “gap_recurrence_sessions”Distinct sessions a gap must appear in before it counts as recurring.
Default: 2. Honoured by: engine. Read by: registry/commands/trace-mining.md, scripts/evidence/gap-analysis.js.
ritual_release_gate
Section titled “ritual_release_gate”Ritual release gate (#2236): when true, bob release promote refuses (exit 4, “held”) while a ritual this project declares with gates: [“stable-release”] is overdue — a dated cadence past its next due date, or a before-stable-release ritual not held since the last stable release — and ritual.js due reports the held promotion in release_gate. Off by default: the gate is opt-in per project; with it off, due still reports what would hold. --allow-overdue <ritual> is the logged override. bob release promote --auto (the farm tick) refuses (exit 3) while the gate is off or unreadable, so unattended promotion never skips it (#3627).
Default: false. Honoured by: engine. Read by: scripts/release/release.sh, scripts/rituals/ritual.js.
docs_release_gate
Section titled “docs_release_gate”Docs currency release gate (#2554): every stable bob release and bob release promote reports a “docs currency gate” line — pages staleness.js grades stale and bob commands check-howto-coverage.js finds without a how-to. When true, a non-zero count HOLDS the release (exit 4) and an unreadable verdict refuses; --allow-stale-docs is the logged override (a decision issue). Off by default: the line is then a warning and the release proceeds.
Default: false. Honoured by: engine. Read by: scripts/release/release.sh.
do_budget_minutes
Section titled “do_budget_minutes”bob do (#2979): the working-phase budget, in minutes, when bob do is run without –budget. Exhausting it moves the run to landing with budget_exhausted: true — never a silent stall. A token budget is –budget only.
Default: 60. Honoured by: engine. Read by: scripts/do/do.js.
reap_idle_minutes
Section titled “reap_idle_minutes”bob warp reap (#3302): minutes a tmux pane running Claude Code (outside the warp-seg-* sessions) may sit idle before it is graded stale, and an idle shell-only session is reported. --idle <minutes> overrides it per call.
Default: 240. Honoured by: engine. Read by: scripts/warp-drive/reap.js.