@tyroneross/build-loop 0.36.0 → 0.43.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 (270) hide show
  1. package/.agents/plugins/marketplace.json +2 -2
  2. package/.claude-plugin/marketplace.json +3 -3
  3. package/.claude-plugin/plugin.json +1 -1
  4. package/.codex-plugin/plugin.json +1 -1
  5. package/.cursor/rules/build-loop-surface.mdc +12 -11
  6. package/.cursor/rules/skill-index.mdc +33 -0
  7. package/AGENTS.md +213 -34
  8. package/README.md +99 -31
  9. package/agents/advisor.md +4 -4
  10. package/agents/alignment-checker.md +2 -2
  11. package/agents/architecture-scout.md +4 -4
  12. package/agents/build-orchestrator.md +38 -36
  13. package/agents/database-assessor.md +11 -5
  14. package/agents/design-contract-specialist.md +8 -8
  15. package/agents/fact-checker.md +13 -3
  16. package/agents/fix-critique.md +2 -2
  17. package/agents/independent-auditor.md +60 -7
  18. package/agents/leak-scanner.md +82 -0
  19. package/agents/overfitting-reviewer.md +2 -2
  20. package/agents/plan-critic.md +1 -1
  21. package/agents/promotion-reviewer.md +5 -5
  22. package/agents/retrospective-synthesizer.md +138 -35
  23. package/agents/scope-auditor.md +82 -11
  24. package/agents/security-reviewer.md +56 -2
  25. package/agents/self-improvement-architect.md +17 -3
  26. package/agents/transcript-pattern-miner.md +5 -5
  27. package/agents/ui-validator.md +1 -1
  28. package/bin/build-loop-debugger.js +143 -0
  29. package/bin/build-loop-install.js +1 -4
  30. package/bin/build-loop-load-probe.js +345 -0
  31. package/codex-skills/build-loop/SKILL.md +28 -6
  32. package/commands/feedback.md +37 -0
  33. package/dist/src/interactive-verifier.d.ts +1 -14
  34. package/dist/src/interactive-verifier.d.ts.map +1 -1
  35. package/dist/src/interactive-verifier.js +6 -113
  36. package/dist/src/interactive-verifier.js.map +1 -1
  37. package/dist/src/quality.d.ts +5 -0
  38. package/dist/src/quality.d.ts.map +1 -0
  39. package/dist/src/quality.js +81 -0
  40. package/dist/src/quality.js.map +1 -0
  41. package/dist/src/storage.d.ts.map +1 -1
  42. package/dist/src/storage.js +37 -3
  43. package/dist/src/storage.js.map +1 -1
  44. package/docs/agent-surface-policy.md +35 -31
  45. package/docs/memory-setup.md +19 -0
  46. package/hooks/git/pre-push +65 -4
  47. package/hooks/hooks.json +95 -38
  48. package/hooks/pre-commit +20 -1
  49. package/hooks/pre-edit-rally-point.sh +10 -3
  50. package/hooks/session-start-codex-hook-trust.sh +30 -0
  51. package/hooks/session-start-git-hooks.sh +3 -1
  52. package/hooks/session-start-rally-point.sh +52 -4
  53. package/hooks/session-start-worktree-gc.sh +47 -94
  54. package/hooks/stop-transcript-sweep.sh +173 -0
  55. package/hooks/test_closeout.sh +14 -2
  56. package/package.json +8 -7
  57. package/scripts/README.md +1 -1
  58. package/scripts/_paths.py +65 -0
  59. package/scripts/groundwork_exchange.py +1012 -0
  60. package/scripts/install_memory.py +33 -1
  61. package/scripts/lessons_index/ingest.py +13 -2
  62. package/scripts/lessons_index/query.py +36 -13
  63. package/scripts/memory_context/__init__.py +108 -14
  64. package/scripts/memory_graph/__init__.py +5 -1
  65. package/scripts/project_resolver.py +42 -36
  66. package/scripts/sync_plugin_cache.py +37 -2
  67. package/skills/agent-rally-point/SKILL.md +46 -0
  68. package/skills/api-registry-bridge/SKILL.md +1 -1
  69. package/skills/architecture/dead/SKILL.md +1 -1
  70. package/skills/architecture/impact/SKILL.md +1 -1
  71. package/skills/architecture/review/SKILL.md +1 -1
  72. package/skills/architecture/rules/SKILL.md +3 -3
  73. package/skills/architecture/scan/SKILL.md +1 -1
  74. package/skills/architecture/trace/SKILL.md +1 -1
  75. package/skills/attribution-standard/SKILL.md +6 -6
  76. package/skills/auto-decision-capture/SKILL.md +31 -2
  77. package/skills/auto-finding-capture/SKILL.md +28 -1
  78. package/skills/build-loop/SKILL.md +131 -23
  79. package/skills/build-loop/fallbacks.md +16 -21
  80. package/skills/build-loop/phases/ui-validation.md +2 -2
  81. package/skills/build-loop/references/advisor-dispatch-ladder.md +1 -1
  82. package/skills/build-loop/references/apple-native-planning.md +1 -1
  83. package/skills/build-loop/references/autonomous-and-per-commit-modes.md +11 -5
  84. package/skills/build-loop/references/autonomy-dashboard.md +115 -0
  85. package/skills/build-loop/references/capability-routing.md +24 -2
  86. package/skills/build-loop/references/coordination.md +24 -6
  87. package/skills/build-loop/references/experiment-results-template.md +15 -3
  88. package/skills/build-loop/references/leadership.md +1 -1
  89. package/skills/build-loop/references/memory.md +14 -3
  90. package/skills/build-loop/references/modular-systems-pack.md +8 -0
  91. package/skills/build-loop/references/output-style.md +86 -0
  92. package/skills/build-loop/references/phase-1-assess.md +102 -2
  93. package/skills/build-loop/references/phase-2-plan.md +9 -1
  94. package/skills/build-loop/references/phase-3-execute.md +5 -2
  95. package/skills/build-loop/references/phase-4-review.md +85 -8
  96. package/skills/build-loop/references/phase-5-iterate.md +76 -8
  97. package/skills/build-loop/references/phase-6-learn.md +10 -17
  98. package/skills/build-loop/references/privileged-request-broker.md +254 -0
  99. package/skills/build-loop/references/resource-aware-execution.md +183 -0
  100. package/skills/build-loop/references/self-recursive-dev.md +2 -2
  101. package/skills/build-loop/references/status-output-format.md +207 -0
  102. package/skills/build-loop/references/verify-dispatch.md +56 -2
  103. package/skills/building-with-deepagents/SKILL.md +1 -1
  104. package/skills/claim-scope/SKILL.md +185 -0
  105. package/skills/color-engine/SKILL.md +103 -0
  106. package/skills/color-engine/_core.py +464 -0
  107. package/skills/color-engine/color_engine.py +175 -0
  108. package/skills/cost-rca/SKILL.md +61 -0
  109. package/skills/data-plane-worktrees/SKILL.md +139 -0
  110. package/skills/data-plane-worktrees/agents/openai.yaml +4 -0
  111. package/skills/database-practice/SKILL.md +200 -0
  112. package/skills/database-practice/references/diagnostic-queries.sql +126 -0
  113. package/skills/database-practice/references/vector-and-graph-tuning.md +208 -0
  114. package/skills/database-practice/scripts/db_table_map.py +1244 -0
  115. package/skills/database-practice/scripts/test_db_table_map.py +514 -0
  116. package/skills/debug-loop/SKILL.md +36 -6
  117. package/skills/debugging-memory/SKILL.md +32 -430
  118. package/skills/debugging-memory/references/pattern-extraction.md +4 -4
  119. package/skills/debugging-memory/references/search.md +32 -120
  120. package/skills/debugging-memory/references/store.md +32 -126
  121. package/skills/debugging-memory/references/subagent-integration.md +1 -1
  122. package/skills/decision-queue/SKILL.md +251 -0
  123. package/skills/decision-queue/assets/template.html +1242 -0
  124. package/skills/decision-queue/references/example-large-queue-batching.md +164 -0
  125. package/skills/decision-queue/scripts/regen_template_constants.py +160 -0
  126. package/skills/defenseclaw-bridge/SKILL.md +2 -2
  127. package/skills/defenseclaw-bridge/references/dc-config-mapping.md +2 -9
  128. package/skills/drain-proposals/SKILL.md +53 -0
  129. package/skills/focused-loop-builder/SKILL.md +31 -0
  130. package/skills/focused-loop-builder/references/spec-format.md +27 -0
  131. package/skills/handoff/SKILL.md +169 -8
  132. package/skills/ibr-bridge/SKILL.md +4 -1
  133. package/skills/knowledge/SKILL.md +26 -14
  134. package/skills/knowledge/references/review-mode.md +2 -3
  135. package/skills/knowledge/templates/madr-minimal.md +1 -1
  136. package/skills/mcp-builder/SKILL.md +1 -1
  137. package/skills/model-bakeoff/SKILL.md +48 -10
  138. package/skills/model-tiering/SKILL.md +92 -31
  139. package/skills/native-ax-driver/SKILL.md +38 -5
  140. package/skills/native-ax-driver/scripts/native_driver.py +278 -22
  141. package/skills/native-ax-driver/scripts/test_native_driver.py +227 -0
  142. package/skills/optimize/SKILL.md +1 -1
  143. package/skills/plugin-builder/SKILL.md +48 -1
  144. package/skills/plugin-builder/references/build-loop-phase-guidance.md +3 -4
  145. package/skills/plugin-builder/references/distribution.md +13 -2
  146. package/skills/plugin-builder/references/plugin-hygiene-lessons.md +2 -2
  147. package/skills/plugin-tests/SKILL.md +2 -2
  148. package/skills/recursive-retrospective/SKILL.md +1 -1
  149. package/skills/repo-closeout/SKILL.md +17 -0
  150. package/skills/repo-closeout/agents/openai.yaml +4 -0
  151. package/skills/repo-maintenance/SKILL.md +179 -0
  152. package/skills/repo-maintenance/agents/openai.yaml +4 -0
  153. package/skills/repo-maintenance/references/pre-public-hygiene.md +134 -0
  154. package/skills/repo-maintenance/references/repository-taxonomy.md +161 -0
  155. package/skills/repo-maintenance/references/safety-protocol.md +106 -0
  156. package/skills/repo-maintenance/references/stack-profiles.md +138 -0
  157. package/skills/repo-maintenance/scripts/audit_repo_maintenance.py +1198 -0
  158. package/skills/repo-maintenance/scripts/test_audit_repo_maintenance.py +506 -0
  159. package/skills/repository-intelligence/SKILL.md +189 -0
  160. package/skills/repository-intelligence/agents/openai.yaml +4 -0
  161. package/skills/repository-intelligence/references/assessment-rubric.md +88 -0
  162. package/skills/repository-intelligence/scripts/repository_inventory.py +347 -0
  163. package/skills/research/SKILL.md +12 -2
  164. package/skills/root-cause-analysis/SKILL.md +1 -1
  165. package/skills/runtime-parity-verification/SKILL.md +36 -1
  166. package/skills/security-methodology/SKILL.md +23 -10
  167. package/skills/security-methodology/references/agentic-handoff-templates.md +220 -0
  168. package/skills/security-methodology/references/cross-source-matrix.md +1 -1
  169. package/skills/security-methodology/references/owasp-agentic-top-10.md +1 -1
  170. package/skills/security-scan/SKILL.md +55 -15
  171. package/skills/self-improve/SKILL.md +70 -50
  172. package/skills/silent-assumptions/SKILL.md +341 -0
  173. package/skills/silent-assumptions/references/elicitation-detectors.md +342 -0
  174. package/skills/spec-writing/SKILL.md +128 -24
  175. package/skills/spec-writing/scripts/check_checklist.py +114 -15
  176. package/skills/ui-design/SKILL.md +6 -4
  177. package/skills/ui-design/references/color-engine.md +132 -0
  178. package/skills/ui-design/references/design-preferences-from-owned-apps.md +8 -8
  179. package/skills/ui-design/references/ui-guidance-sources.md +1 -1
  180. package/skills/ui-design/references/universal-design-principles.alt.md +2 -2
  181. package/plugin-artifacts/codex/.codex-plugin/plugin.json +0 -41
  182. package/plugin-artifacts/codex/AGENTS.md +0 -560
  183. package/plugin-artifacts/codex/BUILD-ARTIFACT.md +0 -5
  184. package/plugin-artifacts/codex/LICENSE +0 -202
  185. package/plugin-artifacts/codex/README.md +0 -313
  186. package/plugin-artifacts/codex/assets/build-loop-plugin-icon.png +0 -0
  187. package/plugin-artifacts/codex/docs/agent-surface-policy.md +0 -63
  188. package/plugin-artifacts/codex/references/advisor-dispatch-ladder.md +0 -62
  189. package/plugin-artifacts/codex/references/agent-role-taxonomy.md +0 -135
  190. package/plugin-artifacts/codex/references/autonomous-and-per-commit-modes.md +0 -161
  191. package/plugin-artifacts/codex/references/autonomy-config.md +0 -231
  192. package/plugin-artifacts/codex/references/backlog-system.md +0 -285
  193. package/plugin-artifacts/codex/references/capability-routing.md +0 -231
  194. package/plugin-artifacts/codex/references/codex-subagents.md +0 -106
  195. package/plugin-artifacts/codex/references/coordination-file-template.md +0 -181
  196. package/plugin-artifacts/codex/references/coordination-rules.md +0 -552
  197. package/plugin-artifacts/codex/references/dogfood-reload-checkpoint.md +0 -112
  198. package/plugin-artifacts/codex/references/halt-and-ask-protocol.md +0 -102
  199. package/plugin-artifacts/codex/references/implementer-envelope-schema.md +0 -302
  200. package/plugin-artifacts/codex/references/intent-capability-pack.md +0 -257
  201. package/plugin-artifacts/codex/references/intent-exploration-prompts.md +0 -96
  202. package/plugin-artifacts/codex/references/leadership.md +0 -72
  203. package/plugin-artifacts/codex/references/memory-systems.md +0 -261
  204. package/plugin-artifacts/codex/references/memory.md +0 -313
  205. package/plugin-artifacts/codex/references/model-tier-mapping.md +0 -296
  206. package/plugin-artifacts/codex/references/modular-systems-pack.md +0 -96
  207. package/plugin-artifacts/codex/references/phase-1-assess.md +0 -249
  208. package/plugin-artifacts/codex/references/phase-2-plan.md +0 -86
  209. package/plugin-artifacts/codex/references/phase-3-execute.md +0 -49
  210. package/plugin-artifacts/codex/references/phase-4-review.md +0 -341
  211. package/plugin-artifacts/codex/references/phase-5-iterate.md +0 -72
  212. package/plugin-artifacts/codex/references/phase-6-learn.md +0 -58
  213. package/plugin-artifacts/codex/references/recent-design-structures.md +0 -274
  214. package/plugin-artifacts/codex/references/research-trigger-policy.md +0 -140
  215. package/plugin-artifacts/codex/references/runtime-smoke-triggers.md +0 -42
  216. package/plugin-artifacts/codex/references/self-review.md +0 -234
  217. package/plugin-artifacts/codex/references/single-writer-commit-protocol.md +0 -90
  218. package/plugin-artifacts/codex/references/task-capture-policy.md +0 -68
  219. package/plugin-artifacts/codex/references/ui-io-contract.md +0 -116
  220. package/plugin-artifacts/codex/references/ui-spotcheck-protocol.md +0 -65
  221. package/plugin-artifacts/codex/references/verify-dispatch.md +0 -85
  222. package/plugin-artifacts/codex/skills/build-loop/SKILL.md +0 -381
  223. package/plugin-artifacts/codex/skills/build-loop/detect-plugins.mjs +0 -82
  224. package/plugin-artifacts/codex/skills/build-loop/eval-guide.md +0 -65
  225. package/plugin-artifacts/codex/skills/build-loop/fallbacks.md +0 -549
  226. package/plugin-artifacts/codex/skills/build-loop/phases/fact-check.md +0 -42
  227. package/plugin-artifacts/codex/skills/build-loop/phases/ui-validation.md +0 -267
  228. package/plugin-artifacts/codex/skills/build-loop/references/advisor-dispatch-ladder.md +0 -62
  229. package/plugin-artifacts/codex/skills/build-loop/references/apple-native-planning.md +0 -439
  230. package/plugin-artifacts/codex/skills/build-loop/references/autonomous-and-per-commit-modes.md +0 -161
  231. package/plugin-artifacts/codex/skills/build-loop/references/capability-routing.md +0 -231
  232. package/plugin-artifacts/codex/skills/build-loop/references/codex-subagents.md +0 -106
  233. package/plugin-artifacts/codex/skills/build-loop/references/coordination.md +0 -161
  234. package/plugin-artifacts/codex/skills/build-loop/references/correction-aware-capture.md +0 -177
  235. package/plugin-artifacts/codex/skills/build-loop/references/experiment-results-template.md +0 -101
  236. package/plugin-artifacts/codex/skills/build-loop/references/independent-auditor.md +0 -72
  237. package/plugin-artifacts/codex/skills/build-loop/references/intent-capability-pack.md +0 -257
  238. package/plugin-artifacts/codex/skills/build-loop/references/intent-exploration-prompts.md +0 -96
  239. package/plugin-artifacts/codex/skills/build-loop/references/leadership.md +0 -72
  240. package/plugin-artifacts/codex/skills/build-loop/references/memory.md +0 -313
  241. package/plugin-artifacts/codex/skills/build-loop/references/modular-systems-pack.md +0 -96
  242. package/plugin-artifacts/codex/skills/build-loop/references/output-style.md +0 -222
  243. package/plugin-artifacts/codex/skills/build-loop/references/pay-it-forward-arch.md +0 -98
  244. package/plugin-artifacts/codex/skills/build-loop/references/phase-1-assess.md +0 -249
  245. package/plugin-artifacts/codex/skills/build-loop/references/phase-2-plan.md +0 -86
  246. package/plugin-artifacts/codex/skills/build-loop/references/phase-3-execute.md +0 -49
  247. package/plugin-artifacts/codex/skills/build-loop/references/phase-4-review.md +0 -341
  248. package/plugin-artifacts/codex/skills/build-loop/references/phase-5-iterate.md +0 -72
  249. package/plugin-artifacts/codex/skills/build-loop/references/phase-6-learn.md +0 -58
  250. package/plugin-artifacts/codex/skills/build-loop/references/recent-design-structures.md +0 -274
  251. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/ASSESSMENT.md +0 -85
  252. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/STANDALONE_TEST_RUN.md +0 -149
  253. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/01-simple-bugfix.md +0 -32
  254. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/02-ui-build-with-iteration.md +0 -48
  255. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/03-multi-failure-escalation.md +0 -60
  256. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/04-ui-build-ibr-absent.md +0 -51
  257. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/05-refactor-navgator-absent.md +0 -71
  258. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/06-recurring-bug-debugger-absent.md +0 -52
  259. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/trace-comparison.md +0 -202
  260. package/plugin-artifacts/codex/skills/build-loop/references/self-recursive-dev.md +0 -77
  261. package/plugin-artifacts/codex/skills/build-loop/references/self-review.md +0 -234
  262. package/plugin-artifacts/codex/skills/build-loop/references/ui-io-contract.md +0 -116
  263. package/plugin-artifacts/codex/skills/build-loop/references/verify-dispatch.md +0 -85
  264. package/plugin-artifacts/codex/skills/build-loop/scanners/audit-design-rules.mjs +0 -476
  265. package/plugin-artifacts/codex/skills/build-loop/scanners/require-visual-evidence.mjs +0 -239
  266. package/plugin-artifacts/codex/skills/build-loop/templates/backlog-item.md +0 -35
  267. package/plugin-artifacts/codex/skills/build-loop/templates/codex-worker-prompt.md +0 -100
  268. package/plugin-artifacts/codex/skills/build-loop/templates/ui-subagent-prompt.md +0 -179
  269. package/plugin-artifacts/codex/skills/build-loop/templates/ux-fix-plan.md +0 -40
  270. package/scripts/build_codex_plugin_artifact.py +0 -321
