@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,10 +1,10 @@
1
1
  {
2
2
  "name": "build-loop",
3
- "version": "0.36.0",
3
+ "version": "0.43.0",
4
4
  "plugins": [
5
5
  {
6
6
  "name": "build-loop",
7
- "source": "./plugin-artifacts/codex"
7
+ "source": "."
8
8
  }
9
9
  ]
10
10
  }
@@ -6,14 +6,13 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Official marketplace for build-loop — orchestrated 5-phase development loop with optional Learn phase",
9
- "version": "0.36.0"
9
+ "version": "0.43.0"
10
10
  },
11
11
  "plugins": [
12
12
  {
13
13
  "name": "build-loop",
14
14
  "source": "./",
15
15
  "description": "Orchestrated 5-phase development loop (Assess → Plan → Execute → Review → Iterate) plus optional Learn phase. Review combines critic, validate, optimize, fact-check, simplify, and report as ordered sub-steps. Bundles native debug-loop, debugging-memory, and logging-tracer skills without a build-loop MCP server. The logging-tracer skill includes an optional Coding Debugger escalation hop to delegate to the standalone supporting plugin for extended capability (cross-project memory, additional assessors). NavGator integration via cherry-pick bridge. Opus 4.7 orchestrator, Sonnet execution, Haiku pattern-matching.",
16
- "version": "0.36.0",
17
16
  "author": {
18
17
  "name": "Tyrone Ross"
19
18
  },
@@ -32,7 +31,8 @@
32
31
  "code-quality",
33
32
  "self-improvement",
34
33
  "prompt-engineering"
35
- ]
34
+ ],
35
+ "version": "0.43.0"
36
36
  }
37
37
  ]
38
38
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "build-loop",
3
- "version": "0.36.0",
3
+ "version": "0.43.0",
4
4
  "description": "Multi-phase build orchestration with native debugging: assess, plan, execute, review, iterate. Plan-verify gate on Phase 2. Optional UI design gates. Native debug-loop, debugging-memory, and logging-tracer skills provide root-cause investigation without a bundled MCP server. Orchestrator owns when-to-fire; bundled skills own procedural detail; the logging-tracer skill includes an optional Coding Debugger escalation hop to the standalone supporting plugin for extended capability.",
