@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.
Files changed (170) hide show
  1. package/.agents/plugins/marketplace.json +2 -2
  2. package/.claude-plugin/marketplace.json +4 -4
  3. package/.claude-plugin/plugin.json +1 -1
  4. package/.codex-plugin/plugin.json +1 -1
  5. package/AGENTS.md +9 -0
  6. package/README.md +8 -7
  7. package/agents/advisor.md +111 -0
  8. package/agents/alignment-checker.md +11 -0
  9. package/agents/assessment-orchestrator.md +1 -1
  10. package/agents/build-orchestrator.md +28 -33
  11. package/agents/fact-checker.md +1 -1
  12. package/agents/fix-critique.md +1 -1
  13. package/agents/independent-auditor.md +1 -1
  14. package/agents/overfitting-reviewer.md +1 -1
  15. package/agents/plan-critic.md +5 -4
  16. package/agents/promotion-reviewer.md +1 -1
  17. package/agents/retrospective-synthesizer.md +20 -3
  18. package/agents/scope-auditor.md +1 -1
  19. package/agents/security-reviewer.md +1 -1
  20. package/agents/self-improvement-architect.md +1 -1
  21. package/commands/{handoff.md → compose-handoff.md} +4 -4
  22. package/commands/{optimize.md → optimize-run.md} +1 -1
  23. package/commands/{agent-rally-point.md → rally-point.md} +3 -3
  24. package/commands/{research.md → research-run.md} +1 -1
  25. package/commands/setup-memory.md +32 -0
  26. package/commands/{plan-verify.md → verify-plan.md} +1 -1
  27. package/docs/agent-surface-policy.md +38 -20
  28. package/docs/memory-setup.md +19 -14
  29. package/hooks/_resolve_python.sh +28 -0
  30. package/hooks/closeout.sh +58 -0
  31. package/hooks/git/pre-push +69 -6
  32. package/hooks/hooks.json +34 -13
  33. package/hooks/post-push-closeout.sh +73 -0
  34. package/hooks/session-start-closeout.sh +69 -0
  35. package/hooks/session-start-memory.sh +27 -0
  36. package/hooks/session-start-plugin-heal.sh +33 -0
  37. package/hooks/test_closeout.sh +124 -0
  38. package/package.json +7 -4
  39. package/plugin-artifacts/codex/.codex-plugin/plugin.json +41 -0
  40. package/plugin-artifacts/codex/AGENTS.md +499 -0
  41. package/plugin-artifacts/codex/BUILD-ARTIFACT.md +5 -0
  42. package/plugin-artifacts/codex/LICENSE +202 -0
  43. package/plugin-artifacts/codex/README.md +404 -0
  44. package/plugin-artifacts/codex/docs/agent-surface-policy.md +63 -0
  45. package/plugin-artifacts/codex/references/advisor-dispatch-ladder.md +62 -0
  46. package/plugin-artifacts/codex/references/agent-role-taxonomy.md +101 -0
  47. package/plugin-artifacts/codex/references/autonomous-and-per-commit-modes.md +161 -0
  48. package/plugin-artifacts/codex/references/autonomy-config.md +231 -0
  49. package/plugin-artifacts/codex/references/capability-routing.md +182 -0
  50. package/plugin-artifacts/codex/references/codex-subagents.md +106 -0
  51. package/plugin-artifacts/codex/references/coordination-file-template.md +181 -0
  52. package/plugin-artifacts/codex/references/coordination-rules.md +283 -0
  53. package/plugin-artifacts/codex/references/dogfood-reload-checkpoint.md +112 -0
  54. package/plugin-artifacts/codex/references/halt-and-ask-protocol.md +102 -0
  55. package/plugin-artifacts/codex/references/implementer-envelope-schema.md +302 -0
  56. package/plugin-artifacts/codex/references/intent-capability-pack.md +257 -0
  57. package/plugin-artifacts/codex/references/intent-exploration-prompts.md +96 -0
  58. package/plugin-artifacts/codex/references/leadership.md +72 -0
  59. package/plugin-artifacts/codex/references/memory-systems.md +238 -0
  60. package/plugin-artifacts/codex/references/memory.md +297 -0
  61. package/plugin-artifacts/codex/references/model-tier-mapping.md +257 -0
  62. package/plugin-artifacts/codex/references/modular-systems-pack.md +96 -0
  63. package/plugin-artifacts/codex/references/phase-1-assess.md +231 -0
  64. package/plugin-artifacts/codex/references/phase-2-plan.md +77 -0
  65. package/plugin-artifacts/codex/references/phase-3-execute.md +47 -0
  66. package/plugin-artifacts/codex/references/phase-4-review.md +320 -0
  67. package/plugin-artifacts/codex/references/phase-5-iterate.md +71 -0
  68. package/plugin-artifacts/codex/references/phase-6-learn.md +56 -0
  69. package/plugin-artifacts/codex/references/recent-design-structures.md +274 -0
  70. package/plugin-artifacts/codex/references/research-trigger-policy.md +140 -0
  71. package/plugin-artifacts/codex/references/runtime-smoke-triggers.md +42 -0
  72. package/plugin-artifacts/codex/references/self-review.md +234 -0
  73. package/plugin-artifacts/codex/references/single-writer-commit-protocol.md +90 -0
  74. package/plugin-artifacts/codex/references/task-capture-policy.md +68 -0
  75. package/plugin-artifacts/codex/references/ui-io-contract.md +116 -0
  76. package/plugin-artifacts/codex/references/ui-spotcheck-protocol.md +65 -0
  77. package/plugin-artifacts/codex/skills/build-loop/SKILL.md +372 -0
  78. package/plugin-artifacts/codex/skills/build-loop/detect-plugins.mjs +82 -0
  79. package/plugin-artifacts/codex/skills/build-loop/eval-guide.md +65 -0
  80. package/plugin-artifacts/codex/skills/build-loop/fallbacks.md +549 -0
  81. package/plugin-artifacts/codex/skills/build-loop/phases/fact-check.md +42 -0
  82. package/plugin-artifacts/codex/skills/build-loop/phases/ui-validation.md +267 -0
  83. package/plugin-artifacts/codex/skills/build-loop/references/advisor-dispatch-ladder.md +62 -0
  84. package/plugin-artifacts/codex/skills/build-loop/references/apple-native-planning.md +439 -0
  85. package/plugin-artifacts/codex/skills/build-loop/references/autonomous-and-per-commit-modes.md +161 -0
  86. package/plugin-artifacts/codex/skills/build-loop/references/capability-routing.md +182 -0
  87. package/plugin-artifacts/codex/skills/build-loop/references/codex-subagents.md +106 -0
  88. package/plugin-artifacts/codex/skills/build-loop/references/coordination.md +161 -0
  89. package/plugin-artifacts/codex/skills/build-loop/references/correction-aware-capture.md +177 -0
  90. package/plugin-artifacts/codex/skills/build-loop/references/independent-auditor.md +72 -0
  91. package/plugin-artifacts/codex/skills/build-loop/references/intent-capability-pack.md +257 -0
  92. package/plugin-artifacts/codex/skills/build-loop/references/intent-exploration-prompts.md +96 -0
  93. package/plugin-artifacts/codex/skills/build-loop/references/leadership.md +72 -0
  94. package/plugin-artifacts/codex/skills/build-loop/references/memory.md +297 -0
  95. package/plugin-artifacts/codex/skills/build-loop/references/modular-systems-pack.md +96 -0
  96. package/plugin-artifacts/codex/skills/build-loop/references/output-style.md +129 -0
  97. package/plugin-artifacts/codex/skills/build-loop/references/pay-it-forward-arch.md +98 -0
  98. package/plugin-artifacts/codex/skills/build-loop/references/phase-1-assess.md +231 -0
  99. package/plugin-artifacts/codex/skills/build-loop/references/phase-2-plan.md +77 -0
  100. package/plugin-artifacts/codex/skills/build-loop/references/phase-3-execute.md +47 -0
  101. package/plugin-artifacts/codex/skills/build-loop/references/phase-4-review.md +320 -0
  102. package/plugin-artifacts/codex/skills/build-loop/references/phase-5-iterate.md +71 -0
  103. package/plugin-artifacts/codex/skills/build-loop/references/phase-6-learn.md +56 -0
  104. package/plugin-artifacts/codex/skills/build-loop/references/recent-design-structures.md +274 -0
  105. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/ASSESSMENT.md +85 -0
  106. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/STANDALONE_TEST_RUN.md +149 -0
  107. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/01-simple-bugfix.md +32 -0
  108. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/02-ui-build-with-iteration.md +48 -0
  109. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/03-multi-failure-escalation.md +60 -0
  110. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/04-ui-build-ibr-absent.md +51 -0
  111. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/05-refactor-navgator-absent.md +71 -0
  112. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/06-recurring-bug-debugger-absent.md +52 -0
  113. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/trace-comparison.md +202 -0
  114. package/plugin-artifacts/codex/skills/build-loop/references/self-recursive-dev.md +77 -0
  115. package/plugin-artifacts/codex/skills/build-loop/references/self-review.md +234 -0
  116. package/plugin-artifacts/codex/skills/build-loop/references/ui-io-contract.md +116 -0
  117. package/plugin-artifacts/codex/skills/build-loop/scanners/audit-design-rules.mjs +476 -0
  118. package/plugin-artifacts/codex/skills/build-loop/scanners/require-visual-evidence.mjs +239 -0
  119. package/plugin-artifacts/codex/skills/build-loop/templates/backlog-item.md +35 -0
  120. package/plugin-artifacts/codex/skills/build-loop/templates/codex-worker-prompt.md +96 -0
  121. package/plugin-artifacts/codex/skills/build-loop/templates/ui-subagent-prompt.md +179 -0
  122. package/plugin-artifacts/codex/skills/build-loop/templates/ux-fix-plan.md +40 -0
  123. package/scripts/_paths.py +59 -13
  124. package/scripts/build_codex_plugin_artifact.py +314 -0
  125. package/scripts/check_cache_sync.py +1 -1
  126. package/scripts/install_memory.py +11 -3
  127. package/scripts/prune_plugin_cache.py +225 -11
  128. package/scripts/sync_navgator_lessons.py +25 -0
  129. package/scripts/sync_plugin_cache.py +66 -36
  130. package/skills/agent-rally-point/SKILL.md +1 -1
  131. package/skills/agent-rally-watcher/SKILL.md +1 -1
  132. package/skills/build-loop/SKILL.md +11 -155
  133. package/skills/build-loop/references/advisor-dispatch-ladder.md +62 -0
  134. package/skills/build-loop/references/autonomous-and-per-commit-modes.md +161 -0
  135. package/skills/build-loop/references/capability-routing.md +4 -3
  136. package/skills/build-loop/references/codex-subagents.md +8 -0
  137. package/skills/build-loop/references/coordination.md +1 -1
  138. package/skills/build-loop/references/intent-capability-pack.md +88 -1
  139. package/skills/build-loop/references/memory.md +17 -2
  140. package/skills/build-loop/references/phase-1-assess.md +13 -0
  141. package/skills/build-loop/references/phase-2-plan.md +1 -1
  142. package/skills/build-loop/references/phase-4-review.md +12 -0
  143. package/skills/build-loop/references/phase-6-learn.md +1 -1
  144. package/skills/build-loop/references/self-review.md +4 -2
  145. package/skills/build-loop/templates/codex-worker-prompt.md +41 -34
  146. package/skills/handoff/SKILL.md +3 -3
  147. package/skills/loop-builder/SKILL.md +98 -0
  148. package/skills/loop-builder/presets/active-project-evidence.yaml +97 -0
  149. package/skills/loop-builder/presets/generic-artifact-loop.yaml +95 -0
  150. package/skills/loop-builder/presets/presentation-audit.yaml +96 -0
  151. package/skills/loop-builder/presets/research-synthesis.yaml +96 -0
  152. package/skills/loop-builder/presets/source-ingestion-raw-data-audit.yaml +96 -0
  153. package/skills/loop-builder/references/spec-format.md +80 -0
  154. package/skills/loop-builder/scripts/loop_builder.py +346 -0
  155. package/skills/model-tiering/SKILL.md +65 -40
  156. package/skills/optimize/SKILL.md +2 -2
  157. package/skills/plan-verify/SKILL.md +1 -1
  158. package/skills/plugin-builder/references/distribution.md +8 -0
  159. package/skills/research/SKILL.md +33 -6
  160. package/skills/runtime-parity-verification/SKILL.md +51 -0
  161. package/skills/spec-writing/SKILL.md +19 -0
  162. package/templates/memory/README.md +65 -0
  163. package/templates/memory/charter.md.template +46 -0
  164. package/templates/memory/manifest.json +24 -4
  165. package/codex-skills/debug-loop/SKILL.md +0 -18
  166. package/codex-skills/handoff/SKILL.md +0 -22
  167. package/codex-skills/knowledge/SKILL.md +0 -21
  168. package/codex-skills/optimize/SKILL.md +0 -18
  169. package/codex-skills/research/SKILL.md +0 -18
  170. /package/commands/{knowledge-review.md → review-knowledge.md} +0 -0