@@ -1,112 +0,0 @@
1
- <!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
2
-
3
- # Dogfood Reload Checkpoint
4
-
5
- Use a reload checkpoint whenever build-loop changes the runtime that active
6
- agents are using. The checkpoint makes the run stop at a safe boundary, reload
7
- or restart onto the validated build, prove runtime identity, then continue from
8
- Rally.
9
-
10
- ## Trigger
11
-
12
- Run the checkpoint after a validated stage touches any runtime surface:
13
-
14
- - `skills/*/SKILL.md`, `agents/*.md`, `commands/*.md`, hooks, plugin manifests,
15
- MCP config, or plugin install/cache/version behavior.
16
- - Rally Point integration, watcher/status/heartbeat code, leadership, inbox, or
17
- room resolution behavior.
18
- - Memory ingestion/recall/bootstrap/research-trigger paths.
19
- - Self-recursive detector, per-commit mode, or self-modification safety gates.
20
-
21
- Do not force a reload checkpoint for ordinary app code or docs that do not
22
- change the running build-loop runtime.
23
-
24
- Detect the surface first:
25
-
26
- ```bash
27
- python3 scripts/dogfood_reload_checkpoint.py detect \
28
- --changed-file skills/build-loop/SKILL.md \
29
- --changed-file scripts/rally_point/task_heartbeat.py
30
- ```
31
-
32
- ## Protocol
33
-
34
- 1. Finish and validate the current stage.
35
- 2. Create the checkpoint:
36
-
37
- ```bash
38
- python3 scripts/dogfood_reload_checkpoint.py create \
39
- --workdir "$PWD" \
40
- --checkpoint-id "reload-<commit>" \
41
- --commit "<commit>" \
42
- --branch "$(git rev-parse --abbrev-ref HEAD)" \
43
- --changed-file "<runtime-file>" \
44
- --expect-tool claude_code \
45
- --expect-tool codex \
46
- --instructions "Claude Code: restart with claude --plugin-dir <path-to>/build-loop; Codex: use source scripts from this checkout; run rally next/status after reload."
47
- ```
48
-
49
- 3. Post the checkpoint path and instructions to Rally using
50
- `scripts/agent_rally.py handoff` or the native Rally CLI.
51
- 4. Every participating terminal stops at the boundary, reloads/restarts, and
52
- ACKs:
53
-
54
- ```bash
55
- python3 scripts/dogfood_reload_checkpoint.py ack \
56
- --workdir "$PWD" \
57
- --checkpoint-id "reload-<commit>" \
58
- --tool codex \
59
- --session-id "$SESSION_ID" \
60
- --runtime-root "$PWD" \
61
- --runtime-commit "$(git rev-parse --short HEAD)" \
62
- --reload-method "source-checkout" \
63
- --rally-next-status "proceed_solo"
64
- ```
65
-
66
- 5. Continue only when `status.ready == true`:
67
-
68
- ```bash
69
- python3 scripts/dogfood_reload_checkpoint.py status \
70
- --workdir "$PWD" \
71
- --checkpoint-id "reload-<commit>"
72
- ```
73
-
74
- If a terminal is unmanaged, stale, or cannot ACK, record the fallback instead
75
- of waiting silently:
76
-
77
- ```bash
78
- python3 scripts/dogfood_reload_checkpoint.py fallback \
79
- --workdir "$PWD" \
80
- --checkpoint-id "reload-<commit>" \
81
- --tool claude_code \
82
- --decision continue_solo \
83
- --reason "lead lease expired; no active peer in Rally status"
84
- ```
85
-
86
- Fallback decisions are limited to `reassign`, `defer`, or `continue_solo`.
87
-
88
- ## Host Reload Boundaries
89
-
90
- Claude Code:
91
-
92
- - Working-tree dogfood path: `claude --plugin-dir <path-to>/build-loop`.
93
- - `SKILL.md` edits may hot-reload with `/reload-plugins`.
94
- - Hook, agent, command, MCP, and manifest changes require `/reload-plugins` or a
95
- fresh session. Prefer a fresh session for self-recursive stage boundaries.
96
-
97
- Codex / Rally:
98
-
99
- - Use scripts from the source checkout when validating source-built behavior.
100
- - Do not assume a globally installed `rally` or plugin cache is current.
101
- - ACK with the source path, commit hash, and the result of the current
102
- `agent_rally.py status` or `rally next --tool <tool> --json` check.
103
-
104
- ## Report Requirement
105
-
106
- Every self-recursive stage that changes runtime behavior states one of:
107
-
108
- - `reload_checkpoint: ready` with checkpoint id, ACKed tools, runtime roots, and
109
- commit.
110
- - `reload_checkpoint: fallback` with the missing tool and fallback decision.
111
- - `reload_checkpoint: not_required` with the detector output proving no runtime
112
- surface changed.
@@ -1,102 +0,0 @@
1
- <!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
2
-
3
- # Halt-and-Ask Protocol (mode-aware decision handler)
4
-
5
- _Linked from `agents/build-orchestrator.md` §Phase 3 Execute._
6
-
7
- C3's `attestation_lint.py` and C4's `synthesis-critic` cover most synthesis-class drift. **Architectural-class decisions** (where a phase lives, defensive contract shape, error-propagation policy, persistence boundary, hard-fail/retry counters, etc.) fall outside both — the lint has nothing to grep for, and the critic only fires on UI files. This protocol catches those via mode-aware routing: implementers return `status: "blocked"` with `novel_decisions[]` populated, and the orchestrator either auto-picks (long-mode) or surfaces the trade-off table (normal-mode) — escalating to the operator only when the implementer signals low confidence.
8
-
9
- This branch fires at envelope-receive time, **before** the commit step (`references/single-writer-commit-protocol.md`). If `status: "blocked"`, you do NOT enter the commit step at all on this iteration — there's nothing to commit yet.
10
-
11
- **Trigger**: implementer envelope arrives with `status: "blocked"` AND `novel_decisions[]` non-empty (or any envelope with `novel_decisions[]` non-empty, when the do/branch/surface policy is active).
12
-
13
- ## Mode resolution
14
-
15
- Before processing the decision, the orchestrator resolves the current run's mode from `state.execution.budget`:
16
-
17
- | Mode | Trigger | Effect |
18
- |---|---|---|
19
- | **long** | `--long` flag, `--budget >= 4h`, or `overnight` keyword in goal | Auto-pick `recommended_default`; log to `autonomousDefaults[]`; continue |
20
- | **normal** | Default (2h budget, no long-mode trigger) | Surface trade-off table to operator; wait |
21
- | **forced-escalate** | `novel_decisions[i].confidence == "low"` | Surface trade-off table even in long-mode |
22
-
23
- The mode resolution is deterministic; the implementer's `confidence` field is the only thing that can override long-mode → normal-mode behavior.
24
-
25
- ## Procedure (per blocked envelope)
26
-
27
- 1. **Validate the envelope schema.** Every `novel_decisions[i]` MUST have `decision_id`, `options` (non-empty), `recommended_default` (matching one of `options[].id`), `confidence` (`high|med|low`), and per-option `user_impact`/`performance`/`speed`/`cost` (non-empty, not `"n/a"`). Schema violations route to Iterate with the implementer asked to fill in the trade-off fields; do NOT enter the resolution loop with a malformed envelope.
28
-
29
- 2. **Classify via `scripts/classify_action.py`** with the envelope passed in. The classifier returns `DECISION` plus a `decision_state` of `pickable`, `low_confidence`, or `malformed`. Branch on state:
30
- - `pickable` → proceed to step 3 (mode-aware routing)
31
- - `low_confidence` → force-escalate (step 4) regardless of mode
32
- - `malformed` → route to Iterate (step 1 caught most cases; this is the belt-and-braces)
33
-
34
- 3. **Mode-aware routing for `pickable` decisions.**
35
-
36
- **Long-mode (`state.execution.budget.mode in {long, custom, overnight}`):**
37
- - For each `novel_decisions[i]`, take `recommended_default` as `chosen`.
38
- - Append to `state.json.runs[].autonomousDefaults[]` via `scripts/log_decision.py --kind autonomous_default`.
39
- - Emit terminal log: `[auto-pick] decision=<id> chose=<chosen> confidence=<level> rationale="<one-line>"`.
40
- - Re-dispatch the implementer with `resolved_decisions:` containing each pick (same shape as the legacy path).
41
- - **Do not** dispatch a Thinking-tier resolver. The implementer already articulated the trade-offs; auto-pick honors that.
42
-
43
- **Normal-mode:**
44
- - Surface the trade-off table to the operator via `AskUserQuestion` with one row per option showing `user_impact`, `performance`, `speed`, `cost`.
45
- - The operator's pick is logged to `autonomousDefaults[].escalated: true` so the audit trail captures human-in-the-loop decisions identically.
46
- - Re-dispatch with the operator's pick as the resolution.
47
-
48
- 4. **Force-escalate for `low_confidence`.** Even in long-mode, surface the trade-off table to the operator. The implementer is signaling "I cannot pick well" — that's a real ask, not a procedural pause. Logged with `escalated: true` and `reason: "low_confidence"`.
49
-
50
- 5. **Hard-fail counter (N=3) — preserved for backwards compatibility.** If the same `decision_id` returns as `novel_decisions[]` three times in a row (auto-pick or operator-pick didn't resolve it), surface as `❓ Unfixed` in Review-G with the unresolved decisions logged to `state.json.novelDecisionUnresolved[]`. The counter is per-chunk per-decision; reaching it indicates either the implementer's recommended_default is genuinely wrong or the plan needs revision.
51
-
52
- 6. **Persist resolutions.** Continue to write `state.json.novelDecisionResolutions[]` for forensic compatibility:
53
- ```json
54
- {
55
- "chunk_id": "<from plan>",
56
- "decision_id": "<from envelope>",
57
- "attempt": <1|2|3>,
58
- "decision": "<verbatim from novel_decisions[]>",
59
- "implementer_reasoning": "<verbatim>",
60
- "resolution": "<chosen option id + summary>",
61
- "rationale": "<from implementer.recommended_default reasoning OR operator pick>",
62
- "resolved_by": "auto_pick | operator | tier:thinking_fallback",
63
- "resolved_at": "<iso8601>"
64
- }
65
- ```
66
-
67
- 7. **Re-dispatch the implementer** with the **same brief** plus an appended `resolved_decisions:` block containing every resolution generated for this chunk. The implementer applies the resolutions as if they had been part of the plan's `synthesis_dimensions` from the start, and attests against them in the next envelope's `synthesis_attestation`.
68
-
69
- 8. **Loop**. The next envelope can return:
70
- - `status: "completed"` / `"fixed"` / `"partial"` → proceed to the commit step (`references/single-writer-commit-protocol.md`).
71
- - `status: "blocked"` again with **new** `novel_decisions[]` → repeat from step 1. Per-decision counter increments. At N=3, surface as ❓ Unfixed.
72
- - Any other failure status → route per the standard commit step's failure handling.
73
-
74
- ## Legacy Thinking-tier resolver fallback
75
-
76
- The pre-mode-aware version of this protocol dispatched a Thinking-tier resolver via `Agent(subagent_type: "build-loop:build-orchestrator", ...)` for every novel decision. That path remains as a **fallback** when:
77
- - The implementer cannot articulate a `recommended_default` (malformed envelope, attempt 1 only; orchestrator re-dispatches asking for the missing field).
78
- - An operator escalation in normal-mode is interrupted before the operator responds (resume contract).
79
-
80
- When the fallback fires, `resolved_by: "tier:thinking_fallback"` and the resolver returns the same `{"resolution", "rationale", "alternatives_rejected"}` shape as before. Model routing is unchanged from the legacy doc (see "Routing is `tier: thinking`" below).
81
-
82
- ## No new dependencies
83
-
84
- This is a status-branch addition to the existing await-implementer dispatch, not a new runtime. The orchestrator already awaits implementer envelopes; `blocked` is just one more value to switch on. Do NOT introduce LangGraph, a state machine library, or any new event loop. The existing `Agent(...)` dispatch + envelope parsing is the substrate.
85
-
86
- ## State writes touched by this branch
87
-
88
- - `state.json.runs[].autonomousDefaults[]` — per-decision auto-picks with full trade-off context (NEW; written by `scripts/log_decision.py`)
89
- - `state.json.novelDecisionAttempts[<chunk_id>:<decision_id>]` — per-decision counter (≤3 attempts before ❓ Unfixed)
90
- - `state.json.novelDecisionResolutions[]` — durable resolution log (preserved for backward compat)
91
- - `state.json.novelDecisionUnresolved[]` — entries that exhausted N=3
92
-
93
- ## Telemetry
94
-
95
- Per auto-pick: `[auto-pick] decision=<id> chose=<chosen> confidence=<level> mode=<long|normal> rationale="<short>"`.
96
- Per operator escalation: `[escalate] decision=<id> reason=<low_confidence|normal_mode> options=<count>`.
97
- Per re-dispatch: `[redispatch] chunk=<id> decision=<id> attempt=<n>/3 resolution="<short>"`.
98
- On hard-fail: `[hard-fail] ❌ chunk=<id> decision=<id> exhausted 3 attempts — routing to ❓ Unfixed`.
99
-
100
- ## Phase 3 UI spot-check (between chunks)
101
-
102
- Extracted to `references/ui-spotcheck-protocol.md` for MECE separation — that file covers the `uiTouched` signal, dispatch shape, routing on return, iteration budget, skip conditions, and render-path fallback. UI spot-check and the C5 halt-and-ask branch share Phase 3 timing but no machinery — UI spot-check fires after successful commits on `uiTouched: true`, while halt-and-ask fires before commit on `status: blocked`.
@@ -1,302 +0,0 @@
1
- <!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
2
-
3
- # Implementer Envelope Schema — Canonical Contract
4
-
5
- This document defines the **canonical return envelope** every build-loop implementer (Mode A fan-out subagent or Mode B inline self-call) MUST populate. The orchestrator and `scope-auditor` parse implementer output against this schema; missing required fields cause the orchestrator to mark the commit as **malformed** and either request a revision or quarantine the diff.
6
-
7
- Per-brief envelope shapes (round-1 through round-3) are deprecated. New briefs reference this schema by path; legacy shapes are accepted by the orchestrator only when the brief was written before this schema landed.
8
-
9
- ## Required top-level fields
10
-
11
- | Field | Type | Description |
12
- |---|---|---|
13
- | `branch` | string | Git branch the implementer worked on. |
14
- | `commit_sha` | string | SHA of the implementer's commit, OR the literal `"pending"` if the implementer didn't commit (canonical case under Hard rule 4 — orchestrator commits). |
15
- | `files_changed` | array of paths | Authoritative list of paths the orchestrator should stage and commit. Absolute or repo-relative; be consistent. |
16
- | `loc_added` | integer | Lines added across `files_changed`. `0` when none. |
17
- | `loc_removed` | integer | Lines removed across `files_changed`. `0` when none. |
18
- | `f_criteria` | object | Map of F-criterion ID → `"pass"` or `"fail"`. Every F-criterion named in the brief MUST appear. |
19
- | `synthesis_attestation` | object | For each dimension named in the plan's `synthesis_dimensions` block, value is `"applied"`, `"deviated"`, or `"n/a"`. If `"deviated"`, the value MUST be an object `{"status": "deviated", "deviation_reason": "<why>"}`. **Empty object `{}` is allowed when the plan has no `synthesis_dimensions` block** (e.g. methodology commits, infra-only commits). |
20
- | `novel_decisions` | array | Array of decision objects (schema below). Empty array `[]` is OK, **but the field MUST be present**. Implementers add an entry whenever they make a synthesis-class decision NOT enumerated in the plan's `synthesis_dimensions`. When the novel decision is **architectural-class** (where a phase lives, defensive contract shape, error-propagation policy, persistence boundary, etc.), the implementer MUST halt and set `status: "blocked"` (see below) rather than guess. **Each entry MUST include `recommended_default` and `confidence`** so the orchestrator can auto-pick in long-mode and surface trade-offs to the operator in normal-mode. See "novel_decisions[] entry schema" below. |
21
- | `decision_ledger` | array | **Required when the plan has a `synthesis_dimensions` block.** Empty array `[]` is permitted only when the plan has no `synthesis_dimensions` block. Each entry MUST contain all six fields: `dimension` (string — matches a key in `synthesis_attestation`), `owner` (`"plan"` or `"implementer"`), `locked_value` (string — concrete value chosen), `alternatives_rejected` (array of strings, or `["none considered"]`), `evidence_file` (repo-relative path, or `null` when `owner == "implementer"` AND the decision is non-code), `on_new_decision` (enum: `"block" \| "flag" \| "absorb"`; default `"block"` for `risk_reason`-tagged chunks, `"flag"` otherwise). See `## decision_ledger in detail` below. |
22
- | `notes` | string | Free-text. ≤200 words. Judgment calls, surprises, deferred concerns. |
23
- | `wall_clock_seconds` | number | End-to-end implementer wall-clock duration. Orchestrator uses this for tier-mix telemetry. |
24
- | `task_id` | string | Per-dispatch unique identifier echoed from the orchestrator's `[TASK_ID: <id>]` prompt prefix. Format: `t-<8-hex-chars>`. The orchestrator generates this before dispatch and writes one row per dispatch to `~/.bookmark/cost-ledger.jsonl` via `scripts/write_cost_ledger_row.py`. The implementer MUST echo it back unmodified so the row's completed-at update can be correlated against its dispatched-at row. Missing field = malformed envelope. If the brief omits the `[TASK_ID: …]` prefix (legacy briefs), return `task_id: "unknown"`. |
25
- | `status` | string | Optional for routine Phase 3 Execute commits (legacy). REQUIRED when the implementer halts on an architectural-class novel decision: set `status: "blocked"` and return early without committing. See "status enum" below. |
26
- | `capabilities_used` | array of strings | **Additive (Step 7 / audit §5.E).** IDs of `available_capabilities[]` entries from the brief that the implementer actually invoked during this chunk. Empty array `[]` when none were used. The orchestrator joins this against the cost-ledger row and surfaces credit-assignment telemetry in Phase 4 Report. Backward-compat: legacy envelopes that omit the field are accepted; the parser treats absence as `[]`. |
27
- | `capabilities_rejected` | array of objects | **Additive (Step 7 / audit §5.E).** Capabilities from `available_capabilities[]` the implementer considered but did NOT use, with a short reason. Shape per entry: `{"id": "<capability_id>", "reason": "<one-sentence why-not>"}`. Empty array `[]` when none were considered-and-rejected. Powers the self-improvement-architect's Phase 6 credit-assignment pattern detector: a capability rejected with the same reason across N chunks is a signal the registry entry needs revision. |
28
- | `downstream_iterate_outcome` | string or null | **Additive (Step 7 / audit §5.E).** Set by the orchestrator AFTER this commit's downstream Phase 5 Iterate cycle closes (the implementer leaves this `null`; the orchestrator backfills via `write_run_entry.py`). Enum: `"clean"` (no Iterate needed), `"resolved-on-pass-1"`, `"resolved-on-pass-2-or-later"`, `"overflow-to-followup"`, `"abandoned"`. Used by Phase 6 Learn to attribute commit-time decisions to their downstream verification outcomes. Backward-compat: legacy envelopes omit this; the parser treats absence as `null`. |
29
- | `merge_plan` | object or null | **Additive (R2 Wave 1).** Required by the orchestrator's final report when 2+ chunks/worktrees are in flight; optional in per-implementer envelopes as a merge suggestion. Shape: `{"clean_against": ["<sha-or-branch>"], "conflicts_with": ["<chunk-id>"], "suggested_order": ["<chunk-id>", "..."], "merge_rationale": "<one sentence>"}`. The report writer lint blocks missing `clean_against`, `conflicts_with`, or `suggested_order` on multi-chunk reports. |
30
-
31
- **Contract:** missing required fields = malformed envelope. Use empty/null sentinels (`""`, `0`, `[]`, `{}`) for absent data; **do not omit keys**. The orchestrator's parser distinguishes "field absent" (malformed) from "field present but empty" (legitimate).
32
-
33
- ## Optional fields (legacy compatibility)
34
-
35
- The following round-1/round-3 fields remain accepted but are no longer required. When the orchestrator commits on the implementer's behalf, it populates these fields itself:
36
-
37
- - `commit_subject`, `commit_body` — used by Mode A orchestrator-commits flow.
38
- - `verifications` — `{typecheck, lint, adjacent_tests, re_grep}` map; recommended but not required.
39
- - `intentional_non_fixes` — list of in-scope items the implementer chose not to fix; recommended for v2-pattern briefs.
40
- - `status` — enum: `fixed | partial | blocked | scope_breach | deferred_architecture | plan_malformed | evidence_stale | needs_dependency | failed | concurrent_modification_detected | completed`. Required for Phase 5 Iterate fix-plan implementers and for the **halt-and-ask** Phase 3 path (see "status enum" below). Optional for routine Phase 3 Execute commits (the orchestrator infers `completed` from a clean envelope with no `blocked` signal).
41
-
42
- ## status enum — full contract
43
-
44
- | Value | When | Implementer behavior | Orchestrator routing |
45
- |---|---|---|---|
46
- | `completed` / `fixed` | Routine success — all `f_criteria` either pass or are honestly marked fail | Modify working tree, return envelope with `commit_subject` + `commit_body`. Do NOT commit. | Orchestrator commits per Phase 3 commit step. |
47
- | `partial` | Fixed M of N evidence lines; remainder needs human judgment | Same as `fixed`; document remainder in `notes`. | Commit and route remainder to Iterate. |
48
- | `blocked` | **Halt-and-ask: encountered an architectural-class synthesis decision NOT in plan's `synthesis_dimensions`** | Add the decision(s) to `novel_decisions[]` with full reasoning. **Do NOT commit. Do NOT make the decision.** Return early with `status: "blocked"`. `commit_sha: ""`, `files_changed: []` (or partial set if work was done before the block was hit — orchestrator will reset). | Orchestrator dispatches each `novel_decisions[]` entry to the configured **Thinking-tier** resolver (per `references/model-tier-mapping.md`). Resolutions stored in `state.json.novelDecisionResolutions[]`; implementer is re-dispatched with resolutions appended to its brief. Hard-fail counter N=3 per chunk. |
49
- | `scope_breach` | Fix needs a file outside `files_touched` | Return with `needed_file` + `why`. | Orchestrator decides whether to extend scope. |
50
- | `deferred_architecture` | Plan's `architecture_impact: true` flag set | Refuse implementation; return immediately. | Routes to user confirmation in Review-F. |
51
- | `plan_malformed` / `evidence_stale` / `needs_dependency` / `failed` | See `agents/implementer.md` "Failure modes" table | Return with the diagnostic field(s) named there. | Re-plan, retry, or escalate per protocol. |
52
- | `concurrent_modification_detected` | A `files_touched` file was modified by something other than this implementer | Return immediately. | Indicates MECE-partition bug; orchestrator investigates. |
53
-
54
- **`blocked` is distinct from `scope_breach`.** Scope breach is a file-system question ("the fix needs a file I don't own"). Blocked is a synthesis question ("the fix needs an architectural decision the plan didn't make"). Both halt the implementer; they route to different resolvers.
55
-
56
- ### When `blocked` is the right call (vs. logging a `novel_decisions` entry and proceeding)
57
-
58
- The C3 attestation lint catches deterministic synthesis drift; the C4 synthesis-critic catches subjective UI-tone drift. Together they cover most synthesis-class decisions. **Architectural-class decisions** fall outside both — `attestation_lint.py` has nothing to grep for, and `synthesis-critic` only fires on UI files. C5 catches those.
59
-
60
- Block when the missing decision is one of:
61
-
62
- - **Where a phase or responsibility lives** (orchestrator vs. implementer; client vs. server; sync vs. async). E.g. "the plan says route the resolved decisions back to the implementer, but doesn't say whether the orchestrator stores resolutions before or after the re-dispatch."
63
- - **Defensive contract shape.** Whether to fail-closed or fail-open on a backend outage; whether a missing field is a malformed envelope or a legitimate empty.
64
- - **Error-propagation policy.** Re-throw vs. swallow vs. wrap in a domain error; route to Iterate vs. mark as ❓ Unfixed.
65
- - **Persistence boundary.** Where new state lives (state.json vs. a new file vs. memory-only); whether it survives a process restart.
66
- - **Hard-fail counter or retry limit.** When to give up.
67
-
68
- Do NOT block on routine synthesis decisions the lint/critic already cover (placement, cta_tier, visual_weight, copy_tone, empty_state) — log them in `novel_decisions[]` and proceed; the orchestrator + scope-auditor will route them appropriately at commit time.
69
-
70
- When in doubt: block. A wasted Thinking-tier resolution is cheaper than a wrong architectural decision shipped to the diff.
71
-
72
- ## synthesis_attestation in detail
73
-
74
- The `synthesis_dimensions` block was added in C1 (`feat(spec-writing): synthesis_dimensions checklist item`). Plans now enumerate the synthesis-class decisions an implementer is expected to apply (e.g. "uses repo's existing pagination convention", "reuses Toast component for error states", "matches existing API error shape"). The implementer attests against each named dimension:
75
-
76
- - `"applied"` — implementer made the synthesis decision exactly as the plan named it.
77
- - `"deviated"` — implementer deviated from the named synthesis call, with a reason. Use the object form `{"status": "deviated", "deviation_reason": "<one sentence>"}`.
78
- - `"n/a"` — the dimension wasn't reachable from this commit's scope (e.g. a UI-only commit attesting to a backend pagination dimension).
79
-
80
- If the implementer finds itself making a synthesis-class decision that the plan didn't name, the implementer MUST halt that decision path and add the decision to `novel_decisions` instead of attesting silently. The orchestrator and `scope-auditor` then decide whether to extend the plan's `synthesis_dimensions` (route to plan-revise) or accept the novel decision (route to commit).
81
-
82
- ## decision_ledger in detail
83
-
84
- The `decision_ledger` array was added in C5 (`feat(envelope): require decision_ledger when synthesis_dimensions present`). While `synthesis_attestation` records *what the implementer claimed* about each dimension, `decision_ledger` records *why each value was chosen* — creating an audit trail that survives the commit log.
85
-
86
- **Required when:** the originating plan contains a `synthesis_dimensions:` block. Every dimension listed in `synthesis_attestation` must have a corresponding `decision_ledger` entry (matched by the `dimension` field).
87
-
88
- **Permitted absent:** when the plan has no `synthesis_dimensions:` block. In that case, omit the field entirely OR provide an empty array `[]`. Both are valid.
89
-
90
- **Per-entry fields (all six required):**
91
-
92
- | Field | Type | Rule |
93
- |---|---|---|
94
- | `dimension` | string | Must match a key in `synthesis_attestation` for this envelope. |
95
- | `owner` | `"plan"` or `"implementer"` | `"plan"` = the value was prescribed by the plan's `synthesis_dimensions` block. `"implementer"` = discovered or chosen during execution. |
96
- | `locked_value` | string | The concrete value chosen (e.g. `"secondary"`, `"after '<SummaryRow>' in path/to/file"`). Never a status word like `"applied"`. |
97
- | `alternatives_rejected` | array of strings | At least one alternative considered. Use `["none considered"]` only when there was genuinely a single viable option and documenting that is itself informative. |
98
- | `evidence_file` | string or `null` | Repo-relative path to the file where the decision manifests in code. `null` is allowed only when `owner == "implementer"` AND the decision is non-code (e.g. a copy-tone choice with no diff file). For `owner == "plan"` decisions, `null` triggers a WARN from the attestation lint. |
99
- | `on_new_decision` | enum string | One of `"block" \| "flag" \| "absorb"`. Controls what happens if a *new* undeclared decision of the same class is encountered during a future re-dispatch. Default: `"block"` for chunks tagged `risk_reason`; `"flag"` otherwise. |
100
-
101
- **Lint behavior (`--check-ledger`):** the attestation lint enforces that (a) every `synthesis_attestation` dimension has a ledger entry, (b) all six fields are present and non-empty (except `evidence_file` per the `null` rule above), and (c) `on_new_decision` is one of the three enum values. See `scripts/attestation_lint.py` `--check-ledger` flag.
102
-
103
- ## novel_decisions[] entry schema
104
-
105
- Each entry in `novel_decisions[]` is a decision the implementer surfaced to the orchestrator. The orchestrator routes the decision per `references/halt-and-ask-protocol.md` (mode-aware: auto-pick in long-mode, surface trade-offs in normal-mode).
106
-
107
- **Required fields per entry:**
108
-
109
- | Field | Type | Rule |
110
- |---|---|---|
111
- | `decision_id` | string | Stable identifier within the chunk (e.g. `"d1"`, `"cache_strategy"`). Used as the dedupe key in `state.json.runs[].autonomousDefaults[]`. |
112
- | `decision` | string | One-sentence statement of the question. Plain language. |
113
- | `options` | array of objects | At least one option. Each option has the option-object schema below. |
114
- | `recommended_default` | string | The `id` of the option the implementer recommends. Must be present and match one of the `options[].id` values. Cannot be omitted — if the implementer cannot recommend, set `confidence: "low"` and pick its best guess; the orchestrator will escalate. |
115
- | `confidence` | `"high" \| "med" \| "low"` | How sure the implementer is about `recommended_default`. **`low` always escalates**, even in long-mode — the implementer is saying "I cannot pick well." |
116
- | `reasoning` | string | Why the implementer recommends `recommended_default`. Cite plan rubric IDs or constitution rules where applicable. |
117
-
118
- **Option-object schema (each entry in `options[]`):**
119
-
120
- | Field | Type | Rule |
121
- |---|---|---|
122
- | `id` | string | Short identifier (e.g. `"A"`, `"cache"`, `"fetch"`). Used as the value of `recommended_default` and `state.json.runs[].autonomousDefaults[].chosen`. |
123
- | `summary` | string | One-line description of what this option does. |
124
- | `user_impact` | string | What end users see if this option ships. Cannot be `""` or `"n/a"`. If the option has no user-visible impact, write `"none — internal-only change"`. |
125
- | `performance` | string | Quantitative or qualitative perf delta (e.g. `"p95 60ms vs 220ms"`, `"~2× faster on warm cache"`, `"no measurable change"`). |
126
- | `speed` | string | Time-to-ship estimate (e.g. `"~30 min"`, `"~half a day if migration succeeds"`, `"unknown — depends on schema migration"`). |
127
- | `cost` | string | Dollar/quota impact at expected volume (e.g. `"$0"`, `"~$12/mo at 10k req/day"`, `"unknown — depends on caching hit rate"`). |
128
-
129
- **Why user-visible-impact fields are required.** The trade-off table is what the operator sees in normal-mode prompts. If the fields are missing or filled with `"n/a"`, the operator can't make an informed choice — they see a list of opaque options. Schema validation rejects entries where `user_impact` is empty or `"n/a"` (use `"none — internal-only change"` for legitimately invisible work).
130
-
131
- **Example entry:**
132
-
133
- ```yaml
134
- novel_decisions:
135
- - decision_id: "classification_provider"
136
- decision: "Which LLM provider for article classification?"
137
- options:
138
- - id: "A"
139
- summary: "OpenAI gpt-4o-mini for classification"
140
- user_impact: "Higher classification accuracy; users see fewer mis-categorized articles in feed"
141
- performance: "p95 ~800ms per classify call"
142
- speed: "~20 min to wire — existing OpenAI client"
143
- cost: "~$3/mo at 10k articles/day"
144
- - id: "B"
145
- summary: "Groq llama-3-70b for classification"
146
- user_impact: "Comparable accuracy; faster feed refresh — users see new articles ~3× sooner"
147
- performance: "p95 ~250ms per classify call"
148
- speed: "~45 min to wire — new SDK"
149
- cost: "~$0.50/mo at 10k articles/day"
150
- - id: "C"
151
- summary: "Local classifier rules (no LLM)"
152
- user_impact: "Lower accuracy; users see more 'Other' bucketing"
153
- performance: "p95 ~5ms"
154
- speed: "~3 hours to build + tune"
155
- cost: "$0"
156
- recommended_default: "B"
157
- confidence: "med"
158
- reasoning: "Plan rubric r2 prioritizes feed-refresh latency; Groq's 3× speed advantage matters more than accuracy delta. Confidence med because we haven't benchmarked Groq's accuracy on this taxonomy."
159
- ```
160
-
161
- **Routing summary** (see `references/halt-and-ask-protocol.md` for full protocol):
162
-
163
- | Confidence | Long-mode (budget ≥4h or `--long` or `overnight` keyword) | Normal-mode |
164
- |---|---|---|
165
- | `high` | Auto-pick `recommended_default`, log to `autonomousDefaults[]` | Surface trade-off table, wait for operator |
166
- | `med` | Auto-pick, log, flag `confidence: "med"` for judge review | Surface trade-off table, wait |
167
- | `low` | **Escalate** — surface trade-off table even in long-mode | Surface trade-off table, wait |
168
-
169
- ## Examples
170
-
171
- ### Example 1 — Minimal (non-UI commit, no synthesis_dimensions)
172
-
173
- A C2 methodology commit with no UI surface and no `synthesis_dimensions` block in the plan. No ledger required; `decision_ledger` is omitted (equivalent to `[]`).
174
-
175
- ```yaml
176
- envelope:
177
- branch: "exp/synth-decisions-opus-only"
178
- commit_sha: "pending"
179
- files_changed:
180
- - "references/implementer-envelope-schema.md"
181
- - "agents/implementer.md"
182
- - "references/implementer-brief-template.md"
183
- loc_added: 142
184
- loc_removed: 6
185
- f_criteria:
186
- F1: pass
187
- F2: pass
188
- F3: pass
189
- F4: pass
190
- F5: pass
191
- synthesis_attestation: {}
192
- decision_ledger: []
193
- novel_decisions: []
194
- notes: "All three files updated in one commit. Schema doc landed under references/ alongside implementer-brief-template.md per existing convention."
195
- wall_clock_seconds: 184
196
- ```
197
-
198
- ### Example 2 — Rich (UI commit with one deviation + one novel decision)
199
-
200
- A C5 commit adding a settings panel. Plan named four synthesis dimensions: `error_state_pattern`, `loading_state_pattern`, `save_on_change_pattern`, `form_field_layout`. Implementer applied three; deviated on one; surfaced one novel decision the plan hadn't enumerated.
201
-
202
- ```yaml
203
- envelope:
204
- branch: "feat/news-preferences-panel"
205
- commit_sha: "pending"
206
- files_changed:
207
- - "components/settings/NewsPreferencesPanel.tsx"
208
- - "components/settings/NewsPreferencesPanel.test.tsx"
209
- - "app/settings/news/page.tsx"
210
- loc_added: 287
211
- loc_removed: 14
212
- f_criteria:
213
- F1: pass
214
- F2: pass
215
- F3: pass
216
- F4: fail
217
- F5: pass
218
- synthesis_attestation:
219
- error_state_pattern: applied
220
- loading_state_pattern: applied
221
- save_on_change_pattern: applied
222
- form_field_layout:
223
- status: deviated
224
- deviation_reason: "Plan specified two-column grid; existing settings pages all use single-column stacked. Followed in-repo precedent over plan."
225
- novel_decisions:
226
- - decision: "Debounced save-on-change at 400ms instead of immediate."
227
- reasoning: "Toggling 5+ topic checkboxes triggered 5 sequential POSTs in tests; debounce coalesces. Plan didn't address rate-of-change."
228
- notes: "F4 fails because the optimistic-UI test is flaky against the local API mock; tracking as known-flake. Real backend confirms shape is correct."
229
- wall_clock_seconds: 612
230
- ```
231
-
232
- ### Example 3 — Populated ledger (UI commit with placement + cta_tier dimensions)
233
-
234
- A UI commit adding a MetricCard to the dashboard. The plan named two synthesis dimensions; both are attested and each has a full ledger entry.
235
-
236
- ```yaml
237
- envelope:
238
- branch: "feat/dashboard-metric-card"
239
- commit_sha: "pending"
240
- files_changed:
241
- - "components/dashboard/MetricCard.tsx"
242
- - "components/dashboard/MetricCard.test.tsx"
243
- loc_added: 84
244
- loc_removed: 12
245
- f_criteria:
246
- F1: pass
247
- F2: pass
248
- synthesis_attestation:
249
- placement_MetricCard: applied
250
- cta_tier_export_button: applied
251
- decision_ledger:
252
- - dimension: "placement_MetricCard"
253
- owner: "plan"
254
- locked_value: "after `<SummaryRow>` in components/dashboard/MetricCard.tsx"
255
- alternatives_rejected:
256
- - "before `<SummaryRow>` — plan specified after; reversing would change visual grouping"
257
- - "inside `<DashboardGrid>` — would require grid-slot refactor outside this chunk's scope"
258
- evidence_file: "components/dashboard/MetricCard.tsx"
259
- on_new_decision: "flag"
260
- - dimension: "cta_tier_export_button"
261
- owner: "plan"
262
- locked_value: "secondary"
263
- alternatives_rejected:
264
- - "primary — too visually dominant for a utility data-export action"
265
- - "tertiary — insufficient affordance for a trigger users must discover"
266
- evidence_file: "components/dashboard/MetricCard.tsx"
267
- on_new_decision: "flag"
268
- novel_decisions: []
269
- notes: "Both dimensions applied as specified. Ledger entries document why alternatives were rejected."
270
- wall_clock_seconds: 142
271
- ```
272
-
273
- ## Brief-construction: input_filter pattern (Step 7 / audit §5.E)
274
-
275
- The orchestrator constructs each implementer brief from a superset of context (intent, plan, MECE packet, architecture slice, capability shortlist, memory recall, prior chunk envelopes). Without scoping, this can balloon — particularly when many prior chunks have closed.
276
-
277
- OpenAI Agents SDK ships an `input_filter` primitive on its `handoff(...)` call: a function that receives the full `HandoffInputData` (with `input_history`, `pre_handoff_items`, `new_items`) and returns a filtered subset for the downstream agent. Build-loop's structure is **agent-as-tools** (not handoff per Microsoft's distinction — control returns to the orchestrator after each dispatch), so build-loop does not adopt the OpenAI runtime. It DOES adopt the `input_filter` pattern at the brief-construction layer.
278
-
279
- **Pattern adoption (internal, build-loop-native):**
280
-
281
- 1. Each Phase 3 dispatch site in `agents/build-orchestrator.md` builds a candidate brief from the full context superset.
282
- 2. Before dispatching, the orchestrator MAY apply a per-chunk `filter` callable to the brief's context blocks (architecture slice, memory recall, prior envelopes). The callable returns a scoped subset — e.g. only memory entries whose `domain` matches `files_owned`, or only prior envelopes from chunks the current chunk has a dependency edge to.
283
- 3. The implementer brief carries an `applied_filter` annotation (one line: `applied_filter: <name>; dropped: <N entries>`) so commit-auditor knows what was suppressed.
284
- 4. Default behavior is the identity filter (no scoping); filters are opt-in per-chunk in the plan via `chunk[*].brief_filter:` field. The orchestrator's catalogue of built-in filters lives in `references/brief-filters.md` (TBD; not required for this step).
285
-
286
- **Why this matters for the envelope schema**: `capabilities_used[]` / `capabilities_rejected[]` are the implementer's view of brief utility. `applied_filter` is the orchestrator's view. Together they let Phase 6 Learn answer "did we send the right context?" without the implementer having to enumerate everything it ignored.
287
-
288
- **Sources** (full citations in `~/dev/research/topics/agentic-systems/agentic-systems.build-loop-agent-audit-2026-05-20.md` §5):
289
- - OpenAI Agents SDK — `handoff(input_type, on_handoff, input_filter)` primitive (Bucket 1 §5.A core)
290
- - Microsoft Agent Framework — handoff vs agent-as-tools distinction (§5.C)
291
-
292
- ## Parser behavior
293
-
294
- The orchestrator parses envelopes via `scripts/parse_implementer_envelope.py` (TBD; not yet landed). Until then, the build-orchestrator agent reads the envelope inline. Either way, the parsing rules are:
295
-
296
- 1. Strict required-field check. Missing key → malformed.
297
- 2. `synthesis_attestation` cross-check against the plan's `synthesis_dimensions` block — every named dimension must have an attestation entry; extra entries are accepted (forward-compat).
298
- 3. `novel_decisions` non-empty + plan had `synthesis_dimensions` block + `status != "blocked"` → orchestrator routes the diff to `scope-auditor` for synthesis-scope review before committing.
299
- 4. **`status: "blocked"` + `novel_decisions` non-empty** → orchestrator does NOT commit. Each `novel_decisions[]` entry is dispatched to the configured Thinking-tier resolver (see `agents/build-orchestrator.md` §"Phase 3 halt-and-ask branch"). Resolutions are stored in `state.json.novelDecisionResolutions[]`, then the implementer is re-dispatched with resolutions appended to its brief. Loop until `status: "completed"` (or equivalent success) or the hard-fail counter (N=3) is exhausted.
300
- 5. `status: "blocked"` + `novel_decisions: []` → malformed. The block has no payload to resolve. Orchestrator treats as `failed` and routes to Iterate.
301
- 6. Any `f_criteria` value of `"fail"` → orchestrator routes to Iterate (Phase 5) with the failing F-criterion as the entry point.
302
- 7. **`novel_decisions[i]` schema check** (do/branch/surface policy): each entry must include `decision_id`, `options` (non-empty), `recommended_default` (matching one of `options[].id`), and `confidence` (`high|med|low`). Each option must include non-empty `user_impact`, `performance`, `speed`, `cost` fields. Missing or `"n/a"`-valued trade-off fields → orchestrator routes to Iterate with the implementer asked to fill them in. Once the schema is clean, `classify_action.py` returns `DECISION` and the orchestrator routes per `references/halt-and-ask-protocol.md`.