@tyroneross/build-loop 0.30.3 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/plugins/marketplace.json +2 -2
- package/.claude-plugin/marketplace.json +4 -4
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/AGENTS.md +9 -0
- package/README.md +8 -7
- package/agents/advisor.md +111 -0
- package/agents/alignment-checker.md +11 -0
- package/agents/assessment-orchestrator.md +1 -1
- package/agents/build-orchestrator.md +28 -33
- package/agents/fact-checker.md +1 -1
- package/agents/fix-critique.md +1 -1
- package/agents/independent-auditor.md +1 -1
- package/agents/overfitting-reviewer.md +1 -1
- package/agents/plan-critic.md +5 -4
- package/agents/promotion-reviewer.md +1 -1
- package/agents/retrospective-synthesizer.md +20 -3
- package/agents/scope-auditor.md +1 -1
- package/agents/security-reviewer.md +1 -1
- package/agents/self-improvement-architect.md +1 -1
- package/commands/{handoff.md → compose-handoff.md} +4 -4
- package/commands/{optimize.md → optimize-run.md} +1 -1
- package/commands/{agent-rally-point.md → rally-point.md} +3 -3
- package/commands/{research.md → research-run.md} +1 -1
- package/commands/setup-memory.md +32 -0
- package/commands/{plan-verify.md → verify-plan.md} +1 -1
- package/docs/agent-surface-policy.md +38 -20
- package/docs/memory-setup.md +19 -14
- package/hooks/_resolve_python.sh +28 -0
- package/hooks/closeout.sh +58 -0
- package/hooks/git/pre-push +69 -6
- package/hooks/hooks.json +34 -13
- package/hooks/post-push-closeout.sh +73 -0
- package/hooks/session-start-closeout.sh +69 -0
- package/hooks/session-start-memory.sh +27 -0
- package/hooks/session-start-plugin-heal.sh +33 -0
- package/hooks/test_closeout.sh +124 -0
- package/package.json +7 -4
- package/plugin-artifacts/codex/.codex-plugin/plugin.json +41 -0
- package/plugin-artifacts/codex/AGENTS.md +499 -0
- package/plugin-artifacts/codex/BUILD-ARTIFACT.md +5 -0
- package/plugin-artifacts/codex/LICENSE +202 -0
- package/plugin-artifacts/codex/README.md +404 -0
- package/plugin-artifacts/codex/docs/agent-surface-policy.md +63 -0
- package/plugin-artifacts/codex/references/advisor-dispatch-ladder.md +62 -0
- package/plugin-artifacts/codex/references/agent-role-taxonomy.md +101 -0
- package/plugin-artifacts/codex/references/autonomous-and-per-commit-modes.md +161 -0
- package/plugin-artifacts/codex/references/autonomy-config.md +231 -0
- package/plugin-artifacts/codex/references/capability-routing.md +182 -0
- package/plugin-artifacts/codex/references/codex-subagents.md +106 -0
- package/plugin-artifacts/codex/references/coordination-file-template.md +181 -0
- package/plugin-artifacts/codex/references/coordination-rules.md +283 -0
- package/plugin-artifacts/codex/references/dogfood-reload-checkpoint.md +112 -0
- package/plugin-artifacts/codex/references/halt-and-ask-protocol.md +102 -0
- package/plugin-artifacts/codex/references/implementer-envelope-schema.md +302 -0
- package/plugin-artifacts/codex/references/intent-capability-pack.md +257 -0
- package/plugin-artifacts/codex/references/intent-exploration-prompts.md +96 -0
- package/plugin-artifacts/codex/references/leadership.md +72 -0
- package/plugin-artifacts/codex/references/memory-systems.md +238 -0
- package/plugin-artifacts/codex/references/memory.md +297 -0
- package/plugin-artifacts/codex/references/model-tier-mapping.md +257 -0
- package/plugin-artifacts/codex/references/modular-systems-pack.md +96 -0
- package/plugin-artifacts/codex/references/phase-1-assess.md +231 -0
- package/plugin-artifacts/codex/references/phase-2-plan.md +77 -0
- package/plugin-artifacts/codex/references/phase-3-execute.md +47 -0
- package/plugin-artifacts/codex/references/phase-4-review.md +320 -0
- package/plugin-artifacts/codex/references/phase-5-iterate.md +71 -0
- package/plugin-artifacts/codex/references/phase-6-learn.md +56 -0
- package/plugin-artifacts/codex/references/recent-design-structures.md +274 -0
- package/plugin-artifacts/codex/references/research-trigger-policy.md +140 -0
- package/plugin-artifacts/codex/references/runtime-smoke-triggers.md +42 -0
- package/plugin-artifacts/codex/references/self-review.md +234 -0
- package/plugin-artifacts/codex/references/single-writer-commit-protocol.md +90 -0
- package/plugin-artifacts/codex/references/task-capture-policy.md +68 -0
- package/plugin-artifacts/codex/references/ui-io-contract.md +116 -0
- package/plugin-artifacts/codex/references/ui-spotcheck-protocol.md +65 -0
- package/plugin-artifacts/codex/skills/build-loop/SKILL.md +372 -0
- package/plugin-artifacts/codex/skills/build-loop/detect-plugins.mjs +82 -0
- package/plugin-artifacts/codex/skills/build-loop/eval-guide.md +65 -0
- package/plugin-artifacts/codex/skills/build-loop/fallbacks.md +549 -0
- package/plugin-artifacts/codex/skills/build-loop/phases/fact-check.md +42 -0
- package/plugin-artifacts/codex/skills/build-loop/phases/ui-validation.md +267 -0
- package/plugin-artifacts/codex/skills/build-loop/references/advisor-dispatch-ladder.md +62 -0
- package/plugin-artifacts/codex/skills/build-loop/references/apple-native-planning.md +439 -0
- package/plugin-artifacts/codex/skills/build-loop/references/autonomous-and-per-commit-modes.md +161 -0
- package/plugin-artifacts/codex/skills/build-loop/references/capability-routing.md +182 -0
- package/plugin-artifacts/codex/skills/build-loop/references/codex-subagents.md +106 -0
- package/plugin-artifacts/codex/skills/build-loop/references/coordination.md +161 -0
- package/plugin-artifacts/codex/skills/build-loop/references/correction-aware-capture.md +177 -0
- package/plugin-artifacts/codex/skills/build-loop/references/independent-auditor.md +72 -0
- package/plugin-artifacts/codex/skills/build-loop/references/intent-capability-pack.md +257 -0
- package/plugin-artifacts/codex/skills/build-loop/references/intent-exploration-prompts.md +96 -0
- package/plugin-artifacts/codex/skills/build-loop/references/leadership.md +72 -0
- package/plugin-artifacts/codex/skills/build-loop/references/memory.md +297 -0
- package/plugin-artifacts/codex/skills/build-loop/references/modular-systems-pack.md +96 -0
- package/plugin-artifacts/codex/skills/build-loop/references/output-style.md +129 -0
- package/plugin-artifacts/codex/skills/build-loop/references/pay-it-forward-arch.md +98 -0
- package/plugin-artifacts/codex/skills/build-loop/references/phase-1-assess.md +231 -0
- package/plugin-artifacts/codex/skills/build-loop/references/phase-2-plan.md +77 -0
- package/plugin-artifacts/codex/skills/build-loop/references/phase-3-execute.md +47 -0
- package/plugin-artifacts/codex/skills/build-loop/references/phase-4-review.md +320 -0
- package/plugin-artifacts/codex/skills/build-loop/references/phase-5-iterate.md +71 -0
- package/plugin-artifacts/codex/skills/build-loop/references/phase-6-learn.md +56 -0
- package/plugin-artifacts/codex/skills/build-loop/references/recent-design-structures.md +274 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/ASSESSMENT.md +85 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/STANDALONE_TEST_RUN.md +149 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/01-simple-bugfix.md +32 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/02-ui-build-with-iteration.md +48 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/03-multi-failure-escalation.md +60 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/04-ui-build-ibr-absent.md +51 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/05-refactor-navgator-absent.md +71 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/06-recurring-bug-debugger-absent.md +52 -0
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/trace-comparison.md +202 -0
- package/plugin-artifacts/codex/skills/build-loop/references/self-recursive-dev.md +77 -0
- package/plugin-artifacts/codex/skills/build-loop/references/self-review.md +234 -0
- package/plugin-artifacts/codex/skills/build-loop/references/ui-io-contract.md +116 -0
- package/plugin-artifacts/codex/skills/build-loop/scanners/audit-design-rules.mjs +476 -0
- package/plugin-artifacts/codex/skills/build-loop/scanners/require-visual-evidence.mjs +239 -0
- package/plugin-artifacts/codex/skills/build-loop/templates/backlog-item.md +35 -0
- package/plugin-artifacts/codex/skills/build-loop/templates/codex-worker-prompt.md +96 -0
- package/plugin-artifacts/codex/skills/build-loop/templates/ui-subagent-prompt.md +179 -0
- package/plugin-artifacts/codex/skills/build-loop/templates/ux-fix-plan.md +40 -0
- package/scripts/_paths.py +59 -13
- package/scripts/build_codex_plugin_artifact.py +314 -0
- package/scripts/check_cache_sync.py +1 -1
- package/scripts/install_memory.py +11 -3
- package/scripts/prune_plugin_cache.py +225 -11
- package/scripts/sync_navgator_lessons.py +25 -0
- package/scripts/sync_plugin_cache.py +66 -36
- package/skills/agent-rally-point/SKILL.md +1 -1
- package/skills/agent-rally-watcher/SKILL.md +1 -1
- package/skills/build-loop/SKILL.md +11 -155
- package/skills/build-loop/references/advisor-dispatch-ladder.md +62 -0
- package/skills/build-loop/references/autonomous-and-per-commit-modes.md +161 -0
- package/skills/build-loop/references/capability-routing.md +4 -3
- package/skills/build-loop/references/codex-subagents.md +8 -0
- package/skills/build-loop/references/coordination.md +1 -1
- package/skills/build-loop/references/intent-capability-pack.md +88 -1
- package/skills/build-loop/references/memory.md +17 -2
- package/skills/build-loop/references/phase-1-assess.md +13 -0
- package/skills/build-loop/references/phase-2-plan.md +1 -1
- package/skills/build-loop/references/phase-4-review.md +12 -0
- package/skills/build-loop/references/phase-6-learn.md +1 -1
- package/skills/build-loop/references/self-review.md +4 -2
- package/skills/build-loop/templates/codex-worker-prompt.md +41 -34
- package/skills/handoff/SKILL.md +3 -3
- package/skills/loop-builder/SKILL.md +98 -0
- package/skills/loop-builder/presets/active-project-evidence.yaml +97 -0
- package/skills/loop-builder/presets/generic-artifact-loop.yaml +95 -0
- package/skills/loop-builder/presets/presentation-audit.yaml +96 -0
- package/skills/loop-builder/presets/research-synthesis.yaml +96 -0
- package/skills/loop-builder/presets/source-ingestion-raw-data-audit.yaml +96 -0
- package/skills/loop-builder/references/spec-format.md +80 -0
- package/skills/loop-builder/scripts/loop_builder.py +346 -0
- package/skills/model-tiering/SKILL.md +65 -40
- package/skills/optimize/SKILL.md +2 -2
- package/skills/plan-verify/SKILL.md +1 -1
- package/skills/plugin-builder/references/distribution.md +8 -0
- package/skills/research/SKILL.md +33 -6
- package/skills/runtime-parity-verification/SKILL.md +51 -0
- package/skills/spec-writing/SKILL.md +19 -0
- package/templates/memory/README.md +65 -0
- package/templates/memory/charter.md.template +46 -0
- package/templates/memory/manifest.json +24 -4
- package/codex-skills/debug-loop/SKILL.md +0 -18
- package/codex-skills/handoff/SKILL.md +0 -22
- package/codex-skills/knowledge/SKILL.md +0 -21
- package/codex-skills/optimize/SKILL.md +0 -18
- package/codex-skills/research/SKILL.md +0 -18
- /package/commands/{knowledge-review.md → review-knowledge.md} +0 -0
|
@@ -19,8 +19,8 @@ A 5-phase development loop with a mandatory Phase 6: assess state and criteria,
|
|
|
19
19
|
Internal modes:
|
|
20
20
|
|
|
21
21
|
- **Build** (default): Full 5-phase loop plus mandatory Phase 6 Learn — triggered by implementation, fix, refactor, migrate, or update language
|
|
22
|
-
- **Optimize**: Metric-driven optimization loop — triggered by "speed up", "reduce", "improve" + a mechanical metric (`/build-loop:optimize` as a direct override)
|
|
23
|
-
- **Research**: Pre-decision analysis, outputs a research packet, no commits — triggered by "research", "evaluate", "compare", "should I" (`/build-loop:research` as a direct override)
|
|
22
|
+
- **Optimize**: Metric-driven optimization loop — triggered by "speed up", "reduce", "improve" + a mechanical metric (`/build-loop:optimize-run` as a direct override)
|
|
23
|
+
- **Research**: Pre-decision analysis, outputs a research packet, no commits — triggered by "research", "evaluate", "compare", "should I" (`/build-loop:research-run` as a direct override)
|
|
24
24
|
- **Debug**: Deep iterative root-cause investigation — triggered by symptom language; also auto-invoked inside the loop on Review-B failures (`/build-loop:debug` as a direct override)
|
|
25
25
|
- **Test**: Static plugin-test suite — triggered by "test plugin", "validate plugin" (`/build-loop:test` as a direct override)
|
|
26
26
|
|
|
@@ -38,158 +38,14 @@ To raise the cap toward the hard ceiling, set in `.build-loop/config.json`:
|
|
|
38
38
|
|
|
39
39
|
Values above 12 are clamped. Values above `cpu_count−2` are clamped to `cpu_count−2` to leave headroom for the orchestrator and host OS.
|
|
40
40
|
|
|
41
|
-
## Autonomous Mode
|
|
41
|
+
## Autonomous Mode + Per-Commit Mode
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
Both are conditional modes — their flag tables, budget/iteration caps, question-timeout rules, self-recursive detection, and the per-commit dispatch contract (incl. the GAP-1 parent-dispatch audit + E3 Learn/retro contract) load on demand from `references/autonomous-and-per-commit-modes.md`. Read it when:
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
- the invocation carries `--long` / `--budget` / `--autonomous=false`, or the goal text matches a long-running keyword (`overnight`, `large-scale`, `multi-day`, …) → **Autonomous Mode** detail;
|
|
46
|
+
- `state.json.selfRecursive.enabled` is true, or the invocation carries `--per-commit` / `--no-per-commit` → **Per-Commit Mode** detail.
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
{ "sessionPrefs": { "continueFromQueues": "never" } }
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
`PRODUCTION`/`DECISION`-classified items still surface (not auto-executed). The continuation runs the same alignment-checker + scope-auditor + independent-auditor wiring as the in-run iterate loop. Stop conditions: iterate-cap (25 autonomous / 5 classic), budget exhausted, PRODUCTION encountered, 5 consecutive iterate failures, explicit user pause. Surfaced in the run report's `## Queue continuation` section.
|
|
52
|
-
|
|
53
|
-
### Flag surface
|
|
54
|
-
|
|
55
|
-
| Invocation | Effect |
|
|
56
|
-
|---|---|
|
|
57
|
-
| `/build-loop:run "goal text"` | default mode, 2h budget, autonomous=true |
|
|
58
|
-
| `/build-loop:run --long "goal text"` | long mode, 8h budget |
|
|
59
|
-
| `/build-loop:run --budget 4h "goal text"` | custom budget (overrides `--long`) |
|
|
60
|
-
| `/build-loop:run --budget 30m "goal text"` | accepts `30s`, `30m`, `4h`, or bare integer seconds |
|
|
61
|
-
| `/build-loop:run --autonomous=false "goal text"` | classic single-pass; queue items become `followup/` |
|
|
62
|
-
| `/build-loop:run "overnight refactor of auth ..."` | keyword `overnight` → long mode, 8h |
|
|
63
|
-
|
|
64
|
-
**Flag precedence (strict, top wins):**
|
|
65
|
-
|
|
66
|
-
1. `--budget <duration>` — explicit duration always wins; mode tagged `custom`.
|
|
67
|
-
2. `--long` — sets mode `long`, budget 8h.
|
|
68
|
-
3. Keyword detection in goal text — only when `--long` not explicitly set.
|
|
69
|
-
4. Default — mode `default`, budget 2h, autonomous=true.
|
|
70
|
-
|
|
71
|
-
`--autonomous=false` is orthogonal: it can combine with any budget flag but disables the queue-drain loop entirely. With autonomous off, `--budget` still tracks wall-clock but the orchestrator runs classic Phase 1–6 once and reports.
|
|
72
|
-
|
|
73
|
-
### Keyword fallback
|
|
74
|
-
|
|
75
|
-
Case-insensitive whole-word match against the goal text (or `intent.update_intent`). Detection runs ONLY when `--long` is not explicit on the command line. The flag always wins over keyword inference.
|
|
76
|
-
|
|
77
|
-
| Keyword | Example phrasings |
|
|
78
|
-
|---|---|
|
|
79
|
-
| `long` | "long refactor of …" |
|
|
80
|
-
| `long-running` | "long-running migration" |
|
|
81
|
-
| `overnight` | "overnight build" |
|
|
82
|
-
| `large-scale` | "large-scale rewrite" |
|
|
83
|
-
| `multi-day` | "multi-day backfill" |
|
|
84
|
-
|
|
85
|
-
Keyword list is configurable via `.build-loop/config.json.autonomy.keywordsLong[]`. The default list above is hard-coded in the orchestrator.
|
|
86
|
-
|
|
87
|
-
### Budget tracking
|
|
88
|
-
|
|
89
|
-
The orchestrator writes `state.execution.budget` at autonomous-mode start:
|
|
90
|
-
|
|
91
|
-
```json
|
|
92
|
-
{
|
|
93
|
-
"mode": "default | long | custom",
|
|
94
|
-
"started_at": "<iso8601 UTC>",
|
|
95
|
-
"deadline_at": "<iso8601 UTC>",
|
|
96
|
-
"last_checkin_at": "<iso8601 UTC> | null",
|
|
97
|
-
"commits_since_push": 0,
|
|
98
|
-
"checkin_interval_pct": 50
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
`scripts/budget_check.py` reads this block at every iterate-loop entry, every commit, and every phase boundary, returning a routing envelope (`continue | checkin | finalize_and_stop`). The script is informational — exit 0 always; sub-5ms compute.
|
|
103
|
-
|
|
104
|
-
**Resume contract**: when a budget block exists and the run resumes via `--resume <run_id>`, the orchestrator MUST reuse the original `deadline_at`. A 2h budget that crashed at 1h59m does NOT get a fresh 2h. `scripts/resume_resolver.py._resolve_budget_on_resume()` is the single source of truth for this rule and surfaces the preserved budget under `budget_resume.preserve_deadline: true`.
|
|
105
|
-
|
|
106
|
-
### Iteration caps
|
|
107
|
-
|
|
108
|
-
| Mode | Per-build cap | Per-item cap |
|
|
109
|
-
|---|---|---|
|
|
110
|
-
| Classic (autonomous=false) | 5 | n/a |
|
|
111
|
-
| Autonomous default | 25 | 3 same-verdict |
|
|
112
|
-
| Autonomous long | 25 | 3 same-verdict |
|
|
113
|
-
|
|
114
|
-
`maxIterateAttemptsAutonomous` is configurable in `.build-loop/config.json.autonomy.maxIterateAttemptsAutonomous`.
|
|
115
|
-
|
|
116
|
-
### Question timeout (autonomous auto-decide)
|
|
117
|
-
|
|
118
|
-
In autonomous / `--long` mode a question that would otherwise block on the human auto-resolves if unanswered within a window, so an unattended run never stalls. When the orchestrator surfaces such a question it states a **recommended default** + a deadline; `scripts/question_timeout.py` is consulted (e.g. on a `ScheduleWakeup` resume) and returns `answered | take_default | wait`. On `take_default` the orchestrator takes the recommended option, records it to `state.execution.autonomousDefaults[]` + `auto-decision-capture`, continues, and lists every auto-decided question in the end-of-run readback for override (prefer the reversible option when deciding).
|
|
119
|
-
|
|
120
|
-
**Never auto-resolves — waits indefinitely:** production push, destructive/irreversible delete, and anything the autonomy gate verdicts `confirm`/`block` (gates #1–#2 in `agents/build-orchestrator.md`). Only reversible / `user_impact: major` decisions (gate #3) and steering clarifications time out — the single production gate is preserved.
|
|
121
|
-
|
|
122
|
-
Config (`.build-loop/config.json.autonomy`): `questionTimeoutMinutes` (default 10), `onTimeout` (`decide_default` default | `wait`).
|
|
123
|
-
|
|
124
|
-
### Per-Phase A constraint
|
|
125
|
-
|
|
126
|
-
Phase A (current ship) wires queue drain + alignment-check + time budget. **Pushes stay manual** — `scripts/autonomous_push.py` and the K-commit batch-push policy ship in Phase B. The `should_push_now` field returned by `budget_check.py` is informational in Phase A; the orchestrator surfaces it in check-ins but does not push autonomously yet.
|
|
127
|
-
|
|
128
|
-
## Per-Commit Mode (Self-Recursive Builds)
|
|
129
|
-
|
|
130
|
-
Per-commit mode splits a multi-commit build into one independent orchestrator dispatch per commit, so each commit reviews and lands cleanly before the next one starts. It activates automatically when the working directory IS the runtime — that is, when the user is editing the build-loop plugin itself (or any plugin whose runtime symlink points back to the working tree). It can also be explicitly opted into or out of via skill arguments.
|
|
131
|
-
|
|
132
|
-
### Detection
|
|
133
|
-
|
|
134
|
-
Phase 1 Assess writes `selfRecursive.enabled: true|false` to `.build-loop/state.json` (commit 1 wired this via `scripts/detect_self_recursive.py`). The skill body MUST read this field BEFORE deciding which dispatch shape to use. If the field is absent, treat it as `false`.
|
|
135
|
-
|
|
136
|
-
### Mode Resolution
|
|
137
|
-
|
|
138
|
-
| Skill arg | `selfRecursive` | Resulting mode |
|
|
139
|
-
|---|---|---|
|
|
140
|
-
| `--per-commit` (explicit) | either | per-commit |
|
|
141
|
-
| `--no-per-commit` (explicit) | either | single-orchestrator |
|
|
142
|
-
| (none) | true | per-commit (default for self-recursive) |
|
|
143
|
-
| (none) | false | single-orchestrator (today's behavior) |
|
|
144
|
-
|
|
145
|
-
Passing both `--per-commit` and `--no-per-commit` is a user error — fail loud with a one-line message naming the conflict and stop before any dispatch.
|
|
146
|
-
|
|
147
|
-
### Dispatch Contract (Per-Commit Mode)
|
|
148
|
-
|
|
149
|
-
1. **Plan first, dispatch many.** The skill body invokes a single planning orchestrator (Phase 1 Assess + Phase 2 Plan only). Its return must include a per-commit work list at `.build-loop/per-commit-plan.json` with this exact JSON shape:
|
|
150
|
-
|
|
151
|
-
```json
|
|
152
|
-
{
|
|
153
|
-
"run_id": "run_<UTC>_<hash>",
|
|
154
|
-
"commits": [
|
|
155
|
-
{
|
|
156
|
-
"id": "c1",
|
|
157
|
-
"subject": "feat(scripts): add foo helper",
|
|
158
|
-
"scope": "...",
|
|
159
|
-
"files_planned": ["scripts/foo.py", "tests/test_foo.py"],
|
|
160
|
-
"spec": "verbatim packet for the implementer orchestrator",
|
|
161
|
-
"depends_on": []
|
|
162
|
-
}
|
|
163
|
-
],
|
|
164
|
-
"branch": "feat/...",
|
|
165
|
-
"from_branch": "main"
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
2. **Per-commit orchestrator dispatch.** For each commit in the plan (respecting `depends_on`), the skill body dispatches a fresh `Agent(subagent_type="build-loop:build-orchestrator", ...)` carrying ONLY that commit's packet plus a `PER_COMMIT_DISPATCH: { commit_id, run_id, prior_commit_hashes }` prompt prefix. Each dispatched orchestrator runs Phase 3 Execute + Phase 4 Review for ITS commit only, then commits and returns. The dispatched orchestrator's behavior on the prefix is documented in `agents/build-orchestrator.md` §0a.
|
|
170
|
-
|
|
171
|
-
3. **Aggregate.** The skill body collects each orchestrator's return envelope and writes a final report combining all commits' results. On partial failure (commit N fails), do NOT dispatch downstream commits; retain `.build-loop/per-commit-plan.json` so a subsequent `/build-loop:run --resume` invocation can pick up where it stopped. **Parent-dispatch contract (GAP-1):** the dispatcher (this skill body) HAS the Agent tool, so it is the parent that owes the audit. For every returned envelope whose `auditor_status` is `not-run:parent-must-dispatch` or `cross-vendor-deferred`, the dispatcher MUST — before declaring that commit/run review-complete — dispatch `Agent(subagent_type="build-loop:independent-auditor")` on that commit's diff range, append the verdict to `.build-loop/judge-decisions.json`, and re-run `write_run_entry --scope build` so the review-completeness gate passes. A nested per-commit orchestrator cannot audit itself; the audit is the dispatcher's responsibility, not an optional step.
|
|
172
|
-
|
|
173
|
-
**Parent owes Phase 6 Learn + retrospective (E3).** A stop-early dispatch that never reaches Phase 4 Review-G can't run Phase 6 Learn or the post-push retro — so the dispatching parent owes them at close, under the same parent-dispatch contract as GAP-1 (not optional, name the owner at dispatch). Full contract: `agents/build-orchestrator.md` §Phase 4 A (E3 block).
|
|
174
|
-
|
|
175
|
-
### State.json schema
|
|
176
|
-
|
|
177
|
-
The per-commit dispatcher tracks its own progress under a `perCommit` block alongside the existing `execution` block:
|
|
178
|
-
|
|
179
|
-
```json
|
|
180
|
-
{
|
|
181
|
-
"perCommit": {
|
|
182
|
-
"enabled": true,
|
|
183
|
-
"mode_source": "self_recursive_default|explicit_flag|opt_out",
|
|
184
|
-
"plan_path": ".build-loop/per-commit-plan.json",
|
|
185
|
-
"completed": [{"commit_id": "c1", "hash": "abc123", "completed_at": "..."}],
|
|
186
|
-
"in_flight": "c2",
|
|
187
|
-
"queued": ["c3"]
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
M2's `execution.iterate_attempt` continues to track per-commit-orchestrator attempt counters (each dispatched orchestrator manages its own iterate counter) — do not duplicate iteration tracking inside `perCommit`.
|
|
48
|
+
Default behavior with none of those signals: classic single-pass Phase 1–6, 2h budget, autonomous queue-drain on. The end-of-run `issues/` then `backlog/` drain is a SHIPPED DEFAULT (2026-06-04), reversible per-repo via `.build-loop/config.json` `sessionPrefs.continueFromQueues: "never"`.
|
|
193
49
|
|
|
194
50
|
## Scope Check
|
|
195
51
|
|
|
@@ -357,13 +213,13 @@ Key steps: subagent-driven-development → model assignment (Sonnet default) →
|
|
|
357
213
|
|
|
358
214
|
## Phase 4: Review — Critic, Validate, Fact-Check, Simplify, Auto-Resolve, Report
|
|
359
215
|
|
|
360
|
-
Seven sub-steps run in order
|
|
216
|
+
Seven sub-steps run in order (A–G): Critic → Validate → Optimize (opt-in) → Fact-Check → Simplify → Auto-Resolve → Report. F (Auto-Resolve) drains non-destructive items via `scripts/autonomy_gate.py` (auto/warn/confirm/block routing). G (Report) is final-pass-only.
|
|
361
217
|
|
|
362
218
|
Key steps: independent-auditor (build scope) adversarial read → build-loop-owned UI validation when UI changed → code-based graders → live smoke gate → LLM judges → fact-checker + mock-scanner + architecture-rules in parallel → simplify → autonomy gate queue → final scorecard + run entry → **non-gating post-push retrospective dispatch** (`build-loop:retrospective-synthesizer` writes the 9-section `.build-loop/retrospectives/<date>/<run-id>.md` + ≤5-line summary surfaced inline; enforce-candidates land at `.build-loop/proposals/enforce-from-retro/` for human review — never auto-promoted; fire-and-continue, run-close is NOT delayed). On self-recursive runs, G appends `## Self-modifications (readback)` listing every self-modification attempted this run — file, what/why, gate verdict, additional-review finding — so the human sees results at the end without the loop stopping. Full spec in `agents/build-orchestrator.md` §G.
|
|
363
219
|
|
|
364
220
|
**Load `skills/build-loop/references/phase-4-review.md`** for sub-step details, gate matrices, routing rules, and the full Sub-step F Auto-Resolve protocol (all 4 verdict arms including `warn` exit-0 behavior).
|
|
365
221
|
|
|
366
|
-
**Independent commit auditor — boundary gate + dispatched judge.** Single consolidated auditor (2026-05-23 — replaces retired `commit-auditor` and earlier retired `sonnet-critic`). Two surfaces share the same context-gathering procedure and verdict taxonomy: (1) a PreToolUse Bash hook fires `scripts/audit_before_commit.py` on every `git commit` regardless of who initiates it (manual, Codex, build-loop, IDE) — deterministic packet-builder, hard-blocks (exit 2) on staged secrets and merge-conflict markers, bypass via `BUILDLOOP_AUDIT_BYPASS=1`; (2) the `independent-auditor` agent dispatches at Phase 3 chunk-close (chunk advisory) and Phase 4 Review-A (build scope) for LLM-grade judgment. Four verdicts: `yay (approve)` / `nay (reject)` / `suggest_correction` / `look_again`. **Auditor dispatch ladder (GAP-1):** a *nested* orchestrator (dispatched as a subagent, or per-commit mode) has no Agent tool and cannot dispatch the auditor — it walks `dispatched-agent → peer-host (rally / codex exec) → not-run:parent-must-dispatch`, records the chosen rung in `auditor_status`, and **never** lets inline self-reasoning masquerade as the independent auditor. A `not-run:parent-must-dispatch` run is not review-complete: the dispatching parent owes the audit before Report. Full reference: `skills/build-loop/references/independent-auditor.md` + `references/phase-4-review.md` §"Sub-step A" + `agents/independent-auditor.md`.
|
|
222
|
+
**Independent commit auditor — boundary gate + dispatched judge.** Single consolidated auditor (2026-05-23 — replaces retired `commit-auditor` and earlier retired `sonnet-critic`). Two surfaces share the same context-gathering procedure and verdict taxonomy: (1) a PreToolUse Bash hook fires `scripts/audit_before_commit.py` on every `git commit` regardless of who initiates it (manual, Codex, build-loop, IDE) — deterministic packet-builder, hard-blocks (exit 2) on staged secrets and merge-conflict markers, bypass via `BUILDLOOP_AUDIT_BYPASS=1`; (2) the `independent-auditor` agent dispatches at Phase 3 chunk-close (chunk advisory) and Phase 4 Review-A (build scope) for LLM-grade judgment. Four verdicts: `yay (approve)` / `nay (reject)` / `suggest_correction` / `look_again`. **Auditor dispatch ladder (GAP-1):** a *nested* orchestrator (dispatched as a subagent, or per-commit mode) has no Agent tool and cannot dispatch the auditor — it walks `dispatched-agent → peer-host (rally / codex exec) → not-run:parent-must-dispatch`, records the chosen rung in `auditor_status`, and **never** lets inline self-reasoning masquerade as the independent auditor. A `not-run:parent-must-dispatch` run is not review-complete: under the parent-dispatch contract the dispatching parent owes the audit before Report. Full reference: `skills/build-loop/references/independent-auditor.md` + `references/phase-4-review.md` §"Sub-step A" + `agents/independent-auditor.md`.
|
|
367
223
|
|
|
368
224
|
## Phase 5: Iterate — Fix Review Failures + UX Queue (up to 5x)
|
|
369
225
|
|
|
@@ -383,11 +239,11 @@ Key steps: recurring-pattern-detector (Haiku; reads `state.json.runs[]` AND `.bu
|
|
|
383
239
|
|
|
384
240
|
## Memory — Global and Project-Scoped
|
|
385
241
|
|
|
386
|
-
One consolidated long-term tree: `~/dev/git-folder/build-loop-memory/`. Project-specific durable memory lives under `projects/<slug>/...`; cross-project lessons/design/debugging/product memory lives in the matching top-level lane. Every build runs `scripts/context_bootstrap.py` at Phase 1 Assess, which reads
|
|
242
|
+
One consolidated long-term tree: `~/dev/git-folder/build-loop-memory/`. Project-specific durable memory lives under `projects/<slug>/...`; cross-project lessons/design/debugging/product memory lives in the matching top-level lane. Every build runs `scripts/context_bootstrap.py` at Phase 1 Assess, which reads the store-root `INDEX.md` first, then root/project `constitution.md` / `MEMORY.md` where present, canonical indexes/folders through `memory_facade`, repo-local `.build-loop/` context, Codex memory at `~/.codex/memories`, and best-effort Rally/coordination state when relevant. Live handoff state is written separately by `scripts/context_snapshot.py` under `.build-loop/context/`; snapshots are not durable memory unless Review-G promotes a reusable decision or lesson. Writes go to exactly one canonical memory lane based on scope. Legacy paths (`~/.build-loop/memory`, `.episodic/decisions`, and `build-loop-memory/decisions/<project>`) are migration/archive inputs only.
|
|
387
243
|
|
|
388
244
|
Routing rule: "Would this apply to a different project?" Yes → global. No → project. Ambiguous → ask the user once.
|
|
389
245
|
|
|
390
|
-
Append-only memory contract: (1) steering answers from `AskUserQuestion` append to `build-loop-memory/projects/<slug>/decisions/` immediately via
|
|
246
|
+
Append-only memory contract: (1) steering answers from `AskUserQuestion` append to `build-loop-memory/projects/<slug>/decisions/` immediately via the decision writer — do not let them die in context; (2) durable lessons/decisions are written when discovered, then deduped at Review-G; (3) every run appends a milestone at Review-G via `scripts/append_milestone.py` when warranted — the permanent progress record, never rewritten; (4) Phase 1 flags staleness when the latest memory update/milestone predates HEAD (`scripts/memory_staleness_check.py`). Full recall-optimized write protocol in `references/memory.md` and `build-loop-memory/references/2026-06-11-memory-discipline-prompt.md` (`version: 2026-06-11.1`).
|
|
391
247
|
|
|
392
248
|
**Load `skills/build-loop/references/memory.md`** for the full routing rule, write timing, read timing, and memory type taxonomy.
|
|
393
249
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
|
|
2
|
+
|
|
3
|
+
# Advisor dispatch ladder (Phase 2 plan synthesis at Frontier)
|
|
4
|
+
|
|
5
|
+
The Advisor (Fable) is the Frontier standing role that **authors and re-plans** the Phase 2 plan synthesis. Generating a plan is harder than evaluating one, so the deepest reasoning pays here — but the Advisor is **pull-based**: summoned only when stakes-gating trips, not every run. This ladder enforces that the plan is authored at Frontier *when it matters*, without breaking the runs where it doesn't.
|
|
6
|
+
|
|
7
|
+
It deliberately **mirrors the GAP-1 independent-auditor ladder** (`phase-4-review.md` §"Sub-step A"). Same shape, same honesty discipline, an analogous `advisor_status` field. If you know that ladder, you know this one.
|
|
8
|
+
|
|
9
|
+
## When the ladder is evaluated (stakes-gating)
|
|
10
|
+
|
|
11
|
+
The orchestrator walks this ladder at the Phase 2 plan-synthesis step **only when** any of these objective triggers fire:
|
|
12
|
+
|
|
13
|
+
- `state.json.synthesisDensity > 5` (synthesis-dense plan), or
|
|
14
|
+
- `triggers.riskSurfaceChange` (security/persistence/runtime/deploy/trust boundary), or
|
|
15
|
+
- `stakes >= medium` (from the commander's-intent posture / charter), or
|
|
16
|
+
- an explicit `dispatch_tier: frontier` on any work item in the draft plan.
|
|
17
|
+
|
|
18
|
+
If none trips, the ladder is skipped entirely — the orchestrator synthesizes the plan inline as today (most runs stay single-context; this respects the multi-agent-handoff risk by not decomposing more than needed). **Triggers are objective signals, never self-reported confidence** (models are systematically overconfident).
|
|
19
|
+
|
|
20
|
+
## The four rungs (record `advisor_status` honestly)
|
|
21
|
+
|
|
22
|
+
Dispatching the Advisor via `Agent(subagent_type="build-loop:advisor")` requires the Agent tool. A *nested* orchestrator (dispatched as a subagent — Mode B — or running per-commit mode) does **not** have the Agent tool, because the harness blocks sub-subagents. Walk the ladder and record `advisor_status`:
|
|
23
|
+
|
|
24
|
+
1. **Rung 0 — own context already Frontier** (the orchestrator is itself running on Fable, e.g. `/build-loop:run` while the session model is Fable): **synthesize the plan inline** — it is *already* Frontier, no handoff needed. → `advisor_status: inline-frontier`. Zero added cost.
|
|
25
|
+
|
|
26
|
+
2. **Rung 1 — Agent tool present** (top-level / Mode A, own context not already Frontier): **dispatch the Fable Advisor** (`Agent(subagent_type="build-loop:advisor")`) to author/re-plan, then verify via plan-critic + scope-auditor. → `advisor_status: ran:dispatched-agent`.
|
|
27
|
+
|
|
28
|
+
3. **Rung 2 — no Agent tool, peer host reachable** (nested Mode B, but a peer host — rally channel / `codex exec` — can execute; reachable because the orchestrator retains Bash even when nested): **run the Advisor as a peer process** over the same channel the cross-vendor reviewer uses. Reconcile the peer's plan + envelope into the plan artifact. → `advisor_status: ran:peer-host(<host>)`. Prefer this over the fallback whenever a peer host can execute (fresh-context synthesis is plausibly *higher quality*, not merely cheaper — see "Quality, not only cost" below).
|
|
29
|
+
|
|
30
|
+
4. **Rung 3 — none reachable** (no Agent tool, no peer host): **synthesize inline on the orchestrator's own model (Opus)**, labeled honestly. → `advisor_status: fallback:inline-opus`.
|
|
31
|
+
|
|
32
|
+
## Non-breaking guarantee
|
|
33
|
+
|
|
34
|
+
**Rung 3 IS today's behavior** — the orchestrator synthesizing the plan inline on Opus. The floor of this ladder equals the current state; it is strictly better whenever a dispatch path (Rung 1/2) or an already-Frontier context (Rung 0) is reachable. The handoff cost fires *only* in Rung 1/2 — i.e., only when the active context isn't already Frontier — so you pay it exactly where it buys an upgrade and never where planning is already Frontier. Worst case equals current; there is no regression path.
|
|
35
|
+
|
|
36
|
+
## Quality, not only cost
|
|
37
|
+
|
|
38
|
+
Dispatch is a **quality lever**, not just a cost knob. Context-separation evidence (⚠️ 2026 cross-context-review lead, directionally consistent with the corroborated self-correction literature: correction needs *external* feedback; intrinsic self-correction degrades accuracy) indicates synthesis in a *fresh* context beats same-session work. So Rungs 1/2 (fresh-context dispatch) are plausibly *higher quality* than Rung 0/3 inline — inline is a genuine quality compromise, taken only when dispatch is unreachable. The Advisor is a **separate agent**, never the executor self-reflecting.
|
|
39
|
+
|
|
40
|
+
## Ledger row per Advisor action (the instrument)
|
|
41
|
+
|
|
42
|
+
The orchestrator (single writer) appends one row to `.build-loop/agent-ledger.jsonl` per Advisor action via `scripts/agent_ledger.py`:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
action: author | re-plan
|
|
46
|
+
agent: advisor · tier: frontier · model: <resolved id (fable / gpt-5.x / …)>
|
|
47
|
+
rung: 0|1|2|3 · status: pass|fail|partial · trigger: <synthesisDensity>5 | riskSurfaceChange | stakes>=medium | dispatch_tier:frontier>
|
|
48
|
+
refs: {output: docs/plans/<slug>.md, input: <prior plan / failure evidence>}
|
|
49
|
+
note: <on re-plan: failure evidence + why a retry is justified>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This closes the unmeasured quality-delta: the A/B test reads the ledger to compare plan outcomes by `rung`/`model` and find whether Frontier planning actually pays.
|
|
53
|
+
|
|
54
|
+
## Re-plan mode (the remediation contract, v1)
|
|
55
|
+
|
|
56
|
+
When the orchestrator diagnoses a **planning miss** during Iterate (the plan itself no longer fits, on an objective signal — test/build failure, auditor verdict, retry-count, scope breach), it re-enters this ladder with `action: re-plan`. The Advisor reads the **failure evidence + the diff vs the current plan**, diagnoses planning-miss vs execution-miss (*its* Frontier call, never the failing executor's self-report), and on a planning miss issues **corrected instructions** — a diff against the prior plan + the evidence — so execution resumes at the cheap tier on a sound plan.
|
|
57
|
+
|
|
58
|
+
**v1 scope:** author + re-plan only. The **take-over-execution rung** (the Advisor executing a chunk directly) and **proactive mid-run checkpoint check-ins** are **v2** — land after the A/B confirms the core pays.
|
|
59
|
+
|
|
60
|
+
## Always verified — never self-certifying
|
|
61
|
+
|
|
62
|
+
The Advisor's authored/re-planned plan is checked by the existing Frontier critics before any implementer runs: `plan_verify.py` (deterministic) → `plan-critic` (reasoning; **blocking on the same stakes triggers**, advisory otherwise) → `scope-auditor` at the Plan→Execute boundary. Frontier-authored output does not get a pass on review. Keep the verification panel multi-specialist — do not collapse it to a single judge.
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
<!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> -->
|
|
2
|
+
<!-- SPDX-License-Identifier: Apache-2.0 -->
|
|
3
|
+
# Autonomous Mode + Per-Commit Mode (conditional detail)
|
|
4
|
+
|
|
5
|
+
Extracted from `SKILL.md` (WP-A, 2026-06-09): both modes are conditional — their
|
|
6
|
+
tables and contracts are load-bearing only when the mode is active, yet they
|
|
7
|
+
loaded in every session. The SKILL.md body now carries a one-line pointer to
|
|
8
|
+
each; the full detail lives here and loads on demand.
|
|
9
|
+
|
|
10
|
+
## Autonomous Mode (Queue-Drain Loop)
|
|
11
|
+
|
|
12
|
+
Autonomous mode generalizes Phase 5 Iterate into a self-replenishing worker that drains its own `ux-queue/` + `issues/` + `proposals/`, alignment-checks each item against the original intent, executes the aligned subset, and commits in batches until the queue is empty or the wall-clock budget elapses. Default since this mode shipped (`--autonomous=false` opts back to classic one-pass).
|
|
13
|
+
|
|
14
|
+
**End-of-run backlog/issues drain — SHIPPED DEFAULT 2026-06-04**: every run now auto-drains `.build-loop/issues/` then `.build-loop/backlog/` at end-of-thread without asking. Reversible per-repo via `.build-loop/config.json`:
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{ "sessionPrefs": { "continueFromQueues": "never" } }
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`PRODUCTION`/`DECISION`-classified items still surface (not auto-executed). The continuation runs the same alignment-checker + scope-auditor + independent-auditor wiring as the in-run iterate loop. Stop conditions: iterate-cap (25 autonomous / 5 classic), budget exhausted, PRODUCTION encountered, 5 consecutive iterate failures, explicit user pause. Surfaced in the run report's `## Queue continuation` section.
|
|
21
|
+
|
|
22
|
+
### Flag surface
|
|
23
|
+
|
|
24
|
+
| Invocation | Effect |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `/build-loop:run "goal text"` | default mode, 2h budget, autonomous=true |
|
|
27
|
+
| `/build-loop:run --long "goal text"` | long mode, 8h budget |
|
|
28
|
+
| `/build-loop:run --budget 4h "goal text"` | custom budget (overrides `--long`) |
|
|
29
|
+
| `/build-loop:run --budget 30m "goal text"` | accepts `30s`, `30m`, `4h`, or bare integer seconds |
|
|
30
|
+
| `/build-loop:run --autonomous=false "goal text"` | classic single-pass; queue items become `followup/` |
|
|
31
|
+
| `/build-loop:run "overnight refactor of auth ..."` | keyword `overnight` → long mode, 8h |
|
|
32
|
+
|
|
33
|
+
**Flag precedence (strict, top wins):**
|
|
34
|
+
|
|
35
|
+
1. `--budget <duration>` — explicit duration always wins; mode tagged `custom`.
|
|
36
|
+
2. `--long` — sets mode `long`, budget 8h.
|
|
37
|
+
3. Keyword detection in goal text — only when `--long` not explicitly set.
|
|
38
|
+
4. Default — mode `default`, budget 2h, autonomous=true.
|
|
39
|
+
|
|
40
|
+
`--autonomous=false` is orthogonal: it can combine with any budget flag but disables the queue-drain loop entirely. With autonomous off, `--budget` still tracks wall-clock but the orchestrator runs classic Phase 1–6 once and reports.
|
|
41
|
+
|
|
42
|
+
### Keyword fallback
|
|
43
|
+
|
|
44
|
+
Case-insensitive whole-word match against the goal text (or `intent.update_intent`). Detection runs ONLY when `--long` is not explicit on the command line. The flag always wins over keyword inference.
|
|
45
|
+
|
|
46
|
+
| Keyword | Example phrasings |
|
|
47
|
+
|---|---|
|
|
48
|
+
| `long` | "long refactor of …" |
|
|
49
|
+
| `long-running` | "long-running migration" |
|
|
50
|
+
| `overnight` | "overnight build" |
|
|
51
|
+
| `large-scale` | "large-scale rewrite" |
|
|
52
|
+
| `multi-day` | "multi-day backfill" |
|
|
53
|
+
|
|
54
|
+
Keyword list is configurable via `.build-loop/config.json.autonomy.keywordsLong[]`. The default list above is hard-coded in the orchestrator.
|
|
55
|
+
|
|
56
|
+
### Budget tracking
|
|
57
|
+
|
|
58
|
+
The orchestrator writes `state.execution.budget` at autonomous-mode start:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"mode": "default | long | custom",
|
|
63
|
+
"started_at": "<iso8601 UTC>",
|
|
64
|
+
"deadline_at": "<iso8601 UTC>",
|
|
65
|
+
"last_checkin_at": "<iso8601 UTC> | null",
|
|
66
|
+
"commits_since_push": 0,
|
|
67
|
+
"checkin_interval_pct": 50
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`scripts/budget_check.py` reads this block at every iterate-loop entry, every commit, and every phase boundary, returning a routing envelope (`continue | checkin | finalize_and_stop`). The script is informational — exit 0 always; sub-5ms compute.
|
|
72
|
+
|
|
73
|
+
**Resume contract**: when a budget block exists and the run resumes via `--resume <run_id>`, the orchestrator MUST reuse the original `deadline_at`. A 2h budget that crashed at 1h59m does NOT get a fresh 2h. `scripts/resume_resolver.py._resolve_budget_on_resume()` is the single source of truth for this rule and surfaces the preserved budget under `budget_resume.preserve_deadline: true`.
|
|
74
|
+
|
|
75
|
+
### Iteration caps
|
|
76
|
+
|
|
77
|
+
| Mode | Per-build cap | Per-item cap |
|
|
78
|
+
|---|---|---|
|
|
79
|
+
| Classic (autonomous=false) | 5 | n/a |
|
|
80
|
+
| Autonomous default | 25 | 3 same-verdict |
|
|
81
|
+
| Autonomous long | 25 | 3 same-verdict |
|
|
82
|
+
|
|
83
|
+
`maxIterateAttemptsAutonomous` is configurable in `.build-loop/config.json.autonomy.maxIterateAttemptsAutonomous`.
|
|
84
|
+
|
|
85
|
+
### Question timeout (autonomous auto-decide)
|
|
86
|
+
|
|
87
|
+
In autonomous / `--long` mode a question that would otherwise block on the human auto-resolves if unanswered within a window, so an unattended run never stalls. When the orchestrator surfaces such a question it states a **recommended default** + a deadline; `scripts/question_timeout.py` is consulted (e.g. on a `ScheduleWakeup` resume) and returns `answered | take_default | wait`. On `take_default` the orchestrator takes the recommended option, records it to `state.execution.autonomousDefaults[]` + `auto-decision-capture`, continues, and lists every auto-decided question in the end-of-run readback for override (prefer the reversible option when deciding).
|
|
88
|
+
|
|
89
|
+
**Never auto-resolves — waits indefinitely:** production push, destructive/irreversible delete, and anything the autonomy gate verdicts `confirm`/`block` (gates #1–#2 in `agents/build-orchestrator.md`). Only reversible / `user_impact: major` decisions (gate #3) and steering clarifications time out — the single production gate is preserved.
|
|
90
|
+
|
|
91
|
+
Config (`.build-loop/config.json.autonomy`): `questionTimeoutMinutes` (default 10), `onTimeout` (`decide_default` default | `wait`).
|
|
92
|
+
|
|
93
|
+
### Per-Phase A constraint
|
|
94
|
+
|
|
95
|
+
Phase A (current ship) wires queue drain + alignment-check + time budget. **Pushes stay manual** — `scripts/autonomous_push.py` and the K-commit batch-push policy ship in Phase B. The `should_push_now` field returned by `budget_check.py` is informational in Phase A; the orchestrator surfaces it in check-ins but does not push autonomously yet.
|
|
96
|
+
|
|
97
|
+
## Per-Commit Mode (Self-Recursive Builds)
|
|
98
|
+
|
|
99
|
+
Per-commit mode splits a multi-commit build into one independent orchestrator dispatch per commit, so each commit reviews and lands cleanly before the next one starts. It activates automatically when the working directory IS the runtime — that is, when the user is editing the build-loop plugin itself (or any plugin whose runtime symlink points back to the working tree). It can also be explicitly opted into or out of via skill arguments.
|
|
100
|
+
|
|
101
|
+
### Detection
|
|
102
|
+
|
|
103
|
+
Phase 1 Assess writes `selfRecursive.enabled: true|false` to `.build-loop/state.json` (commit 1 wired this via `scripts/detect_self_recursive.py`). The skill body MUST read this field BEFORE deciding which dispatch shape to use. If the field is absent, treat it as `false`.
|
|
104
|
+
|
|
105
|
+
### Mode Resolution
|
|
106
|
+
|
|
107
|
+
| Skill arg | `selfRecursive` | Resulting mode |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| `--per-commit` (explicit) | either | per-commit |
|
|
110
|
+
| `--no-per-commit` (explicit) | either | single-orchestrator |
|
|
111
|
+
| (none) | true | per-commit (default for self-recursive) |
|
|
112
|
+
| (none) | false | single-orchestrator (today's behavior) |
|
|
113
|
+
|
|
114
|
+
Passing both `--per-commit` and `--no-per-commit` is a user error — fail loud with a one-line message naming the conflict and stop before any dispatch.
|
|
115
|
+
|
|
116
|
+
### Dispatch Contract (Per-Commit Mode)
|
|
117
|
+
|
|
118
|
+
1. **Plan first, dispatch many.** The skill body invokes a single planning orchestrator (Phase 1 Assess + Phase 2 Plan only). Its return must include a per-commit work list at `.build-loop/per-commit-plan.json` with this exact JSON shape:
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"run_id": "run_<UTC>_<hash>",
|
|
123
|
+
"commits": [
|
|
124
|
+
{
|
|
125
|
+
"id": "c1",
|
|
126
|
+
"subject": "feat(scripts): add foo helper",
|
|
127
|
+
"scope": "...",
|
|
128
|
+
"files_planned": ["scripts/foo.py", "tests/test_foo.py"],
|
|
129
|
+
"spec": "verbatim packet for the implementer orchestrator",
|
|
130
|
+
"depends_on": []
|
|
131
|
+
}
|
|
132
|
+
],
|
|
133
|
+
"branch": "feat/...",
|
|
134
|
+
"from_branch": "main"
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
2. **Per-commit orchestrator dispatch.** For each commit in the plan (respecting `depends_on`), the skill body dispatches a fresh `Agent(subagent_type="build-loop:build-orchestrator", ...)` carrying ONLY that commit's packet plus a `PER_COMMIT_DISPATCH: { commit_id, run_id, prior_commit_hashes }` prompt prefix. Each dispatched orchestrator runs Phase 3 Execute + Phase 4 Review for ITS commit only, then commits and returns. The dispatched orchestrator's behavior on the prefix is documented in `agents/build-orchestrator.md` §0a.
|
|
139
|
+
|
|
140
|
+
3. **Aggregate.** The skill body collects each orchestrator's return envelope and writes a final report combining all commits' results. On partial failure (commit N fails), do NOT dispatch downstream commits; retain `.build-loop/per-commit-plan.json` so a subsequent `/build-loop:run --resume` invocation can pick up where it stopped. **Parent-dispatch contract (GAP-1):** the dispatcher (this skill body) HAS the Agent tool, so it is the parent that owes the audit. For every returned envelope whose `auditor_status` is `not-run:parent-must-dispatch` or `cross-vendor-deferred`, the dispatcher MUST — before declaring that commit/run review-complete — dispatch `Agent(subagent_type="build-loop:independent-auditor")` on that commit's diff range, append the verdict to `.build-loop/judge-decisions.json`, and re-run `write_run_entry --scope build` so the review-completeness gate passes. A nested per-commit orchestrator cannot audit itself; the audit is the dispatcher's responsibility, not an optional step.
|
|
141
|
+
|
|
142
|
+
**Parent owes Phase 6 Learn + retrospective (E3).** A stop-early dispatch that never reaches Phase 4 Review-G can't run Phase 6 Learn or the post-push retro — so the dispatching parent owes them at close, under the same parent-dispatch contract as GAP-1 (not optional, name the owner at dispatch). Full contract: `agents/build-orchestrator.md` §Phase 4 A (E3 block).
|
|
143
|
+
|
|
144
|
+
### State.json schema
|
|
145
|
+
|
|
146
|
+
The per-commit dispatcher tracks its own progress under a `perCommit` block alongside the existing `execution` block:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"perCommit": {
|
|
151
|
+
"enabled": true,
|
|
152
|
+
"mode_source": "self_recursive_default|explicit_flag|opt_out",
|
|
153
|
+
"plan_path": ".build-loop/per-commit-plan.json",
|
|
154
|
+
"completed": [{"commit_id": "c1", "hash": "abc123", "completed_at": "..."}],
|
|
155
|
+
"in_flight": "c2",
|
|
156
|
+
"queued": ["c3"]
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
M2's `execution.iterate_attempt` continues to track per-commit-orchestrator attempt counters (each dispatched orchestrator manages its own iterate counter) — do not duplicate iteration tracking inside `perCommit`.
|
|
@@ -16,7 +16,8 @@ Phase 1 runs `node ${CLAUDE_PLUGIN_ROOT}/skills/build-loop/detect-plugins.mjs` a
|
|
|
16
16
|
|-------|---------|----------|
|
|
17
17
|
| `writing-plans` | Phase 2 (Plan) | Write a structured plan directly: goal, tasks with exact file paths, dependency order, test commands |
|
|
18
18
|
| `subagent-driven-development` | Phase 3 (Execute) | Dispatch parallel agents manually using the host's available delegation tool for independent file groups |
|
|
19
|
-
| `verification-before-completion` | Phase 4 sub-step G (Report) | Run all test/build/lint commands and confirm output before claiming completion |
|
|
19
|
+
| `verification-before-completion` | Phase 4 sub-step G (Report) | Run all test/build/lint commands and confirm output before claiming completion. For app/UI changes this is NOT sufficient alone — also run the runtime UI⇄source-of-truth parity check (`runtime-parity-verification`); compile-green and a screenshot do not prove the running flow works |
|
|
20
|
+
| `runtime-parity-verification` | Phase 4 Review-B + Phase 5 Iterate (any `uiTarget != null` or user-visible flow) | Cross-check the rendered/queryable UI against the authoritative backend (DB/API/daemon/tool-state), screen-independently, and keep a validated per-repo smoke. Catches the "action does nothing / not showing / shows empty despite real data / stale projection" class. Drivers: web `ui-validator`; macOS `native-ax-driver` / IBR `scan_macos`; iOS `idb`; agent = tool-result vs rendered output. Reference smoke: easy-terminal `tools/smoke_launch.py` |
|
|
20
21
|
| `simplify` (slash: `/simplify`) | Phase 4 sub-step E (Simplify) | Self-review the diff: remove scaffolding, inline single-use helpers, delete dead branches |
|
|
21
22
|
| `complexity_detector.py` (accelerator, not a gate) | Phase 4 sub-step E (Simplify) | Diff-scoped stdlib-AST hotspot detector for changed Python; surfaces high-severity hotspots for a simpler rewrite, apply-vs-advise via existing Review-B + independent-auditor. Optional Python aid — the default Simplify pass reasons over the diff language-agnostically (see `phase-4-review.md` §"Sub-step E: Simplify") |
|
|
22
23
|
| `build-loop:self-improve` | Phase 6 (Learn) | Scan recent runs for recurring patterns, auto-draft experimental skills/agents with A/B tracking, notify user for keep/remove decisions |
|
|
@@ -80,7 +81,7 @@ Tie-breaker: if signals are mixed (an Apple project with both `ios/` and a macOS
|
|
|
80
81
|
|
|
81
82
|
**Migration source**: if `.replit` / `replit.nix` present → `migrationSource: "replit"`. Lovable / Bolt / v0 export markers (e.g. `lovable.config`, `bolt.config`, `v0.dev` in comments) → corresponding source. `replit-migrate` skills generalize — load `migration-scan` for any of the above, override hints as needed.
|
|
82
83
|
|
|
83
|
-
**Apple deploy**: when `platform: "apple"` AND goal includes "deploy", "TestFlight", or "App Store" → Phase 7/8 invoke `apple-dev` deploy flow using ASC creds
|
|
84
|
+
**Apple deploy**: when `platform: "apple"` AND goal includes "deploy", "TestFlight", or "App Store" → Phase 7/8 invoke `apple-dev` deploy flow using ASC creds from your harness memory store (e.g. `~/.claude/projects/<project-slug>/memory/reference_asc_credentials.md`). Apply deployment policy first: TestFlight/App Store Connect upload/export defaults to `auto`; App Store production release/submission defaults to `confirm`.
|
|
84
85
|
|
|
85
86
|
**Web deploy verify**: fires when `.vercel/project.json` or `vercel.json` is present AND the build performed a push/deploy → Phase 4 Review-B invokes `scripts/verify_deploy.py` (preferred-tier upgrade: Vercel MCP only if the user has added it to `.mcp.json`). Infra failures return `skipped`, never block the build.
|
|
86
87
|
|
|
@@ -175,7 +176,7 @@ If Phase 1 detects that the task touches plugin components, Phase 3 must map eac
|
|
|
175
176
|
|
|
176
177
|
| Source | When | How |
|
|
177
178
|
|---|---|---|
|
|
178
|
-
| `/cookbook` | Claude API patterns: tool calling, PTC, code execution, Agent SDK, RAG, thinking, structured output, batch, caching | Invoke `/cookbook` or read `~/.claude/projects
|
|
179
|
+
| `/cookbook` | Claude API patterns: tool calling, PTC, code execution, Agent SDK, RAG, thinking, structured output, batch, caching | Invoke `/cookbook` or read `reference_claude_cookbook.md` from your harness memory store (`~/.claude/projects/<project-slug>/memory/`) |
|
|
179
180
|
| `RossLabs-AI-Toolkit/LESSONS-LEARNED.md` | Any plugin work | Read during Phase 1 ASSESS |
|
|
180
181
|
| `context7` MCP | Any library/framework use | `query-docs` / `resolve-library-id` — do NOT code from training data |
|
|
181
182
|
| `research` skill | Factual claims, pricing, versions | Run `scripts/research_trigger.py` first; T1 official docs → T4 forums; 2-source minimum |
|
|
@@ -70,6 +70,14 @@ Prefer explicit prompt packets over full context forks. Use full context only wh
|
|
|
70
70
|
|
|
71
71
|
Shared reads should happen once in the lead session, then be condensed into worker prompts. This keeps workers focused and reduces contradictory interpretations.
|
|
72
72
|
|
|
73
|
+
### Prompt Cache Discipline
|
|
74
|
+
|
|
75
|
+
OpenAI prompt caching is automatic, so Build Loop cannot call the cache directly from Codex. The lever the Codex adapter controls is prompt shape: keep the reusable prefix stable, and move volatile task state later.
|
|
76
|
+
|
|
77
|
+
For Codex CLI and Codex app runs, put reusable role rules, output contracts, validation expectations, and ownership schema before task-specific facts. Put Rally state, timestamps, command output, diffs, browser comments, thread IDs, worktree metadata, current claims, and task IDs after the stable contract.
|
|
78
|
+
|
|
79
|
+
Do not reorder stable sections between worker prompts. Monitoring cached-token counters only detects prefix churn; the improvement comes from preserving the prefix and reducing noisy context before dispatch.
|
|
80
|
+
|
|
73
81
|
## Parallel Pattern
|
|
74
82
|
|
|
75
83
|
1. Lead creates the plan and identifies parallel-safe groups.
|
|
@@ -100,7 +100,7 @@ explicit extraction edges:
|
|
|
100
100
|
|
|
101
101
|
| Future plugin | Embedded namespace | Build-loop compatibility entrypoints |
|
|
102
102
|
|---|---|---|
|
|
103
|
-
| `agent-rally-point` | `scripts/rally_point/**` | `scripts/agent_rally.py`, `commands/
|
|
103
|
+
| `agent-rally-point` | `scripts/rally_point/**` | `scripts/agent_rally.py`, `commands/rally-point.md`, `hooks/*rally-point.sh`, `scripts/coordination_status.py`, `scripts/coordination_rally.py`, `scripts/coordination_bootstrap.py` |
|
|
104
104
|
| `agent-rally-watcher` | `scripts/agent_rally_watcher/**` | `scripts/coordination_watch.py` |
|
|
105
105
|
|
|
106
106
|
The machine-readable contract lives at
|
|
@@ -17,6 +17,65 @@ Every build starts by capturing:
|
|
|
17
17
|
|
|
18
18
|
Write the result to `.build-loop/intent.md` and mirror the compact version into `.build-loop/state.json.intent`.
|
|
19
19
|
|
|
20
|
+
### Commander's-intent posture (WP-F, all OPTIONAL — LLM-inferred, confirm-on-ambiguity)
|
|
21
|
+
|
|
22
|
+
North Star captures who/what; **posture** captures the tradeoff stance that drives
|
|
23
|
+
autonomous forks when the agent loses comms (the Marine-Corps commander's-intent
|
|
24
|
+
analog: purpose + key tasks + end state, so a subordinate who can't ask still
|
|
25
|
+
chooses correctly). A walkie-talkie app for generals-on-ops, for kids, and for
|
|
26
|
+
traders share North Star *fields* but differ entirely in *what to optimize when
|
|
27
|
+
forced to choose*. All fields are OPTIONAL and LLM-inferred from the ask; confirm
|
|
28
|
+
only on genuine ambiguity (reuse the restatement protocol — never `AskUserQuestion`,
|
|
29
|
+
never a gate). Mirror into `state.json.intent.posture`.
|
|
30
|
+
|
|
31
|
+
- **audience** + **stakes** — one line each (who the change serves; what a failure
|
|
32
|
+
costs). `stakes` ∈ {low, medium, high}.
|
|
33
|
+
- **priority_order** — the ranked tie-breaker the agent applies when two viable
|
|
34
|
+
paths conflict. FIXED VOCAB (ordered subset of
|
|
35
|
+
`security / reliability / speed / cost / simplicity / polish`) plus a free-text
|
|
36
|
+
`notes` escape for expressiveness. The fixed vocab aids weak-LLM recall; `notes`
|
|
37
|
+
carries anything the vocab can't.
|
|
38
|
+
- **acceptable_tradeoffs** — what is OK to cut under pressure.
|
|
39
|
+
- **non_goals** — what is never cut. At `stakes: high`, a `non_goals` entry that
|
|
40
|
+
names a REAL risk is a candidate to **graduate to a constitution invariant** — but
|
|
41
|
+
only once it is **promoted into the project constitution** (`projects/<slug>/constitution.md`),
|
|
42
|
+
where the LLM enforces it as a hard line. Until promoted, it stays advisory like the
|
|
43
|
+
rest of the posture. There is no separate deterministic gate that reads `non_goals`
|
|
44
|
+
directly (`grep non_goals scripts/` is intentionally empty); enforcement rides the
|
|
45
|
+
constitution, not a parallel mechanism. See the tiered charter below.
|
|
46
|
+
|
|
47
|
+
`priority_order` wires into the `alignment-checker` as the Phase-2-fork and
|
|
48
|
+
Phase-5-queue-drain tie-breaker: not just "matches intent?" but "which viable path
|
|
49
|
+
does THIS user's priority order prefer?" — advisory data the LLM weighs, never a gate.
|
|
50
|
+
|
|
51
|
+
### Tiered intent — `stakes` is the depth dial (WP-F/F2)
|
|
52
|
+
|
|
53
|
+
- **Per-run intent** (ephemeral, `.build-loop/intent.md`): restated ask + this
|
|
54
|
+
change's posture. Unchanged lifecycle.
|
|
55
|
+
- **Project charter** (persistent): stable North Star + posture + invariants + key
|
|
56
|
+
architecture decisions. ACCRETES via promotion — a fact promotes to durable when
|
|
57
|
+
user-confirmed OR stable/unchallenged across N runs; stays `inferred` until then;
|
|
58
|
+
carries the falsifier that would unseat it (doctrine rule 8). Storage + sync:
|
|
59
|
+
`scripts/charter.py` (canonical `build-loop-memory/projects/<slug>/charter.md`;
|
|
60
|
+
repo mirror `.build-loop/charter.md` with a `canonical:` pointer + content hash;
|
|
61
|
+
one writer = the run, from canonical; user hand-edit of the mirror promotes to
|
|
62
|
+
canonical `authored_by: user` on next run via hash-mismatch detection).
|
|
63
|
+
- **Depth scales by `stakes`**: low → intent line only (skills/agents/toys — do NOT
|
|
64
|
+
force a charter, that's the anti-pattern); medium → thin charter (web/mobile);
|
|
65
|
+
high → full charter, and risk-naming `non_goals` become candidates to promote into
|
|
66
|
+
the constitution as invariants (where the LLM enforces them). The promotion is the
|
|
67
|
+
enforcement; no `non_goals`-specific gate exists outside the constitution.
|
|
68
|
+
- **PRD stance**: opt-in upfront via `start-prd`; accretion is the default; never
|
|
69
|
+
required. A PRD, when present, PREFILLS the charter richer — input, not a gate.
|
|
70
|
+
|
|
71
|
+
Enforcement philosophy (binding): all advisory. The one stronger-than-advisory path
|
|
72
|
+
is **constitution promotion** — a risk-naming `non_goals` at `stakes: high` graduates
|
|
73
|
+
to a hard invariant only when it is written into `projects/<slug>/constitution.md`,
|
|
74
|
+
which the LLM treats as a binding line. Per `feedback_deterministic_only_for_known_risks` —
|
|
75
|
+
posture/charter depth is the dial; the LLM weighs, never a gate. The constitution, not
|
|
76
|
+
a `non_goals`-specific script, carries any graduated invariant (no dormant determinism
|
|
77
|
+
claim — there is no `non_goals` enforcement code to wire up).
|
|
78
|
+
|
|
20
79
|
## Intent restatement protocol (always-on)
|
|
21
80
|
|
|
22
81
|
Run this protocol on every build, judged by the orchestrator LLM — never a regex, never a detector script, never a binary gate. Depth scales with ambiguity, not a threshold. The behavior is intrinsic to Phase 1; no separate skill, script, or routing step gates it.
|
|
@@ -73,10 +132,38 @@ Mirror the result to `.build-loop/state.json.intent`:
|
|
|
73
132
|
"restated_intent": "<one sentence>",
|
|
74
133
|
"approach_options": ["<label>", "<label>"], // optional; empty when Step A alone fired
|
|
75
134
|
"assumptions": ["<line>", "<line>"], // optional; empty when no leaps were made
|
|
76
|
-
"confidence": "high" | "medium" | "low"
|
|
135
|
+
"confidence": "high" | "medium" | "low", // LLM judgment, not a script
|
|
136
|
+
"run_id": "<current run_id>" // Step E: the run this intent was written for
|
|
77
137
|
}
|
|
78
138
|
```
|
|
79
139
|
|
|
140
|
+
### Step E — Run-id freshness stamp (per-run staleness guard)
|
|
141
|
+
|
|
142
|
+
`intent.md` lives in `.build-loop/` and survives across runs in the same workdir, so a
|
|
143
|
+
resumed or back-to-back run finds the PRIOR run's intent on disk. The "auto-execute fast
|
|
144
|
+
path" (Step A: "write the line and move on" for a concrete goal) can be misread as
|
|
145
|
+
"the present file already satisfies the protocol", so the rewrite gets skipped and the
|
|
146
|
+
stale intent describes prior work — the exact bl-intent-refresh-per-run failure (the
|
|
147
|
+
A–H consolidation run listed as a non-goal what WP-A shipped).
|
|
148
|
+
|
|
149
|
+
Two cheap, deterministic moves close it:
|
|
150
|
+
|
|
151
|
+
1. **Stamp on write.** Whenever Phase 1 (re)writes `intent.md`, embed the current
|
|
152
|
+
`run_id` as an HTML comment so the prose never has to carry it:
|
|
153
|
+
`<!-- intent_run_id: <run_id> -->` (helper: `intent_freshness.stamp_marker(run_id)`).
|
|
154
|
+
Mirror `run_id` into `state.json.intent.run_id`.
|
|
155
|
+
2. **Check at Phase 1 start.** Run
|
|
156
|
+
`python3 ${CLAUDE_PLUGIN_ROOT}/scripts/intent_freshness.py --workdir "$PWD" --json`.
|
|
157
|
+
A `stale` (stamp ≠ current run) or `unstamped` verdict means the on-disk intent is
|
|
158
|
+
from a prior run — re-run Steps A–D and re-stamp. The check is **advisory** and exit-0
|
|
159
|
+
always: a run-id *mismatch* is an objective structural fact (equality, not a content
|
|
160
|
+
judgment), so detecting it respects "never a content gate" — only the refresh (the LLM
|
|
161
|
+
rewriting the prose) is judgment. Surface the verdict line in the run report; never
|
|
162
|
+
`AskUserQuestion`, never `## Held`, never block.
|
|
163
|
+
|
|
164
|
+
This is detection-by-structure + refresh-by-LLM: it does not re-introduce the retired
|
|
165
|
+
regex that judged intent *content*; it only answers "does this file belong to this run?".
|
|
166
|
+
|
|
80
167
|
### Hard guarantees (non-negotiable)
|
|
81
168
|
|
|
82
169
|
- **Never `AskUserQuestion`.** Intent capture is autonomous. The user reads the restatement + assumptions in the run report and can correct on the next dispatch.
|