@@ -0,0 +1,63 @@
1
+ # Agent Surface Policy
2
+
3
+ Build Loop keeps one user-facing Codex entrypoint while preserving the richer
4
+ Claude Code skill tree for hosts that can route helpers internally.
5
+
6
+ ## Public Entry Points
7
+
8
+ Codex must expose exactly one user-facing Build Loop choice:
9
+
10
+ - `build-loop` — main workflow and router for build, fix, debug, optimize,
11
+ research, knowledge capture, handoff, and plugin-test work
12
+
13
+ Claude Code may expose advanced direct overrides in its command/skill surface
14
+ where useful:
15
+
16
+ - `build-loop`
17
+ - `debug-loop`
18
+ - `optimize`
19
+ - `research`
20
+ - `knowledge`
21
+ - `handoff`
22
+
23
+ ## Host Rules
24
+
25
+ Codex and ChatGPT install from `plugin-artifacts/codex`, not from the source
26
+ repo root. Codex auto-discovers root `skills/*/SKILL.md` files and manifest
27
+ skill paths supplement that default, so installing the source root leaks every
28
+ internal helper into the picker. The artifact is generated by:
29
+
30
+ ```bash
31
+ python3 scripts/build_codex_plugin_artifact.py --source . --target plugin-artifacts/codex
32
+ ```
33
+
34
+ The artifact contains one `skills/build-loop/SKILL.md` copied from the
35
+ canonical workflow and `.codex-plugin/plugin.json` rewritten to
36
+ `"skills": "./skills"`. It must not contain any other `SKILL.md` files.
37
+
38
+ The local Codex marketplace (`.agents/plugins/marketplace.json`) points at this
39
+ artifact. Release and marketplace updates must do the same.
40
+
41
+ Claude Code keeps `.claude-plugin/plugin.json` pointed at `./skills` because
42
+ commands and orchestrator agents load internal skills by qualified name. Helper
43
+ skills must set `user-invocable: false`; the public entrypoints set
44
+ `user-invocable: true`.
45
+
46
+ Cursor and other AGENTS.md-style tools should treat `AGENTS.md` plus this file
47
+ as the routing contract. Start from `build-loop`. Read helper files under
48
+ `skills/` only when the active entrypoint, a command, or an orchestrator
49
+ instruction explicitly references them.
50
+
51
+ ## Cache Hygiene
52
+
53
+ Plugin cache pruning is explicit and auditable:
54
+
55
+ ```bash
56
+ npm run codex:sync-cache
57
+ python3 scripts/prune_plugin_cache.py --source . --apply
58
+ ```
59
+
60
+ `npm run codex:sync-cache` rebuilds the slim artifact first, then syncs that
61
+ artifact into the Codex cache. The prune command keeps the current host manifest
62
+ version and deletes older verified cache directories for the same plugin. Use
63
+ `--host codex` or `--host claude` for a single host.
@@ -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,101 @@
1
+ <!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
2
+
3
+ # Agent Role Taxonomy
4
+
5
+ This reference answers two recurring coordination questions:
6
+
7
+ 1. Who is lead?
8
+ 2. Is a "coder", "backend", or "database" entity an agent, a skill, or a task role?
9
+
10
+ Use this doc with `references/model-tier-mapping.md`: this file defines
11
+ responsibility boundaries, while model-tiering defines the model class used for
12
+ each role.
13
+
14
+ ## Binding Rule
15
+
16
+ The lead is the session holding the current valid Rally Point leadership lease.
17
+ It is not a hardcoded tool name, default UI label, or mock value. If no valid
18
+ lease exists, the first active orchestrator that claims the lease becomes lead
19
+ until it transfers, relinquishes, or expires.
20
+
21
+ ```bash
22
+ python3 scripts/agent_rally.py lead status --workdir "$PWD" --json
23
+ ```
24
+
25
+ When the displayed lead conflicts with the live lease, trust the live lease and
26
+ file the display as a Rally Point bug.
27
+
28
+ ## Roles
29
+
30
+ | Role | Current surface | Default tier | Owns | Must not own |
31
+ |---|---|---:|---|---|
32
+ | Human/operator | User prompt and explicit gates | n/a | Goal, production push approval, irreversible delete approval, major user-impact decisions | Routine commit cadence, reversible implementation choices |
33
+ | Lead orchestrator | `agents/build-orchestrator.md`; Rally Point leadership lease | Thinking | Run plan, phase transitions, ownership partition, dispatch, final judgment, commits, release/report | Pretending peer handoffs are approval, ignoring stale/off-task peers |
34
+ | Peer host/session | Rally Point presence/inbox/handoff | Host-selected | Its claimed lane, verdicts, handoffs, review requests | Files claimed by another active peer, silent lead takeover |
35
+ | Coder subagent | `agents/implementer.md` | Code | Bounded implementation against owned files and a written spec | Architecture expansion, git staging/commit/push, cross-lane cleanup |
36
+ | Domain assessor | `agents/database-assessor.md`, `api-assessor.md`, `frontend-assessor.md`, `performance-assessor.md` | Code or Thinking by complexity | Diagnosis and evidence in one domain | Shipping code by default; use implementer for the fix |
37
+ | Architecture/scope specialist | `architecture-scout`, `scope-auditor`, architecture skills | Thinking | Blast-radius tracing, caller impact, scope gaps | Applying the fix after finding the gap |
38
+ | Reviewer/auditor | `independent-auditor`, `security-reviewer`, `plan-critic`, `fix-critique`, `synthesis-critic` | Code or Thinking by rubric/judgment mix | Read-only challenge, risk ranking, verdicts | Mutating code under review |
39
+ | UI/design specialist | `design-contract-specialist`, `ui-validator`, `ui-design` skill | Code or Thinking by task | UI contract, visual validation, design direction | Business logic outside the UI contract |
40
+ | Retrospective/learning agent | `retrospective-synthesizer`, `recurring-pattern-detector`, `self-improvement-architect` | Pattern to Thinking | Pattern extraction, proposals, lessons | Silent promotion of new enforcement |
41
+ | Skill | `skills/*/SKILL.md` | n/a | Procedural guidance, routing rules, references, scripts | Acting as a live worker or owner |
42
+ | Script/tool | `scripts/*` | n/a | Deterministic checks, writes, summaries | Making LLM judgment calls unless explicitly wrapped by an agent |
43
+
44
+ ## Coder vs Backend/Database Agent
45
+
46
+ Build-loop already has a dedicated coder subagent: `implementer`. Do not add a
47
+ separate generic `coder` agent unless evidence shows agents or users repeatedly
48
+ miss that `implementer` is the coding role.
49
+
50
+ For backend/database work:
51
+
52
+ 1. Use the domain assessor when the problem is diagnostic or cross-layer:
53
+ `database-assessor`, `api-assessor`, `performance-assessor`, or
54
+ `assessment-orchestrator`.
55
+ 2. Use `implementer` when the fix is scoped to owned files and the "what" is
56
+ decided.
57
+ 3. Escalate to `scope-auditor` or `architecture-scout` when a persistence,
58
+ schema, API, or data-contract boundary might widen the blast radius.
59
+
60
+ This keeps roles MECE: assessors diagnose, implementer edits, reviewers judge,
61
+ and the lead orchestrator commits.
62
+
63
+ ## Lead Responsibilities
64
+
65
+ The lead orchestrator must:
66
+
67
+ - Claim or verify the leadership lease at Phase 1 and renew it at phase starts.
68
+ - Keep Rally Point status/watch active when peers, inbox items, or an active
69
+ coord file exist.
70
+ - Write task heartbeats for long-running work and pass `--task-ref` into
71
+ status/watch.
72
+ - Assign exactly one owner per file/chunk before dispatch.
73
+ - Dispatch subagents by role, not by vague labels like "backend agent" unless
74
+ the role maps to one of the surfaces above.
75
+ - Remain the single writer to `.git/`; subagents return envelopes, not commits.
76
+ - Decide routine reversible choices under `references/leadership.md`.
77
+
78
+ ## Peer Responsibilities
79
+
80
+ Every peer host/session must:
81
+
82
+ - Use a stable `tool` id (`claude_code`, `codex`, `cursor`, etc.).
83
+ - Publish presence and lane ownership before mutating shared files.
84
+ - Read direct and broadcast inbox messages before acting on a handoff preview.
85
+ - Post verdicts or handoffs through Rally Point, not only terminal prose.
86
+ - Use `heartbeat --task-ref` during long-running tasks so other sessions can
87
+ distinguish "process alive" from "still on task".
88
+
89
+ ## When To Add A New Agent
90
+
91
+ Add a new agent only when all are true:
92
+
93
+ 1. The task repeats across builds.
94
+ 2. The task has a stable input/output envelope.
95
+ 3. The responsibility is not already owned by one row above.
96
+ 4. A skill or script cannot express the behavior cleanly.
97
+ 5. Verification can check the output before the orchestrator accepts it.
98
+
99
+ If the need is "teach agents how to do X", add or update a skill/reference. If
100
+ the need is "perform X repeatedly with a bounded contract", add an agent. If
101
+ the need is "compute X deterministically", add a script.
@@ -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`.
@@ -0,0 +1,231 @@
1
+ <!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
2
+
3
+ # Autonomy Gate — Configuration Reference
4
+
5
+ ## Purpose
6
+
7
+ `scripts/autonomy_gate.py` is the generalized action classifier that lets Phase 4.5 Auto-Resolve drain non-destructive open items (guidance fixes, cache resyncs, lint cleanups, open-rec executions) without prompting the operator. The existing `scripts/deployment_policy.py` already handles push/deploy/release commands; this gate handles everything else, and delegates to deployment_policy when a command looks deployment-flavored. Together they form the complete autonomy boundary: deployment_policy is authoritative for deploy targets, autonomy_gate is authoritative for everything else.
8
+
9
+ ## Default policy
10
+
11
+ ### confirmFor — 7 built-in patterns
12
+
13
+ These patterns require operator confirmation (`exit 1`). They are active whenever a repo does NOT supply its own `confirmFor` list:
14
+
15
+ ```
16
+ npm publish*
17
+ git push --force*
18
+ git push * main
19
+ git push * master
20
+ production deploy*
21
+ DROP TABLE*
22
+ rm -rf /*
23
+ ```
24
+
25
+ Matching uses `fnmatch.fnmatch` (Unix-shell-style globs, case-insensitive).
26
+
27
+ ### warnFor — empty by default (NEW)
28
+
29
+ No commands are flagged by default. Repos may add patterns to `warnFor` to observe match-rate without blocking (`exit 0`). The canonical workflow is to ship a candidate pattern as `warnFor` first, observe 10+ builds via `state.json.runs[].autonomyEvents[]`, then promote to `confirmFor` if the match-rate justifies it.
30
+
31
+ ### blockFor — empty by default
32
+
33
+ No commands are hard-blocked by default. Repos may add patterns to `blockFor` to create absolute vetoes (`exit 2`).
34
+
35
+ ### Boolean flags
36
+
37
+ | Flag | Default | Meaning |
38
+ |---|---|---|
39
+ | `autoFixGuidance` | `true` | Phase 4.5 may auto-apply guidance-class fixes without operator confirmation |
40
+ | `autoExecuteOpenRecs` | `true` | Phase 4.5 may auto-execute open recommendations without operator confirmation |
41
+
42
+ These flags are read by the skill body and orchestrator (Chunks B/C). `autonomy_gate.py` surfaces them in the envelope's `flags` key but does not act on them directly.
43
+
44
+ ## Repo override schema
45
+
46
+ Add an `autonomy` block to `.build-loop/config.json`:
47
+
48
+ ```json
49
+ {
50
+ "autonomy": {
51
+ "autoFixGuidance": true,
52
+ "autoExecuteOpenRecs": true,
53
+ "confirmFor": [
54
+ "wipe database*",
55
+ "reset production*"
56
+ ],
57
+ "warnFor": [
58
+ "touch-prod-config*"
59
+ ],
60
+ "blockFor": [
61
+ "rm -rf /"
62
+ ]
63
+ }
64
+ }
65
+ ```
66
+
67
+ All five fields are optional. Omitting `confirmFor`, `warnFor`, or `blockFor` leaves the defaults active. Setting them (even to `[]`) replaces the defaults.
68
+
69
+ **Tie semantics**: when a command matches both `confirmFor` and `warnFor`, `confirmFor` wins. The stricter verdict always takes precedence.
70
+
71
+ ## Replacement semantics
72
+
73
+ `confirmFor`, `warnFor`, and `blockFor` **REPLACE** the defaults — they do not extend them. This is intentional: repos that need a smaller or entirely different set of guarded commands should not be forced to fight the defaults.
74
+
75
+ To extend the defaults, copy the 7 default `confirmFor` patterns into your config and add your custom patterns alongside them:
76
+
77
+ ```json
78
+ {
79
+ "autonomy": {
80
+ "confirmFor": [
81
+ "npm publish*",
82
+ "git push --force*",
83
+ "git push * main",
84
+ "git push * master",
85
+ "production deploy*",
86
+ "DROP TABLE*",
87
+ "rm -rf /*",
88
+ "wipe database*"
89
+ ]
90
+ }
91
+ }
92
+ ```
93
+
94
+ ## Precedence
95
+
96
+ The gate applies rules in this order, stopping at the first match:
97
+
98
+ 1. **deployment_policy first** — if the command contains deploy/push/release keywords, shell out to `python3 scripts/deployment_policy.py --workdir <path> --command <command>`. Use its verdict directly. `list_source: "deployment_policy"`.
99
+ 2. **Repo blockFor next** — if any `blockFor` glob from `.build-loop/config.json` matches the command, return `block` (`exit 2`). `list_source: "config"`.
100
+ 3. **Repo confirmFor next** — if any `confirmFor` glob from config matches, return `confirm` (`exit 1`). `list_source: "config"`. **confirmFor wins over warnFor on a tie** — checked first.
101
+ 4. **Repo warnFor next** — if any `warnFor` glob from config matches, return `warn` (`exit 0`). `list_source: "config"`. (NEW)
102
+ 5. **Default confirmFor next** — if no repo `confirmFor` was provided, check the 7 default patterns. Match → `confirm` (`exit 1`). `list_source: "default"`.
103
+ 6. **Default warnFor next** — if no repo `warnFor` was provided, check the default warn list (empty). Match → `warn` (`exit 0`). `list_source: "default"`. (NEW, no-op by default)
104
+ 7. **Default blockFor next** — if no repo `blockFor` was provided, check the default block list (empty). Match → `block` (`exit 2`). `list_source: "default"`.
105
+ 8. **Otherwise** — return `auto` (`exit 0`). `list_source: "default"` or `"config"` depending on whether a config file exists.
106
+
107
+ Note: repo `confirmFor`, `warnFor`, and `blockFor` only apply when explicitly set in config. If `confirmFor` is absent from config, step 3 is skipped and step 5 applies. If `confirmFor` is present (even as `[]`), step 5 is skipped entirely. Same logic applies to `warnFor` (step 4 vs step 6) and `blockFor` (step 2 vs step 7).
108
+
109
+ ## Relationship to deployment_policy.py
110
+
111
+ `deployment_policy.py` is the canonical gate for push/deploy commands. It understands deployment targets (preview, testflight, production, unknown) and repo-level target policies. `autonomy_gate.py` delegates to it rather than duplicating that logic.
112
+
113
+ `autonomy_gate.py` generalizes for everything else: lint fixes, cache ops, open-rec execution, guidance application, and any other non-deploy action the orchestrator may want to auto-execute. It also delegates to deployment_policy when it detects deployment-flavored keywords.
114
+
115
+ Do not modify deployment_policy.py to handle non-deploy actions. The two scripts are intentionally decoupled; autonomy_gate calls deployment_policy as a subprocess.
116
+
117
+ ## Usage from skill body / orchestrator
118
+
119
+ ### Human-readable output (default)
120
+
121
+ ```bash
122
+ python3 scripts/autonomy_gate.py \
123
+ --workdir /path/to/repo \
124
+ --action "cache resync" \
125
+ --command "rsync ... codex cache"
126
+ # output: auto: cache resync — no pattern matched; safe to execute
127
+ # exit: 0
128
+ ```
129
+
130
+ ### JSON envelope (for machine consumers)
131
+
132
+ ```bash
133
+ python3 scripts/autonomy_gate.py \
134
+ --workdir /path/to/repo \
135
+ --action "npm publish" \
136
+ --command "npm publish" \
137
+ --json
138
+ ```
139
+
140
+ Output:
141
+
142
+ ```json
143
+ {
144
+ "action": "confirm",
145
+ "matched_rule": "npm publish*",
146
+ "list_source": "default",
147
+ "reason": "matched default confirmFor pattern",
148
+ "label": "npm publish",
149
+ "command": "npm publish",
150
+ "flags": {
151
+ "autoFixGuidance": true,
152
+ "autoExecuteOpenRecs": true
153
+ }
154
+ }
155
+ ```
156
+
157
+ ### Exit code mapping (mirror of deployment_policy.py)
158
+
159
+ | Exit code | Meaning |
160
+ |---|---|
161
+ | `0` | `auto` — safe to execute without operator input |
162
+ | `0` | `warn` — safe to execute; flagged for match-rate tracking (NEW) |
163
+ | `1` | `confirm` — operator must approve before proceeding |
164
+ | `2` | `block` — do not execute under any circumstance |
165
+
166
+ ### Consuming in a shell script
167
+
168
+ ```bash
169
+ python3 scripts/autonomy_gate.py \
170
+ --workdir "$WORKDIR" \
171
+ --action "$ACTION_LABEL" \
172
+ --command "$COMMAND" \
173
+ --json > /tmp/gate_result.json
174
+ exit_code=$?
175
+ action=$(python3 -c "import json,sys; print(json.load(open('/tmp/gate_result.json'))['action'])")
176
+
177
+ case $exit_code in
178
+ 0)
179
+ if [ "$action" = "warn" ]; then
180
+ echo "[warn] Executing (flagged): $ACTION_LABEL"
181
+ else
182
+ echo "Auto-executing: $ACTION_LABEL"
183
+ fi ;;
184
+ 1) echo "Needs confirmation: $ACTION_LABEL" ; exit 1 ;;
185
+ 2) echo "BLOCKED: $ACTION_LABEL" ; exit 2 ;;
186
+ esac
187
+ ```
188
+
189
+ ### Reading flags from the envelope
190
+
191
+ The `flags` key surfaces the two boolean flags regardless of which rule triggered. Consumers check them before deciding whether to auto-apply guidance or open-rec items:
192
+
193
+ ```python
194
+ import json, subprocess, sys
195
+
196
+ result = subprocess.run(
197
+ [sys.executable, "scripts/autonomy_gate.py",
198
+ "--workdir", workdir, "--action", label, "--command", cmd, "--json"],
199
+ capture_output=True, text=True,
200
+ )
201
+ data = json.loads(result.stdout)
202
+ if result.returncode == 0 and data["flags"]["autoFixGuidance"]:
203
+ apply_guidance_fix()
204
+ ```
205
+
206
+ ## Warn-before-block workflow
207
+
208
+ The canonical pattern for introducing new guarded patterns:
209
+
210
+ 1. **Ship as `warnFor`**: add the candidate glob to `warnFor` in `.build-loop/config.json`. The gate executes the action, records it in `## Done` with a `[warn] <reason>` prefix, and appends one entry to `state.json.runs[].autonomyEvents[]`.
211
+
212
+ 2. **Observe match-rate**: run ~10 builds. Inspect `autonomyEvents[]` entries for this pattern. High match-rate + never-intended-to-run = promote to `confirmFor`. Low match-rate = the pattern is too broad; refine the glob first.
213
+
214
+ 3. **Promote to `confirmFor`**: move the glob from `warnFor` to `confirmFor`. From this point the gate will pause execution and route the item to `## Held` for manual operator approval.
215
+
216
+ This three-step lifecycle keeps the autonomy policy calibrated. Jumping straight to `confirmFor` with an untested glob creates friction for every legitimate execution of that command. Jumping straight to `blockFor` without data risks blocking operations that are actually safe in this repo's context.
217
+
218
+ **`autonomyEvents[]` entry shape** (one entry per `warn` verdict, appended by the orchestrator at the end of Sub-step F):
219
+ ```json
220
+ {
221
+ "action": "warn",
222
+ "matched_rule": "<glob>",
223
+ "list_source": "config",
224
+ "label": "<action label>",
225
+ "command": "<full command>",
226
+ "run_id": "<state.json run_id>",
227
+ "timestamp": "<iso8601>"
228
+ }
229
+ ```
230
+
231
+ The orchestrator emits this entry. The gate script itself does not write to `state.json` — separation of concerns: gate classifies, orchestrator records.