5
5
  "author": {
6
6
  "name": "Tyrone Ross",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "build-loop",
3
- "version": "0.36.0",
3
+ "version": "0.43.0",
4
4
  "description": "Multi-phase build orchestration with native debugging: assess, plan, execute, review, iterate. Plan-verify gate on Phase 2. Optional UI design gates. Native debug-loop, debugging-memory, and logging-tracer skills provide root-cause investigation without a bundled MCP server. Orchestrator owns when-to-fire; bundled skills own procedural detail; bridges are optional escalation hops to supporting plugins for extended capability.",
5
5
  "author": {
6
6
  "name": "Tyrone Ross",
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Keep Build Loop routing focused on public entrypoints and treat helper skills as internal implementation details.
2
+ description: Build Loop exposes one human-facing entry; every skill under skills/ is internal implementation.
3
3
  globs:
4
4
  - "**/*"
5
5
  alwaysApply: true
@@ -7,16 +7,17 @@ alwaysApply: true
7
7
 
8
8
  # Build Loop Surface
9
9
 
10
- Use these public Build Loop entrypoints first:
10
+ Build Loop has exactly one human-facing entry: `/build-loop:run`. Describe the
11
+ work in plain language — build, fix, debug, optimize, research, test, plan — and
12
+ the orchestrator routes it internally. There are no mode flags and no second
13
+ command to choose between.
11
14
 
12
- - `build-loop` for multi-step code work
13
- - `debug-loop` for root-cause debugging
14
- - `optimize` for measurable optimization
15
- - `research` for pre-build investigation
16
- - `knowledge` for durable decisions and lessons
15
+ Every skill under `skills/` sets `user-invocable: false`. A skill becomes public
16
+ only by declaring `public-justification:` in its own frontmatter; today none do.
17
17
 
18
- Treat `skills/` as Build Loop's internal implementation tree. Do not load
19
- helper skills directly unless a public entrypoint, command file, or orchestrator
20
- instruction explicitly references that helper.
18
+ Treat `skills/` as Build Loop's internal implementation tree. Do not load a
19
+ helper skill directly unless `/build-loop:run`, a command file, or an
20
+ orchestrator instruction explicitly references that helper.
21
21
 
22
- For the full policy, read `docs/agent-surface-policy.md`.
22
+ For the full policy, read `docs/agent-surface-policy.md`. It and this file are
23
+ enforced against the code by `scripts/test_agent_surface_policy.py`.
@@ -0,0 +1,33 @@
1
+ ---
2
+ description: Route requests to the right Build Loop skill using the generated skill index at docs/SKILL-INDEX.md.
3
+ globs:
4
+ - "**/*"
5
+ alwaysApply: true
6
+ ---
7
+
8
+ # Skill Index
9
+
10
+ `docs/SKILL-INDEX.md` is the routing table for every skill in this repo. Each row
11
+ names a skill, says when to use it, how it is reached, and whether it is
12
+ user-facing. Read that file to pick the skill that owns a request; read the
13
+ linked `SKILL.md` for the procedure.
14
+
15
+ That file is the only skill list. This rule deliberately does not repeat it —
16
+ three copies of the same list in `CLAUDE.md`, `AGENTS.md`, and `.cursor/rules/`
17
+ would be three places to drift.
18
+
19
+ The index is generated from `skills/**/SKILL.md` frontmatter, so a newly
20
+ authored skill is indexed by regenerating, not by editing the table:
21
+
22
+ ```bash
23
+ python3 scripts/skill_index.py --workdir . --apply # regenerate
24
+ python3 scripts/skill_index.py --workdir . --check # exit 1 when stale
25
+ ```
26
+
27
+ Never hand-edit `docs/SKILL-INDEX.md`. To change a row, edit that skill's
28
+ `SKILL.md` `description:` and regenerate. `--check` is the drift guard; a
29
+ non-zero exit means run `--apply`.
30
+
31
+ Companion rule: `.cursor/rules/build-loop-surface.mdc` covers which skills are
32
+ reachable by a human (today: only `/build-loop:run`). This rule covers where to
33
+ look them up.
package/AGENTS.md CHANGED
@@ -16,43 +16,102 @@ Action classification: SAFE → execute on main; RISKY → isolate to branch + l
16
16
 
17
17
  There is NO gate for code size or complexity. Genuine inability to proceed (missing credential, external blocker) is logged, worked around with available tasks, and reported in the readback — not a stop-and-ask. Oversight is the end-of-run readback, not a mid-run halt.
18
18
 
19
+ ## Privileged commands — always go through the broker
20
+
21
+ **Never run a command that asks macOS for an administrator password directly.** Route it through the broker so the request is named before the dialog appears, shares one authorization with any identical read-only request already in flight, and lands in a durable record:
22
+
23
+ ```bash
24
+ python3 <build-loop>/scripts/privileged_broker.py classify --command "<your command>" --json # is anything privileged?
25
+ python3 <build-loop>/scripts/privileged_broker.py request \
26
+ --purpose "<one plain sentence: why this is needed>" \
27
+ --task-id "$RUN_ID" --repo "$PWD" --initiating-app codex \
28
+ --argv <executable> <args...>
29
+ ```
30
+
31
+ `--purpose` is mandatory; a request without one is refused. That sentence is what the user reads next to the password dialog, which today names only the binary.
32
+
33
+ Exit codes: `0` completed · `1` denied/cancelled/timeout/failed · `2` refused by the broker.
34
+
35
+ **On a `1`, do not retry.** A denial, cancellation, or timeout is cached and replayed, so an immediate retry cannot produce a different answer — it can only produce another dialog. This is the exact 2026-08-20 failure: one Codex turn ran `sfltool dumpbtm` twice, 14 seconds apart, because a refused read returned empty output that was indistinguishable from "no matches". Report the denial and continue with the rest of the work.
36
+
37
+ Claude Code enforces this through a PreToolUse hook. Codex and other hosts follow it as protocol. Full contract, registry format, and risk-class behaviour when the coordinator is unavailable: `skills/build-loop/references/privileged-request-broker.md`.
38
+
19
39
  ## Session-start preflight
20
40
 
21
41
  Run this once at the start of every session, **before any other action**, to learn the coordination state of this repo (active peers, pending ACKs addressed to you, north-star paths, memory locations, guardrails) and to write a presence record so other tools can see you. Rally is coordination metadata, not verification evidence: use it to discover peers, claims, handoffs, and soft file conflicts; confirm code/package/release truth from the repo, tests, manifests, registries, or GitHub directly.
22
42
 
23
43
  ```bash
24
- rally enter --tool codex --json
25
- rally next --tool codex --json
26
- rally room --tool codex --json
44
+ # Rally takes an exclusive lock on .rally/direct.owner.lock for EVERY command,
45
+ # including the read-only ones. Under a read-only sandbox (`codex exec --sandbox
46
+ # read-only`, a hardened CI runner) that open fails EPERM and all three commands
47
+ # below emit a JSON error. Coordination is optional, so check first and skip
48
+ # cleanly rather than opening a session with three failures in the log.
49
+ _rally_writable() {
50
+ local root="$PWD" d="$PWD/.rally"
51
+ if [ -d "$d" ]; then [ -w "$d" ] || return 1
52
+ else [ -w "$root" ] || return 1; mkdir -p "$d" 2>/dev/null || return 1
53
+ fi
54
+ ( : > "$d/.writetest.$$" ) 2>/dev/null || return 1 # mode bits lie under seatbelt; prove it
55
+ rm -f "$d/.writetest.$$" 2>/dev/null
56
+ }
57
+
58
+ if _rally_writable; then
59
+ BASE_TOOL="${BUILD_LOOP_RALLY_TOOL:-codex}" # set to this host family
60
+ RALLY_SESSION_ID="$(python3 scripts/rally_point/actor_identity.py --tool "$BASE_TOOL" --field session-id)"
61
+ export RALLY_SESSION_ID
62
+ RALLY_TOOL="$(python3 scripts/rally_point/actor_identity.py --tool "$BASE_TOOL" --session-id "$RALLY_SESSION_ID")"
63
+ rally enter --tool "$RALLY_TOOL" --session-id "$RALLY_SESSION_ID" --json
64
+ rally next --tool "$RALLY_TOOL" --json
65
+ rally room --tool "$RALLY_TOOL" --json
66
+ else
67
+ echo "[build-loop] rally preflight skipped: .rally is not writable (read-only sandbox)." >&2
68
+ echo "[build-loop] You have NO peer/claim visibility this session. Treat every file as possibly claimed by a peer, and do not assume you are alone." >&2
69
+ fi
27
70
  ```
28
71
 
29
- The command surface is **host-neutral** substitute the `--tool` value for your host: `codex`, `cursor`, `gemini`, `claude_code`, or `other`. If `rally --help` on the local machine disagrees with an older instruction, follow the live CLI help and record the docs drift.
72
+ The command surface is **host-neutral**. Set `BASE_TOOL` to the host family (`codex`, `cursor`, `gemini`, `claude_code`, or `other`); `RALLY_TOOL` is the session-qualified native actor. Never use the bare family as a native Rally actor because two same-host sessions would collapse into one squad, claim owner, and reader cursor. Build Loop's local fallback deliberately keeps the base tool plus its separate session id. If `rally --help` on the local machine disagrees with an older instruction, follow the live CLI help and record the docs drift.
30
73
 
31
74
  When you know your intent or files at session start, include them so peers can see the work immediately:
32
75
 
33
76
  ```bash
34
- rally enter --tool codex --path "<file-or-dir>" --json
35
- rally say claim --tool codex --subject "<what you are doing>" --path "<file-or-dir>" --json
77
+ rally enter --tool "$RALLY_TOOL" --session-id "$RALLY_SESSION_ID" --path "<file-or-dir>" --json
78
+ rally say claim --tool "$RALLY_TOOL" --subject "<what you are doing>" --path "<file-or-dir>" --json
36
79
  ```
37
80
 
38
81
  When you finish or hand off, close the loop:
39
82
 
40
83
  ```bash
41
- rally stop codex --json
84
+ python3 scripts/agent_rally.py stop --workdir "$PWD" \
85
+ --tool "$BASE_TOOL" --session-id "$RALLY_SESSION_ID" --json
42
86
  ```
43
87
 
44
- `rally stop` removes live presence for the selected session/name/tool and releases active claims for cooperative peers. Peers read active work from Rally room state; those records are peer-authored coordination records, never proof that code, tests, releases, or remote refs are correct.
88
+ `agent_rally.py stop` removes live presence for the exact session actor and releases only that session's active claims. Peers read active work from Rally room state; those records are peer-authored coordination records, never proof that code, tests, releases, or remote refs are correct.
45
89
 
46
90
  **Fallback:** if `rally` is not on PATH, proceed without preflight — do **not** crash, do **not** block on it. The Phase 1 Rally Point presence write below covers the minimum coordination contract.
47
91
 
48
92
  **Codex heartbeat parity:** codex sessions emit presence via `session_probe.py --tool codex` (wired in `.codex/hooks.json` `SessionStart`), so their presence/claims/lead decay identically to claude sessions — parity proven by `scripts/rally_point/heartbeat_parity_vectors.json`.
49
93
 
94
+ ## Skill index — how to find the right skill
95
+
96
+ `docs/SKILL-INDEX.md` is the routing table for every skill in this repo: one row per skill giving its id, when to use it, how an agent reaches it, and whether it is user-facing. Read that file when you need to decide which skill owns a request. It is plain markdown with no host-specific syntax, so Codex, Claude Code, Cursor, and any other agent get the same answer from the same file.
97
+
98
+ The index is **generated** from `skills/**/SKILL.md` frontmatter, never hand-maintained — a hand-kept list would be a second source of truth and would drift from the skills it describes. Authoring a skill is therefore enough to get it indexed; regenerate and the row appears.
99
+
100
+ ```bash
101
+ python3 scripts/skill_index.py --workdir . --apply # regenerate after adding or editing a skill
102
+ python3 scripts/skill_index.py --workdir . --check # exit 1 when the index is stale
103
+ ```
104
+
105
+ `--check` is the drift guard: run it before declaring any skill work done, and treat a non-zero exit as "run `--apply`", not as a reason to edit the index. To change a row, edit that skill's `SKILL.md` description. The script scans any plugin root via `--workdir`, so sibling plugins reuse it with no new code.
106
+
50
107
  ## Output style
51
108
 
52
109
  Concise output — say only what the user needs to decide or act; cut narration, restated context, filler; no jargon.
53
110
 
54
111
  Lead each point with the finding. Progressive disclosure: headline first, files/detail below. Number points as standalone **bold-number** paragraphs with a blank line between (plain `1.` list syntax renders compressed). Never use the contrastive-pivot construction ("not X — it's Y", "isn't X, it's Y", "not just X but Y"); state the point directly. Style only, never a gate.
55
112
 
113
+ Direct language — clear verb, clear outcome (the leverage stack): fix clarity top-down — message logic (lead with the answer to the question actually asked; `suggesting` when evidence implies a cause, `because` only when proven), then sentence emphasis (match the opening to the job: actor / outcome / cause / metric / contrast-first; default spine `[Actor] [strong verb] [specific outcome] because [specific cause]`), then word spine (strong verb over weak-verb-plus-filler `was responsible for`→`caused`; data over adverbs `significantly increased`→`increased 42%`; concrete nouns over vague). Enforced by `report_lint.py` (weak-verb / filler-opener / hedge); full tables in `skills/build-loop/references/output-style.md`. Block-level shape for findings and status — the cold-read test (actor / specific object / modality) — is `skills/build-loop/references/status-output-format.md`.
114
+
56
115
  ## Phases
57
116
 
58
117
  | # | Phase | Purpose | Output |
@@ -76,7 +135,7 @@ These run parameters apply on any host — pass them on the invocation (`--flag`
76
135
  | `--autonomous=false` | Classic single pass — run Phases 1–6 once; queue items become `followup/` instead of being drained. |
77
136
  | `--resume <run-id \| latest>` | Re-enter a crashed/killed build mid-flight. Reuses the original `deadline_at` (a 2h budget that died at 1h59m does NOT get a fresh 2h — `resume_resolver.py` owns this). Reads existing `intent.md`/`plan.md`; jumps to remaining chunks. On a normal dispatch with an incomplete prior run detected, offer resume vs fresh before Phase 1. |
78
137
 
79
- **Iteration caps:** classic = 5 per build; autonomous = 25 per build (3 same-verdict per item). Stop conditions: cap reached, budget exhausted, a drained item classifying `confirm`/`block`, 5 consecutive same-criterion failures, or an item whose intent anchor no longer resolves.
138
+ **Iteration caps:** classic = 5 per build; autonomous = 25 per build. For one unresolved item, the third identical verdict requires an independent audit before another attempt; the fifth quarantines the item with evidence. A resolved issue resets the counter. Stop conditions: cap reached, budget exhausted, a drained item classifying `confirm`/`block`, 5 consecutive same-criterion failures, or an item whose intent anchor no longer resolves.
80
139
 
81
140
  **Per-commit mode** (self-recursive builds — when the working dir IS the runtime, e.g. editing build-loop itself): plan once, then run one orchestrator pass per commit so each commit reviews and lands cleanly before the next starts. Auto-on for self-recursive; force with `--per-commit` / `--no-per-commit`.
82
141
 
@@ -88,11 +147,16 @@ The phase logic in this file is host-neutral, but several primitives it names ar
88
147
 
89
148
  | Claude primitive | Codex equivalent | How |
90
149
  |---|---|---|
91
- | `Agent(subagent_type="<name>", …)` | Codex worker, peer process, inline read, or unavailable-fallback | **Preferred:** spawn a Codex worker per `references/codex-subagents.md` (role mapping + permission gate) using `templates/codex-worker-prompt.md` as the prompt skeleton — only under explicit `--parallel` / delegation authorization. **No authorization:** keep the work in the lead session (inline), still writing the same MECE plan + ownership packet. **Cross-vendor verifier:** a reachable peer host via `codex exec <prompt>` or a rally-channel handoff. **None reachable:** record the role as not-run and have the dispatching parent owe it (see the verifier matrix below). |
150
+ | `Agent(subagent_type="<name>", …)` | Native `spawn_agent`, Codex worker, peer process, inline read, or unavailable-fallback | **Preferred:** spawn a Codex worker per `references/codex-subagents.md` (role mapping + permission gate) using `templates/codex-worker-prompt.md` as the prompt skeleton — only under explicit `--parallel` / delegation authorization. **No authorization:** keep the work in the lead session (inline), still writing the same MECE plan + ownership packet. **Cross-vendor verifier:** a reachable peer host via `codex exec <prompt>` or a rally-channel handoff. **None reachable:** record the role as not-run and have the dispatching parent owe it (see the verifier matrix below). **Isolation caveat (verified 2026-08-22, codex-cli 0.149.0):** native `spawn_agent` SHARES the working directory and has no worktree flag, so it does not satisfy the concurrent-dispatch isolation rule on its own — provision explicitly with `git worktree add <path> -b <branch>` then `codex -C <path>`. |
92
151
  | `Skill("<name>")` | Inline-read the skill | Read that skill's `SKILL.md` and follow it inline. Codex auto-discovers root `skills/*/SKILL.md`; for nested build-loop skills, read the file at its path. There is no Codex "invoke skill" call — the SKILL.md body is the instruction set. |
93
- | `AskUserQuestion` | Surface to user | Codex has no structured-choice tool. Print the question + 2–4 labeled options inline and wait for the reply; persist the answer as a DECISION record (see Post-Build steering-decision capture). For non-blocking/reversible choices, pick the default, label it `[ASSUMED: <reason>]`, and continue. |
94
- | `TaskCreate` / `TaskUpdate` / `TaskList` | Backlog files or inline list | Use the host-neutral backlog system (`scripts/backlog.py`, `.build-loop/backlog/`) for durable work items, or a plain inline checklist in the lead session for within-run tracking. Do not block on a task tool that does not exist. |
152
+ | `AskUserQuestion` | `request_user_input` (Plan mode), else surface to user | Codex DOES have a structured-choice tool, `request_user_input`, available in Plan mode (verified 2026-08-22, codex-cli 0.149.0 — this row previously claimed it did not). Outside Plan mode: Print the question + 2–4 labeled options inline and wait for the reply; persist the answer as a DECISION record (see Post-Build steering-decision capture). For non-blocking/reversible choices, pick the default, label it `[ASSUMED: <reason>]`, and continue. |
153
+ | `TaskCreate` / `TaskUpdate` / `TaskList` | `update_plan` (ephemeral) + backlog files (durable) | Use the host-neutral backlog system (`scripts/backlog.py`, `.build-loop/backlog/`) for durable work items, or a plain inline checklist in the lead session for within-run tracking. Codex's native `update_plan` covers within-run plan state; it is ephemeral, so durable work still belongs in `.build-loop/backlog/`. Do not block on a task tool that does not exist. |
95
154
  | `PushNotification` | Surface to user | Print the notification inline in the session; there is no background push channel under `codex exec`. |
155
+ | `ScheduleWakeup` / the `/loop` command | `coordination_watch.py --interval N`, or a launchd/systemd timer | Both are Claude-Code-only (`/loop` is bundled in the Claude binary and has no on-disk surface, so there is nothing to invoke elsewhere). **Never hand-pick a wait primitive.** Ask the resolver and execute what it returns: `python3 "$root"/scripts/wake_scheduler.py --tool codex --wait-kind tracked_subwork\|external\|peer_ack --desired-seconds N --json`. It returns a `decision` (`stop_surface_human` / `harness_auto` / `self_wake`) plus the `directive` and `delay_seconds` for THIS host — Claude Code gets `ScheduleWakeup`, every other host gets the poll watcher or an OS timer. Codex has NO native scheduler (verified 2026-08-22): `codex resume <session-id>` and `codex queue --thread <id> --message <text>` are manual re-entry, not a timer. A `stop_surface_human` decision means the pending action is irreversible; surface it rather than resuming. |
156
+ | `WebSearch` | Native `web_search` | Enable with `codex --search` (interactive). **`codex exec --help` does not list `--search`**, so a non-interactive worker may have no search at all — check before relying on it, and when it is absent record the query you WOULD have run rather than answering from memory (`agents/root-cause-investigator.md` already specifies that fallback). |
157
+ | `WebFetch` | Native `web__run({open:…})`, else `curl` | Available in the Codex runtime when web tooling is enabled; `curl` is the universal floor. Same rule as Claude: fetch only user-provided URLs or links returned by a search. |
158
+ | `EnterWorktree` / `ExitWorktree` | Plain git | `git worktree add <path> -b <branch>` then `codex -C <path>`; remove with `git worktree remove`. There is no built-in — see the isolation caveat on the `Agent` row above. |
159
+ | Finding callers of a symbol — `code-intel refs` on BOTH hosts (**not** Claude's built-in `LSP` tool) | `code-intel refs` CLI, else `mcp__code_intel__refs`, else grep | Same tool both sides. **Prefer the `code-intel` CLI on PATH** (`code-intel refs <file>:<line>:<col>`) — it needs no MCP registration and no tool approval, so it survives `--ask-for-approval never`. The `mcp__code_intel__refs` MCP form (check `codex mcp list`) is equivalent but approval-gated and DENIED under that flag; fall back to grep only when neither is reachable. Claude's built-in `LSP` tool is **not** a substitute: it sees only servers a host plugin registered and returns confident, incomplete answers on every other language with no error (observed 2026-08-29: 1 hit vs code-intel's 4 on the same TypeScript symbol). Record which method you used and honor the `ready` semantics in `agents/scope-auditor.md`. |
96
160
  | `${CLAUDE_PLUGIN_ROOT}` | Repo-relative path or `BUILD_LOOP_ROOT` | Under Codex this variable is unset. Resolve scripts/references relative to the repo root (`root="$(git rev-parse --show-toplevel)"`), or export `BUILD_LOOP_ROOT=<path-to-build-loop>` and substitute it. Every `${CLAUDE_PLUGIN_ROOT}/…` invocation in this file has a working `"$root"/…` or `"$BUILD_LOOP_ROOT"/…` equivalent. |
97
161
 
98
162
  When a primitive is unavailable and no equivalent applies, do not silently skip the step — record it as not-run and surface it in the end-of-run readback so the dispatching parent (or the user) can complete it.
@@ -117,6 +181,7 @@ When a primitive is unavailable and no equivalent applies, do not silently skip
117
181
  - **Keep going until done.** Once the user accepts the plan, every phase is authorized scope. Do not ask the user to confirm each phase. Issues found mid-build route to Iterate. Status updates are fine; permission requests are not. Completed, validated, authorized work commits automatically — asking "should I commit?" or "want me to commit this?" is a workflow violation. `git commit` is classified `auto` by the autonomy gate (exit 0); it is never a permission-gated action. The only commit-adjacent stops are autonomy-gate `confirm`/`block` verdicts on a *push or deploy* command. The only valid stops are: a destructive action not in the plan, a missing credential, externally-blocked work, an explicit hand-off point in the plan, a genuine scope branch the plan does not resolve, or 8 hours wall-clock without a Review pass / 5 consecutive Iterate failures on the same criterion. **NOT stops:** posting a coordination handoff to a peer is *fire-and-continue* (work your owned lane in parallel; only a verifier verdict gating the *next* step is a wait); output volume / turn length is never a stop; "continue or hold?" on authorized, lane-isolated, determinate remaining work is a manufactured fork — finish it. A multi-step prune/refactor/migration with a defined item list runs to completion across that list.
118
182
  - **Commit authorship stays human.** When build-loop manages a commit or push, do not set the official git author, committer, GitHub author, push actor, release actor, or equivalent platform actor to `Claude Code`, `Codex`, or any agent identity. Use the repo's configured human or service identity for official authorship. Agent involvement may be recorded in commit-body notes, run notes, `.build-loop` context, judge decisions, or auxiliary metadata; it must not replace the official author or actor field.
119
183
  - **Self-heal SAFE issues — reactive fix AND proactive self-simplification (C-HEAL / self_heal_safe_issues).** Self-heal has two arms, both active. **Reactive:** when build-loop encounters (a) an error or crash from its own tooling, a hook, a script, a Bash command, or a build/test/lint failure; OR (b) a quality or performance issue from any Review sub-step, self-review, fact-check, simplify, or efficiency scan — ROOT-CAUSE and FIX it, then continue. Classify via `scripts/classify_action.py`: SAFE → apply, verify, commit, continue — no surface, no ask; RISKY → isolate to worktree-branch + log + continue main + surface in report; DECISION/PRODUCTION → surface/escalate. **Proactive:** during deep self-review (and any self-recursive build), the self-review/self-heal loop ALSO proactively simplifies build-loop's own code — reducing complexity, splitting oversized files, removing dead/duplicated logic, adding missing tests — driven by `self_review.py`'s `self_simplification[]` findings. The loop MAY also author new skills and new scripts (new scripts require a colocated `test_<name>.py`). Any change to build-loop's own code MUST pass the SELF-MODIFICATION SAFETY GATE (`self_mod_verify.py --scope auto --auto-revert`, `verdict: pass` required) before commit; on fail the gate auto-reverts and the change is not committed. **Self-modifications execute — they do not stop the loop.** A self-modification that is part of the accepted plan (including edits to the gate, tests, or the self-improvement loop) executes behind the test-suite gate. Build-loop never halts a planned self-modification for human approval. Oversight is post-hoc: (a) self-modifying runs trigger an ADDITIONAL adversarial review (independent-auditor at build scope; the periodic deep self-review re-audits recent self-modifications) — non-blocking; (b) the end-of-run readback reports every self-modification and the additional-review findings. The loop stays on task and reports once, at the end. Structural/architectural self-modifications surface as DECISION, never auto-apply. Full gate in `skills/build-loop/references/self-review.md` §"Self-modification of the restricted repo". **Banned anti-pattern:** bypassing a fixable error — `--no-verify`, xfail-ing a test, commenting out failing code, `|| true` on a real failure — when a SAFE fix exists. Workarounds allowed only when the fix classifies RISKY/DECISION/PRODUCTION or is genuinely infeasible; record both.
184
+ - **Flagged-issue default route — disposition by WHERE the issue lives (C-HEAL / flagged_issue_default_route).** No run ends with an issue merely flagged plus a "want me to?" question. When work surfaces an issue at any phase, the DEFAULT action is set by where it lives: build-loop's OWN repo (plugin or `build-loop-memory`) → EXECUTE the fix (C-HEAL/Iterate, behind the self-mod gate); any OTHER repo → FILE a task on the shared Operations Center queue (the queue of record — do not build a build-loop-side cross-repo tracker) mechanically via `python3 scripts/file_to_operations_center.py --repo <repo> --title <one-line> --spec <desc+fix-hint> --urgency <low|normal|high|critical> --json` (urgency→priority critical=P0…low=P3; the helper shells the Operations Center CLI `add` subcommand and returns a task-id receipt — it NEVER writes the sqlite store directly; a missing binary returns `filed:false`+exit 1 to surface as its own blocker); PRODUCTION-class or genuinely ambiguous (irreversible / user-trust / product-direction / unclear routing) → SURFACE to the user. The report dispositions every open finding (own-repo fix commit, cross-repo Operations Center task id, or surfaced) — a cross-repo finding left as prose is a workflow violation. Full policy: `references/keep-going-policy.md` §"Flagged-issue default route".
120
185
 
121
186
  ## Phase Details
122
187
 
@@ -151,11 +216,11 @@ Run once at the Phase 1 preamble, immediately after `run_id` is known and before
151
216
  --workdir "$PWD" --query "<goal-keywords>" \
152
217
  --output "$PWD/.build-loop/context-bootstrap.json" --json
153
218
  ```
154
- The packet covers: canonical `build-loop-memory` root/project `MEMORY.md` + `constitution.md`, indexed recall via `memory_facade.py`, repo-local `.build-loop/{feedback,state,goal,intent,plan}` files, Codex memory registry `~/.codex/memories/MEMORY.md` plus linked rollout summaries, best-effort Rally/coordination state, **queue counts + top items** (`queues.{issues,backlog,ux-queue,followup,proposals}.{count,top[]}`), a **backlog summary** (`backlog.{open_p01,stale,gated}` from `.build-loop/backlog/INDEX.md` when present), **progressive lessons** (`lessons_progressive[]` — SQLite FTS5, scoped to current work, zero external deps; degrades gracefully when DB absent), and `session_prefs`.
219
+ The packet covers memory, repo-local state, Codex memory, Rally coordination, **executable queue counts** (`queues.{queue,issues,ux-queue,followup}`), non-executable inboxes, a **classed backlog summary** (`backlog.{planned,initiatives,decisions}`), workstream-relevant decisions in `backlog_work.relevant_decisions`, progressive lessons, and `session_prefs`.
155
220
 
156
- **Backlog system (host-neutral, any agent).** Deferred-but-wanted work lives in `<repo>/.build-loop/backlog/` as plain Markdown+YAML items (`items/<ID>.md`, canonical truth) with a regenerated `INDEX.md` (derived view). Read it with `cat <repo>/BACKLOG.md` `INDEX.md` `grep` over `items/*.md`; write it with `python3 ${RUNTIME_PLUGIN_ROOT}/scripts/backlog.py {new,sync,list} --repo <path>` (pure stdlib runs under bare `python3`, no host SDK). `sync` regenerates INDEX deterministically, archives done/dropped (never deletes), flags past-`review_by` items, and mirrors active items one-way into the user's personal memory (`build-loop-memory/projects/<slug>/backlog/`) for a cross-repo view. Full convention, schema, and lifecycle: `references/backlog-system.md`.
221
+ **Backlog system (host-neutral, any agent).** Deferred work lives in `<repo>/.build-loop/backlog/items/` and uses `bucket: planned | initiative | decision`. Planned items are pickup-eligible only at a planning boundary; `promote` creates an executable queue receipt. Initiatives require a user approval receipt plus an isolated non-main worktree and carry `production_policy: prohibited`. Decisions never auto-promote; they surface only when their `workstream`/`related_to` matches active work, and only dependent tasks wait. Use `scripts/backlog.py {new,update,promote,reconcile,sync,list}`; `reconcile` is dry-run-first and lossless.
157
222
  3. **Surface + ask once** (immediately after reading the packet):
158
- - Read `packet.agent_brief` for the one-liner summary, then check each queue: if any `queues.*.count > 0`, emit `#issues=N #backlog=M …` plus the top item titles from `queues.*.top[0].title`.
223
+ - Read `packet.agent_brief`. Queue counts cover executable lanes only. Backlog candidates and relevant decisions come from `packet.backlog_work`; never treat backlog items as queued work until `promote` writes a queue receipt.
159
224
  - Surface `lessons_progressive[].name` (up to 3) as ambient context so planning reflects recent learnings.
160
225
  - Check `session_prefs.continue_from_queues`:
161
226
  - `"always"` → include queue work in the plan without asking.
@@ -171,10 +236,10 @@ After the main build's followup drain completes (or `.build-loop/followup/` was
171
236
  ```python
172
237
  from scripts.context_bootstrap import should_continue_into_queues, pending_queue_items
173
238
  should_continue = should_continue_into_queues(workdir) # True iff session_prefs == "always"
174
- pending = pending_queue_items(workdir) # {"issues": N, "backlog": M}
239
+ pending = pending_queue_items(workdir) # queue/issues/ux-queue/followup
175
240
  ```
176
241
 
177
- Proceed only when BOTH `should_continue is True` AND `pending["issues"] + pending["backlog"] > 0`. When both are true, enter one additional Phase 5 iterate cycle targeting `.build-loop/issues/` then `.build-loop/backlog/` (issues first). Use the same iterate machinery: alignment-checker per item, scope-auditor, independent-auditor post-fix; same iterate-cap and stop conditions. Items classified `PRODUCTION` or `DECISION` surface in report, do not auto-execute. When either condition is false, the run ends — do NOT ask again (the preference was already captured at session start).
242
+ Proceed only when BOTH `should_continue is True` AND `sum(pending.values()) > 0`. Drain `.build-loop/queue/`, then issues, UX queue, and followup. Backlog stays deferred. At a new planning boundary, an agent may select a relevant `planned` candidate and call `backlog.py promote`; it may not auto-pick initiatives or decisions.
178
243
 
179
244
  **Multi-session presence (Rally Point — cross-host: Claude Code, Codex, Gemini CLI, others):**
180
245
 
@@ -182,13 +247,13 @@ Multiple build-loop sessions can run concurrently against the same project acros
182
247
 
183
248
  1. **Write presence and intent at the Phase 1 preamble** (immediately after `run_id` is known), and refresh it at each phase-start. Preferred Rust path:
184
249
  ```bash
185
- rally enter --tool codex --json
186
- rally say presence --tool codex --subject "phase=assess" --json
250
+ rally enter --tool "$RALLY_TOOL" --session-id "$RALLY_SESSION_ID" --json
251
+ rally say presence --tool "$RALLY_TOOL" --subject "phase=assess" --json
187
252
  ```
188
253
  When files are owned, include one `--path` per file or directory so Rally creates explicit file claims:
189
254
  ```bash
190
- rally enter --tool codex --path "src/app.ts" --json
191
- rally say claim --tool codex --subject "phase=execute" --path "src/app.ts" --json
255
+ rally enter --tool "$RALLY_TOOL" --session-id "$RALLY_SESSION_ID" --path "src/app.ts" --json
256
+ rally say claim --tool "$RALLY_TOOL" --subject "phase=execute" --path "src/app.ts" --json
192
257
  ```
193
258
  Embedded fallback path when the Rust `rally` binary is unavailable:
194
259
  ```python
@@ -202,7 +267,7 @@ Multiple build-loop sessions can run concurrently against the same project acros
202
267
  model="<model>", run_id="$RUN_ID", app_slug=slug,
203
268
  phase="assess", files_in_flight=[])
204
269
  ```
205
- `tool` values: `claude_code | codex | gemini | other`. Resolve the channel through `discovery_bridge.resolve(...)` before every direct write. Rust-backed channels use `rally enter` / `rally stop`; embedded fallback writes one file per live session at `<resolved-channel>/sessions/<session-id>.json` (session_id, tool, model, run_id, app_slug, phase, files_in_flight, heartbeat_ts, read cursor). Fire-and-forget — never raises, never blocks.
270
+ Local-fallback `tool` values are host families: `claude_code | codex | gemini | other`. Native Rally uses the session-qualified `RALLY_TOOL`; keep the base family explicit as metadata. Resolve the channel through `discovery_bridge.resolve(...)` before every direct write. Rust-backed channels use `rally enter` / the hardened `scripts/agent_rally.py stop`; embedded fallback writes one file per live session at `<resolved-channel>/sessions/<session-id>.json` (session_id, tool, model, run_id, app_slug, phase, files_in_flight, heartbeat_ts, read cursor). Fire-and-forget — never raises, never blocks.
206
271
  2. **Read active peers** at the preamble and each phase-start:
207
272
  ```python
208
273
  peers = presence.read_active_presence(channel, exclude_session="<sid>")
@@ -341,7 +406,7 @@ Wire all three surfaces (`skills/build-loop/SKILL.md`, `agents/build-orchestrato
341
406
  - Each worker gets minimal context + integration contract (what interfaces to implement) + an intent packet explaining how the subtask fits the north star + a MECE ownership packet defining all seven fields: owned files, non-owned files, interface contracts, integration checkpoints, allowed tools, denied tools, and acceptance criteria (the testable conditions the returning envelope must satisfy — the verifier's per-chunk oracle)
342
407
  - If the host supports typed subagents, map read-only codebase questions to explorer-style agents and disjoint implementation slices to worker-style agents. If the host requires explicit user authorization for subagents, identify parallel-safe groups but execute locally unless the user asked for delegation, parallelization, workers, or a `--parallel` mode.
343
408
  - **Single-entry routing (host-neutral):** every coding task enters through one build-loop invocation; the runtime auto-classifies intent (build / optimize / research / debug / test) and routes accordingly. The host does not pick a mode — classification is internal. This applies equally across coding hosts (Claude Code, Codex, Cursor, Gemini CLI, others).
344
- - **Subagent scaling (host-neutral):** when the host supports parallel delegation (e.g. Codex with `--parallel` authorization), dispatch up to `scripts/parallelism.py effective_max_implementers()` workers machine-aware cap, default 8, ceiling 12 decomposing work into the maximum number of independent MECE chunks. The permission gate still applies: workers only on explicit `--parallel` / delegation authorization. When parallel delegation is unavailable, execute sequentially without asking.
409
+ - **Subagent scaling (host-neutral):** when the host supports parallel delegation (e.g. Codex with `--parallel` authorization), the autonomy supervisor chooses each wave through `scripts/parallelism.py`: the effective width is the minimum of independent MECE work, project/request capacity, CPU headroom, token budget, shared cross-session capacity, and the absolute ceiling of 150. Default project capacity remains 8; adaptive backpressure reduces on provider, memory, disk, thermal, cost, latency, or failure pressure and recovers only after stable windows. The permission gate still applies: workers only on explicit `--parallel` / delegation authorization. When parallel delegation is unavailable, execute sequentially without asking.
345
410
  - Do not delegate ambiguous product decisions, final integration, destructive git operations, push/deploy confirmation, or tasks whose result blocks the immediate next lead-session step.
346
411
  - For UI work: follow established design system or sensible defaults (44px touch targets, 4.5:1 contrast). Every visible element must have meaning, working behavior, a clear user purpose, and a matching entry in the UI input/output contract.
347
412
  - Surface pre-existing issues separately from new work. If an issue impacts users and is local to the current build, plan and fix it automatically; if too large/risky, log user impact and defer.
@@ -395,7 +460,7 @@ Two checkpoints fire automatically after every implementer commit on plans that
395
460
 
396
461
  Both backstops are first-class on the code-tier (fan-out) implementer path where they catch some of the recall gap, and defense-in-depth on the thinking-tier path where they rarely fire.
397
462
 
398
- **Sub-step B — Validate**: when the build touches UI, run build-loop's `ui-validator` first, then check the UI input/output contract for changed surfaces, code-based graders (test, lint, type, build), design-rule scanner, visual evidence capture, and LLM-as-judge for nuanced criteria. Every pass/fail has evidence. Use only headless/programmatic surfaces never auto-open a viewer/dashboard. IBR's interactive viewer / persistent browser sessions stay explicit-only; **UI visual-verification** (BL-3) routes through `build-loop:ibr-bridge` as the primary verifier when the IBR plugin is installed (headless scan is a programmatic action), with `native-ax-driver` / `ui-validator` as fallback. Symbol-only checks (`nm`, `strings`, `otool`) are never a substitute for visual/AX verification on a UI chunk. Scorecard format:
463
+ **Sub-step B — Validate**: when Build Loop updates, compares, or audits a renderable UI design, route headless verification through `build-loop:ibr-bridge` as the primary verifier when IBR is installed, then run `ui-validator`, UI contract checks, code graders, and design-rule scans. When IBR is absent or cannot reach the surface, use `native-ax-driver`, simulator/browser evidence, `ui-validator`, and the static scanner. Never auto-open a viewer/dashboard. The binding trigger and boundary contract is `references/ibr-ui-verification-policy.md`. Symbol-only checks (`nm`, `strings`, `otool`) never substitute for visual/AX verification. Scorecard format:
399
464
 
400
465
  | # | Criterion | Method | Result | Evidence |
401
466
  |---|-----------|--------|--------|----------|
@@ -466,6 +531,8 @@ Log iteration state to `.build-loop/state.json`.
466
531
 
467
532
  Runs after Review sub-step G (Report) on **every** build. Cheap detector + `consolidate_memory.py` + `procedural_governance.py --mode detect-patterns` always fire. A `## Learn` outcome line is always emitted. Three outcome states:
468
533
 
534
+ Run `python3 scripts/learn/__main__.py run --workdir "$PWD" --run-id <recorded-run-id> --source review-g --json`. Dispatch only returned `work_orders[]`, attach results through `attest`, and require `status: complete` with `run_close_lint.py --require-learn`. The receipt is `.build-loop/learn/<run-id>.json`.
535
+
469
536
  - **Accruing** (`runs[] < 3`): cheap detector + consolidation only; report `Learn: accruing (N/3 runs)`.
470
537
  - **Deferred** (debug-only `closeout: false` in dispatch envelope OR budget-exhausted `budget_check.py` envelope `action == "finalize_and_stop"` at Phase 6 entry): cheap detector + consolidation; write `.build-loop/proposals/learn-deferred-<run-id>.md` marker with `{reason, runs_count, budget_action}`; skip Sonnet draft + Opus signoff so Learn never blows the budget ceiling. Report `Learn: deferred — <reason>`.
471
538
  - **Full** (`runs[] >= 3` AND pattern crossing threshold AND not-deferred): full flow below.
@@ -495,7 +562,7 @@ Build loop stores state in `.build-loop/` within the project directory:
495
562
  │ └── <id>.md
496
563
  ├── followup/ # Overflow when iteration cap hit; input to subsequent build
497
564
  │ └── <topic>.md
498
- ├── backlog/ # Deferred-but-wanted work (drained by end-of-run continuation)
565
+ ├── backlog/ # Deferred work; classed and never drained as an execution queue
499
566
  │ ├── INDEX.md # DERIVED view — regenerated by `scripts/backlog.py sync`; do not hand-edit
500
567
  │ ├── items/<ID>.md # CANONICAL items — host-neutral MD+YAML (id/status/priority/type/area/gated/provenance/evidence/review_by)
501
568
  │ └── archive/<ID>.md # done/dropped items (never deleted)
@@ -516,25 +583,27 @@ Runs by default at the end of every run (after Phase 6 Learn if it ran, otherwis
516
583
  2. Stop coordination watchers: SIGTERM any `coordination_watch.py --interval N` processes started during this run (PIDs tracked in `state.json.runs[N].watcherPids[]`).
517
584
  3. **Collapse branches and worktrees (merge winner first, then collapse):** for solo-on-main runs the work is already on `main` — nothing to merge. For multi-worktree runs, merge the winning/validated line(s) to `main` via the normal single-writer commit flow before calling collapse. Then run:
518
585
  ```bash
519
- python3 ${RUNTIME_PLUGIN_ROOT}/scripts/collapse_run.py --workdir "$PWD" --run-id latest --json
586
+ python3 ${RUNTIME_PLUGIN_ROOT}/scripts/collapse_run.py --workdir "$PWD" \
587
+ --run-id <exact-run-id> --branch <exact-branch> \
588
+ --strict --merged-only --owner-released --release-source phase-d-integrator --json
520
589
  ```
521
- The script normalizes `dispatchedWorktrees[]` + `riskyBranches[]` + `createdRefs[]` into one ref list, creates a `git bundle ... --all` under `.build-loop/bundles/` (reversibility), then per ref: MERGED delete branch + remove worktree folder; UNMERGED+`review_hold` keep branch ref, remove worktree folder (→ `kept_for_review`); UNMERGED+no-hold keep branch ref, remove worktree folder (→ `surfaced_unmerged`). Output: `{run_id, bundle_path, deleted[], kept_for_review[], surfaced_unmerged[], errors[], dry_run}`. Fail-soft errors logged, closeout continues.
590
+ Run this from the integrating/primary worktree only after positive owner release; Stop and missing liveness evidence are not release. The script creates and verifies an exact-branch bundle, writes a prepared receipt, rechecks safety and exact branch-to-worktree registration, removes without force, then rechecks the OID and uses Git's checked-out-aware safe branch deletion. Branch hygiene is complete only when output has `strict_success:true`, `bundle_verified:true`, a terminal `receipt_path`, and `errors:[]`. Unmerged/unsafe/ambiguous refs are retained. Full contract: `references/phase-d-closeout.md`.
522
591
  4. Archive the coordination file: move `.build-loop/coordination/<this-coord-file>.md` to `.build-loop/coordination/archived/`.
523
592
  5. Optional `changes.jsonl` rotation: `scripts/rally_point/lifecycle.rotate_changes_log(channel_dir, max_mb=1, max_entries=500)`.
524
- 6. Final post: `post(kind="phase", payload={"phase": "run-closeout", ...})` signals to the channel that this run is done.
593
+ 6. Final post: `post(kind="phase", run_id=<exact-run-id>, workdir=Path("$PWD"), payload={"phase": "run-closeout", ...})` signals to the channel that this run is done. The post returns `None` and writes nothing unless `branch_closeout_gate.py` verifies terminal branch hygiene (solo-on-main/no-ref runs pass directly).
525
594
  7. Write `state.json.runs[N].closeout_status`.
526
595
 
527
596
  **`## Branch hygiene` report block** — every run's final report includes:
528
597
  ```
529
598
  ## Branch hygiene
530
- created N · merged-to-main M (deleted) · kept-for-review R: [<branch-name>, ...]
531
- · surfaced-unmerged U: [<branch-name>, ...] (ask keep/discard) · bundle: <path>
599
+ created N · closed M · retained R: [<branch-name>, ...]
600
+ · bundle-verified: yes|no · receipt: <path/status> · strict-success: yes|no
532
601
  ```
533
602
  When a run created zero refs: `Branch hygiene: clean — no run-created branches/worktrees; on main.`
534
603
 
535
604
  **Structural run-close (Stop hook).** Phase D above is the orchestrator path. An INLINE run (skill-as-methodology, no orchestrator dispatch) never reaches it, so a host `Stop` hook fires the minimum structural closeout with no human prompt — `hooks/closeout.sh stop` → `scripts/stop_closeout.py`:
536
605
 
537
- 1. **Record + surface.** Records the run via `append_run.py` (so Phase 6 Learn's `runs[]` sees it) and runs `judgment_gate.py --agent-tool-available false`, surfacing a WARN `systemMessage` when a stakes-gated run skipped the Frontier judgment layer. A Stop hook cannot dispatch agents, so it auto-records + auto-surfaces the gap — it does not run the retrospective-synthesizer or memory closeout; it leaves `.build-loop/closeout-pending/<run-id>.md` for the next SessionStart (`hooks/closeout.sh session-start`) to surface once. A terminal (`pass`) record also releases the run identity — the `execution` block is archived to `historicalExecutions` and cleared so the next inline effort mints a fresh `build_loop_id` instead of silently resuming a finished run (partial/blocked outcomes keep identity for crash-resume).
606
+ 1. **Record + surface.** Records the run via `append_run.py` (so Phase 6 Learn's `runs[]` sees it) and runs `judgment_gate.py --agent-tool-available false`, surfacing a WARN `systemMessage` when a stakes-gated run skipped the Frontier judgment layer. A Stop hook cannot dispatch agents, so it auto-records + auto-surfaces the gap — it does not run the retrospective-synthesizer or memory closeout; it leaves `.build-loop/closeout-pending/<run-id>.md` for the next SessionStart (`hooks/closeout.sh session-start`) to surface once. Before a terminal (`pass`) record archives and clears `execution`, Stop materializes its branch/worktree as `createdRefs.status=open` with `branch_closeout.status=pending_external_merge`. Stop is a turn boundary: it never writes owner release or a prepared cleanup receipt.
538
607
 
539
608
  2. **Contract.** Advisory + fail-open (always exit 0, never `decision: block`), self-gated on `.build-loop/` presence + this-session match (`current_session_id`, heartbeat-freshness fallback when the host passes no session id), minimal-PATH safe, idempotent with Phase D — the marker is the inline-path sentinel and `runs[]` membership is the Phase-D sentinel, so neither double-records the other. Tests: `scripts/test_stop_closeout.py` + `hooks/test_closeout.sh`.
540
609
 
@@ -542,12 +611,13 @@ When a run created zero refs: `Branch hygiene: clean — no run-created branches
542
611
 
543
612
  **Codex closeout + run-recording fallbacks (do these MANUALLY when hooks do not fire).** Because repo-level Codex hooks are dormant under `codex exec` (verified above), the `Stop`/`SessionStart` shim that auto-records a run does NOT run on its own in a Codex session. Unless the global `~/.codex/hooks.json` is installed AND confirmed firing, a Codex run must perform these steps by hand before declaring the run done (resolve `${RUNTIME_PLUGIN_ROOT}` to the build-loop repo root — see the Codex Execution Adapter):
544
613
 
545
- 1. **Append the run record** — `python3 "$root"/scripts/append_run.py …` so Phase 6 Learn's `runs[]` sees this run. Without it, the run is invisible to the recurring-pattern detector and the milestone log.
614
+ 1. **Append the run record** — `python3 "$root"/scripts/append_run.py …` so Phase 6 Learn's `runs[]` sees this run. Without it, the run is invisible to the recurring-pattern detector and the milestone log. Pass `--push-range <base>..<head>` whenever the run pushed: `append_run` corroborates `--commit` against that range and records `pending` rather than a SHA it cannot reach (this manual path is where the 2026-07-09 wrong-SHA record came from).
546
615
  2. **Run the judgment gate** — `python3 "$root"/scripts/judgment_gate.py --workdir "$PWD" --run-id <run-id> --agent-tool-available false --json`. On a stakes-gated run that stayed at the inline floor, it surfaces the skipped-Frontier-judgment WARN that the Stop hook would otherwise have surfaced.
547
616
  3. **Write the closeout status** — record `state.json.runs[N].closeout_status` (and the inline-path marker `.build-loop/closeout-pending/<run-id>.md` if a follow-up surface is needed), matching what `stop_closeout.py` would have written.
548
- 4. **Phase 6 Learn recording** — run the cheap detector + consolidation and emit the `## Learn` outcome line (accruing / deferred / full) explicitly; it does not auto-fire without the hook.
617
+ 4. **Finalize branch hygiene after merge and positive owner release** — from the integrating/primary worktree run `python3 "$root/scripts/collapse_run.py" --workdir "$PWD" --run-id <exact-run-id> --branch <exact-branch> --strict --merged-only --owner-released --release-source codex-manual --json`. Do not declare branch hygiene clean unless `strict_success:true`, `bundle_verified:true`, a terminal receipt, and `errors:[]` are present.
618
+ 5. **Phase 6 Learn recording** — run `python3 "$root/scripts/learn/__main__.py" run --workdir "$PWD" --run-id <run-id> --source manual --json`; complete returned work orders and emit its `learn_line`.
549
619
 
550
- These are idempotent with the hook path (the marker is the inline sentinel; `runs[]` membership is the Phase-D sentinel), so a later host that DOES fire the hook will not double-record. The rule: **never let "the hook will catch it" stand in for run recording under Codex** — confirm the hook fired, or do the four steps by hand.
620
+ These are idempotent with the hook path (the marker is the inline sentinel; `runs[]` membership is the Phase-D sentinel), so a later host that DOES fire the hook will not double-record. The rule: **never let "the hook will catch it" stand in for run recording or branch finalization under Codex** — confirm the hook fired, or do the five steps by hand.
551
621
 
552
622
  ## Post-Build
553
623
 
@@ -558,3 +628,112 @@ YYYY-MM-DD | what happened | what to do differently
558
628
  ```
559
629
 
560
630
  These entries are loaded during Phase 1 (Assess) of future builds to prevent repeating mistakes.
631
+
632
+ ## Retrospective finding capture
633
+
634
+ Every retrospective MUST file the issues and recommendations it names to their relevant location — a finding left only in prose is a workflow violation. This command surface is host-neutral: run it identically from Claude Code, Codex, or any other host.
635
+
636
+ ```bash
637
+ cd <build-loop>/scripts
638
+ python3 -m retrospective.file_findings plan --retro <path> [--json] # dry-run: what would be filed, where
639
+ python3 -m retrospective.file_findings apply --retro <path> [--json] # execute the plan
640
+ python3 -m retrospective.file_findings lint --retro <path> [--json] # exit 1 if findings are named but not all filed
641
+ ```
642
+
643
+ `plan`/`apply` also accept `--repo-root <dir>` (repeatable, default `~/dev/git-folder`) and `--default-repo <path>` (repo to use for findings naming no recognizable surface).
644
+
645
+ **When `plan` reports `needs_input`, fill the plan and feed it back — do NOT hand-run `backlog.py new`.** `backlog.py new` creates a backlog store in whatever repo it is pointed at, so running it for a finding the ladder routed to `LESSONS-LEARNED.md` scaffolds a store into a repo that deliberately has none. `apply` honors each entry's resolved mechanism:
646
+
647
+ ```bash
648
+ python3 -m retrospective.file_findings plan --retro <path> --json > plan.json
649
+ # edit plan.json: fill each entry.finding.{what_happened,impact,recommendation,why}
650
+ # and clear that entry's "needs_input" list. Use
651
+ # "unknown - <what would determine it>" when you genuinely cannot tell.
652
+ python3 -m retrospective.file_findings apply --retro <path> --plan plan.json --json
653
+ ```
654
+
655
+ `--plan -` reads the filled plan from stdin. `apply` writes the `## Filed findings` table into the retrospective itself, and replaces a stale one rather than stacking a second, so a regenerated retro recovers its receipt without re-filing.
656
+
657
+ **Filing ladder** (per finding, first match wins):
658
+ 1. The affected repo's `.build-loop/backlog/`, via:
659
+ ```bash
660
+ python3 <build-loop>/scripts/backlog.py new --repo <repo> --area <area> --type <type> \
661
+ --title <title> --provenance-source retrospective --provenance-ref <retro-path> \
662
+ --observed <YYYY-MM-DD> --impact <text> --what-happened <text> \
663
+ --recommendation <text> --why <text> --json
664
+ ```
665
+ 2. That repo's `KNOWN-ISSUES.md`
666
+ 3. That repo's `LESSONS-LEARNED.md`
667
+ 4. build-loop's own `KNOWN-ISSUES.md` (fallback when the repo has none of the above)
668
+
669
+ **Five body segments, fixed order, every filed finding:** What happened → When → Impact → Recommendation → Why. `apply` never invents a missing segment — an undeducible one is reported `needs_input` rather than filed hollow.
670
+
671
+ Every retrospective ends with a `## Filed findings` section naming every id/path this run produced — the checkable artifact `lint` requires. `apply` writes it; you do not hand-author it. Lint fails when the section is missing, when it names no location other than the retro itself, or when it accounts for fewer findings than the retro names.
672
+
673
+ `python3 -m retrospective` runs this lint automatically after writing a retrospective and reports the verdict as `filing` in its JSON envelope, so an unfiled finding surfaces without anyone choosing to check.
674
+
675
+ ## Silent assumptions — expose the calls you made without asking
676
+
677
+ Doing ordinary work you make judgement calls the user never sees: what "latest"
678
+ meant, which viewports counted, who the audience was, whether to optimise for
679
+ precision or recall. Each is defensible; none was surfaced. The user finds out
680
+ only when a result is wrong, and then cannot tell which call caused it.
681
+
682
+ The full procedure — the eleven detectors and the two filters — is
683
+ `skills/silent-assumptions/SKILL.md`, with worked examples in
684
+ `skills/silent-assumptions/references/elicitation-detectors.md`. Both are plain
685
+ markdown with no host-specific syntax, so Codex, Claude Code, and Cursor read the
686
+ same instructions. This section is the Codex-specific operating note.
687
+
688
+ **This never blocks.** Make the call, apply your default, keep working. The
689
+ register records work already done. It is the structural opposite of
690
+ `skills/decision-queue/`, which exists because work has STOPPED and the user is
691
+ blocked. Never merge the two.
692
+
693
+ **The file-based path is primary, and it is the whole mechanism under Codex.**
694
+ Codex cannot publish a self-saving artifact, so the interactive page is a
695
+ Claude-only enhancement layered on top and is never required. `register.json`
696
+ plus a generated `dashboard.html` need no artifact host, no browser, and no model
697
+ tokens to refresh.
698
+
699
+ ```bash
700
+ BL=<build-loop>
701
+ DIR="$PWD/.build-loop/decisions/<YYYY-MM-DD>-<slug>"
702
+ mkdir -p "$DIR"
703
+
704
+ python3 "$BL/scripts/assumption_register.py" new \
705
+ --slug <slug> --title "<title>" --repo "$PWD" -o "$DIR/register.json"
706
+ # … replace the example row with real rows elicited by the eleven detectors …
707
+
708
+ python3 "$BL/scripts/assumption_register.py" check "$DIR/register.json" # exit 1 on any error
709
+ python3 "$BL/scripts/assumption_register.py" build "$DIR/register.json" --check # render + lint
710
+ python3 "$BL/scripts/assumption_register.py" read "$DIR/register.json" # after the user edits
711
+ python3 "$BL/scripts/assumption_register.py" promote "$DIR/register.json" --workdir "$PWD"
712
+ ```
713
+
714
+ `check` enforces what a cold reader needs: a `consequence` naming what breaks,
715
+ for whom and when; evidence pointing at a real path, selector, line or count;
716
+ at least two real options with exactly one marked as the default you already
717
+ applied. A row that cannot pass is deleted, not softened.
718
+
719
+ **The user rules by editing the register**, setting `rows[].decision.pick` to a
720
+ 0-based index into that row's `options` and writing `rows[].decision.note`. Then
721
+ `read` reports it, leading with the overrides. **Treat every note as a standing
722
+ instruction, not a comment on that row** — in the reference register 8 of 14
723
+ rulings carried notes and several were policy for all future work.
724
+
725
+ **The one proactive behaviour is an offer, never a prompt.** Score unruled rows
726
+ `high`=2, `med`=1, `low`=0 and offer at 6; any row marked `escalate` offers
727
+ immediately regardless of score. `assumption_register.py offer <register>` exits
728
+ 0 when it is worth one ignorable sentence and 1 when it is not. Never
729
+ `AskUserQuestion`, never mid-task, never twice for the same register.
730
+
731
+ **Tracking across repos reuses the existing decision store.** `promote` calls
732
+ `scripts/write_decision/__main__.py` — the same atomic writer
733
+ `auto-decision-capture` uses — landing rows in
734
+ `build-loop-memory/projects/<project>/decisions/` tagged `silent-assumption`. A
735
+ silent assumption is a decision with a subtype, not a new record type. Do not
736
+ build a second store.
737
+
738
+ Reference register, 20 rows with the user's 14 real rulings:
739
+ the consuming project's `.build-loop/decisions/<date>-<slug>/`.