@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
@@ -10,6 +10,16 @@
10
10
 
11
11
  Entered when Review sub-step A, B, or D finds blocking issues OR `.build-loop/ux-queue/` is non-empty. Critic-only failures (strong-checkpoint from A without touching B) route to Execute instead — no iteration counter burn.
12
12
 
13
+ **Bounded admission at first entry.** Snapshot pre-existing, intent-aligned queue
14
+ work once with `python3 scripts/autonomy_supervisor.py --workdir "$PWD" snapshot
15
+ --goal "<intent>" --limit <configured-or-12>`. Schedule only paths in
16
+ `.build-loop/autonomy/queue-manifest.json`; later queue arrivals wait for the
17
+ next manifest. An issue discovered while executing the current work is handled
18
+ separately: run `classify-related` and execute it in this run when the verdict is
19
+ `execute` (intent-aligned, inside the repo, reversible, and deterministically
20
+ testable). `followup` writes a durable item. `decision` names why the owner is
21
+ needed, available choices, and owner/app/user/other impact.
22
+
13
23
  **Iterate input contract (prioritized work list)**:
14
24
 
15
25
  | Priority | Source | Notes |
@@ -23,25 +33,61 @@ Entered when Review sub-step A, B, or D finds blocking issues OR `.build-loop/ux
23
33
 
24
34
  The "code is cheap, AI agents build fast" framing: the orchestrator does NOT defer based on patch size. It defers only when `architecture_impact: true` (new component, new data flow, navigation graph change, schema migration, auth provider swap). Everything else is fair game for the current loop.
25
35
 
36
+ ## Premise re-validation gate (MANDATORY before scheduling any queue item)
37
+
38
+ A queue item is written at one moment and executed at another. By the time it surfaces, the bug may be fixed, the file moved, or the precondition false. Before scheduling any item drained from `.build-loop/queue/`, `.build-loop/issues/`, `.build-loop/ux-queue/`, or `.build-loop/followup/`:
39
+
40
+ ```bash
41
+ python3 "${CLAUDE_PLUGIN_ROOT:-.}/scripts/premise_revalidation.py" gate --item <path> --repo "$PWD" --json
42
+ ```
43
+
44
+ Exit 0 = `fresh`, schedule it. Exit 1 = do not schedule; route by `reason_code`:
45
+
46
+ | Verdict | Meaning | Route |
47
+ |---|---|---|
48
+ | `fresh` | Within the window, or re-validated with evidence | Schedule |
49
+ | `stale_needs_revalidation` | Past the window (default 7d), never re-checked | Re-check the premise against the live repo, then `validate --note "<what you checked>"`; if it has resolved, close the item with that receipt |
50
+ | `premise_broken` | A cited path or commit the item depends on is genuinely gone | Close the item with the receipt; do not implement |
51
+ | `needs_human_recheck` | A cited path **relocated** (same basename elsewhere), or extraction was ambiguous | Re-read the item against the new path before acting |
52
+
53
+ Freshness falls back to `created` when `validated` is absent, so an item filed minutes ago is fresh by construction — the gate cannot deadlock a queue fed by the current run. Stamp freshness only through:
54
+
55
+ ```bash
56
+ python3 "${CLAUDE_PLUGIN_ROOT:-.}/scripts/premise_revalidation.py" validate --item <path> --note "<evidence>"
57
+ ```
58
+
59
+ `--note` is required. A bare timestamp asserts freshness without evidence, which is the failure being fixed.
60
+
61
+ **Why `needs_human_recheck` is a separate verdict from `premise_broken`.** 2026-08-07: a sweep of 67 queue cards found 16 (24%) whose premise had already resolved — one claimed 65 commits were stranded by a push blocker that had cleared two days earlier. Several card specs even carried hand-written *"VALIDATE FIRST (mandatory) … if stale, write a receipt and STOP"* prose, which proves the need was known and unautomated. The sharper finding: **the careful human sweep was itself stale** — it reported a file as deleted when the file had been relocated, and a repo as 0 ahead when it was 6. A missing path is therefore never enough to declare a premise dead; the gate checks for a same-basename relocation first and asks for a human re-read instead of concluding. Staleness is also repo-dependent (one repo measured 4/4 stale, another 12 live to 1 stale), so the gate is per-item, never a blanket policy.
62
+
63
+ Mirrors the Operations Center design (`validated_at` + refusal at the same gate that already refuses an unrunnable card, commit `3fd0a23`) rather than reinventing it.
64
+
26
65
  **Fan-out** (mode-dependent): After dequeue, partition entries by `files_touched` into independent groups (no overlapping files).
27
66
 
67
+ Before each fan-out and after a provider/worker error, run
68
+ `autonomy_supervisor.py backpressure --signals '<json>'`. Feed available 429
69
+ count, memory percentage, free disk, thermal state, error streak, cost use and
70
+ ceiling, current concurrency, and stable-window count. Obey `pause_new_work`,
71
+ `reduce_concurrency`, `steady`, or `recover_one`; finish in-flight chunks before
72
+ reducing admission. Missing signals retain current concurrency.
73
+
28
74
  - **Top-level mode** (orchestrator invoked directly via the user's session): dispatch up to 4 `implementer` subagents in parallel via `Agent(subagent_type="build-loop:implementer", ...)` per the bundled `agents/implementer.md` (Sonnet 5, scoped tools=[Read, Write, Edit, Bash, Glob, Grep]). Hard cap from `~/.claude/CLAUDE.md` §Sub-Agents. Sequential groups process after the parallel batch.
29
75
  - **Subagent mode** (orchestrator was itself spawned via `Agent(...)` so the no-sub-sub-agents rule applies): degrade to **inline-implementer mode** — iterate the queue serially, apply each fix following the implementer's protocol (scope to `files_touched`, refuse `architecture_impact: true`, verify locally before declaring fixed). No parallelism, same quality bar. The orchestrator surfaces the degradation in Review-F.
30
76
 
31
77
  In both modes, each pass returns the same structured outcome (status + files_changed + verifications). Status routing covers all 9 implementer return values:
32
78
  - `fixed` → mark done (delete the .md)
33
79
  - `partial` → keep entry, re-pass next iteration
34
- - `scope_breach` → ask user before extending scope
80
+ - `scope_breach` → re-plan automatically when the added files remain inside the authorized repo and resolve to the current intent; otherwise route through `classify-related`
35
81
  - `deferred_architecture` → Review-F surfaces for explicit user confirmation
36
82
  - `evidence_stale` → regenerate via `ux_triage.py --clear`, then re-pass
37
83
  - `plan_malformed` → same as `evidence_stale` (regenerate); log id to `.build-loop/state.json.malformedPlans[]`
38
- - `needs_dependency` → ask user; never auto-add deps
39
- - `failed` → re-pass with implementer's `notes` as `additional_context`; after 2 attempts escalate to Opus per `model-tiering`; after 3 surface as Unfixed
84
+ - `needs_dependency` → classify the concrete dependency change with `classify_action.py`; SAFE/RISKY follows its normal branch route, while DECISION/PRODUCTION surfaces with impact
85
+ - `failed` → re-pass with implementer's `notes` as `additional_context`; after 2 attempts escalate per `model-tiering`; after 3 identical verdicts quarantine and continue
40
86
  - `concurrent_modification_detected` → abort current parallel batch (orchestrator partition bug; never transient)
41
87
 
42
88
  Results re-enter Sub-step B for re-validation. For Validate failures (no queue entry), construct an inline plan in the same shape and treat identically.
43
89
 
44
- **UI re-validate hook (when uiTarget != null)**: After each implementer subagent reports back AND before re-entering Sub-step B Validate, the orchestrator runs the build-loop-owned UI re-validate path for affected surfaces: `ui-validator` for web routes when resolvable, native AX driver for macOS, or simulator screenshot/interaction commands for iOS. Catches "fix introduced a new visual or interaction regression" cheaply, without burning a full Validate cycle. If no renderable surface can be resolved, record the gap and fall back to `audit-design-rules.mjs`. IBR is not invoked unless the user explicitly requested it for this build.
90
+ **UI re-validate hook (when uiTarget != null)**: After each implementer subagent reports back AND before re-entering Sub-step B Validate, invoke headless IBR for affected renderable surfaces when installed, following `../../../references/ibr-ui-verification-policy.md`. Run `ui-validator` in parallel for web, with native AX or simulator/browser evidence as the fallback. If no renderable surface can be resolved, record the gap and fall back to `audit-design-rules.mjs`.
45
91
 
46
92
  **Infra self-heal before counting an attempt (C-HEAL / self_heal_safe_issues).** When an Iterate attempt's own tooling, hook, or Bash command FAILS (infra error — non-zero exit that is not a graded-criterion failure, e.g. a pre-commit hook crash, a lint runner that throws on a binary file, a script that errors on a missing env var): ROOT-CAUSE and FIX that infra error first. Classify via `scripts/classify_action.py`. SAFE → apply, verify (re-run the failed action), commit, then resume the Iterate attempt. RISKY/DECISION/PRODUCTION → isolate/surface per the normal routing table. An infra self-heal does NOT burn the iterate budget; only a graded-criterion failure (test/lint/validate failure against the rubric) burns a count. This prevents `--no-verify` bypasses and other workarounds from masking fixable infra errors.
47
93
 
@@ -53,17 +99,39 @@ Per attempt:
53
99
  - **2 consecutive same-root-cause failures** → parallel multi-domain assessment via `build-loop:debugging-memory` `{op:"assess"}`. Pass `model: sonnet` to domain assessors explicitly (override `inherit` default to prevent 4× Opus fan-out from the Opus 4.7 orchestrator). The full procedure is documented in `skills/debug-loop/SKILL.md` §"If stuck — parallel multi-domain assessment".
54
100
  - **3 consecutive same-criterion failures** → causal-tree investigation via `Skill("build-loop:debug-loop")`. Runs its own 7-phase cycle internally; returns with fix applied or hard-stop.
55
101
  3. **Build the prioritized work list** from the table above (Validate failures + UX queue).
56
- 4. **Partition for parallel fan-out**: group by disjoint `files_touched`; dispatch ≤4 subagents in parallel.
102
+ 4. **Partition for parallel fan-out**: group by disjoint `files_touched`; use `autonomy_supervisor.py fanout` for the binding dynamic admission count. The absolute ceiling is 150, while independent work, shared capacity, provider errors, cost, memory, disk, load, latency, and measured thermal stability normally set a lower limit.
57
103
  5. **Execute fixes**; for UI files, run the UI re-validate hook before continuing.
58
104
  6. **Loop back to Review sub-step B** (Validate). Sub-step A (Critic) usually skipped on re-runs unless the fix touched new files. Sub-steps C-F run only on final pass.
105
+ - When the completed queue file has `source: autonomy-dashboard`, read its
106
+ `dashboard_gap_id` and record the validated completion before advancing:
107
+ `python3 scripts/autonomy_dashboard.py --workdir "$PWD" --complete
108
+ "<dashboard_gap_id>" --summary "<what changed>" --evidence
109
+ "commit:<sha>; tests:<result>; audit:<verdict>"`. This moves the file out
110
+ of the executable follow-up queue and makes the dashboard show `Applied`.
59
111
  7. **Followup overflow**: when the iteration cap (5) is reached and queue entries remain, write them to `.build-loop/followup/<topic>.md` for a subsequent `/build-loop:run` invocation. Plan content is already complete — the followup build skips its own Plan phase for these entries.
60
112
  - **`judgment-owed-<run-id>.md`** entries (written by `stop_closeout` when a stakes-gated inline run closed at the inline floor) mean: **dispatch the owed verification layer(s) named in the file for that run** (the Frontier auditor/advisor it skipped), then the file is cleared automatically on the next passing Stop. Do not treat it as a code work-item — it is a dispatch-the-judgment debt.
61
113
  8. **Track**: attempt count, what failed, what was attempted, what changed, queue depth before/after each pass.
62
114
 
115
+ After every item outcome, enforce the per-item limit:
116
+
117
+ ```bash
118
+ python3 scripts/autonomy_supervisor.py --workdir "$PWD" verdict \
119
+ --item "<stable-item-id>" --verdict "<verdict>" --limit 5 --audit-at 3 \
120
+ --actor-id "<worker-id>" --actor-session "<worker-session-id>"
121
+ ```
122
+
123
+ `action: independent_audit` dispatches a different worker/session. The orchestrator first
124
+ records the returned `verify` action in the current run's agent ledger with
125
+ `refs.item_id` and `refs.session_id`, then records its evidence with
126
+ `autonomy_supervisor.py audit --item <stable-item-id> --evidence <evidence>
127
+ --auditor-id <auditor-id> --auditor-session <auditor-session-id>`. Only then may the
128
+ fourth attempt start. `action: quarantine` moves the item to follow-up with all five
129
+ verdict receipts and continues the manifest. A resolved verdict resets the counter.
130
+
63
131
  **Convergence detection**:
64
- - Same criterion fails 2x with same root cause → escalate to user
65
- - Fix A breaks criterion B (oscillation) → flag and ask user
66
- - 3+ criteria fail simultaneously after a fix → systemic issue, stop and reassess
132
+ - Same criterion fails 2x with the same root cause → invoke the causal-tree re-plan; the third identical unresolved verdict requires an independent audit, and the fifth quarantines the item
133
+ - Fix A breaks criterion B (oscillation) → revert the weaker reversible fix, re-plan once, then quarantine on recurrence
134
+ - 3+ criteria fail simultaneously after a fix → treat as one systemic issue, re-plan from the shared cause, and continue unaffected manifest items
67
135
 
68
136
  **Stop condition (QM v0.13.0 — severity-aware, replaces the blunt 5-cap for critical/high)**. The 5-iteration cap still bounds the loop, but it **cannot finalize with an open `critical` or `high` finding** (the no-critical/high exit gate in Review-G, `review_finding_gate.py`, blocks the final pass). On reaching the cap:
69
137
  - **Open `critical`/`high` remain** → do NOT silently ship as ❓ Unfixed. Escalate to the user with the blocking findings and their `closure_proof` gaps; the build does not pass until they close or the user explicitly waives. (If the same approach keeps failing, re-plan instead of burning more iterations.)
@@ -6,30 +6,21 @@
6
6
 
7
7
  ## Phase 6: Learn — Cross-Build Pattern Detection (mandatory; always runs and always reports)
8
8
 
9
+ **One executable path:** `python3 scripts/learn/__main__.py run --workdir "$PWD" --run-id <recorded-run-id> --source review-g --json`. It writes `.build-loop/learn/<run-id>.json`, updates `runs[].learn`, and returns durable `work_orders[]` for agent-only drafting/review. Dispatch those roles and attach results with the CLI's `attest` command. `status: complete` is the only completed Phase 6 state.
10
+
9
11
  **Goal**: detect recurring patterns across recent runs, auto-draft experimental skills/agents to address them, surface them for keep/remove decisions. Closes the loop between "build N times" and "build N+1 is faster because we learned."
10
12
 
11
13
  **Load the `build-loop:self-improve` skill for the full protocol.** (Skill keeps its existing name for backward compatibility; this phase was named "Self-Improvement Review" in v0.2.0 — renamed here to avoid collision with Phase 4 Review.)
12
14
 
13
- **Mandatory contract (v0.30.0+).** Every Phase 6 always does three things: (a) dispatches the Haiku detector (cheap), (b) runs `consolidate_memory.py` + `procedural_governance.py --mode detect-patterns` (already unconditional), and (c) emits a `## Learn` outcome line in the Review-G report even when nothing crosses threshold. Net marginal cost over the prior gated path is one cheap Haiku state-scan per run. The expensive arm (Sonnet draft + Opus signoff) stays conditional on `runs[] >= 3` AND a pattern crossing threshold AND not-deferred. Also user-invokable via `/build-loop:self-improve` to run a scan without a build.
15
+ **Mandatory contract (v0.39.0+).** Every Phase 6 runs the deterministic detector and consolidation stages, persists their receipt, and emits its `learn_line` in Review-G. This path uses no LLM when nothing crosses threshold. Sonnet drafting and promotion review stay conditional and appear as explicit work orders. Also user-invokable via `/build-loop:self-improve` after recording a manual run id.
14
16
 
15
17
  Quick flow:
16
18
 
17
- 1. **Detect** — dispatch `recurring-pattern-detector` (Haiku). Reads **two signal sources**:
18
- - **Signal 1**: `.build-loop/state.json.runs[]` emits `phase_failure`, `manual_intervention`, and `security_finding` patterns (real pain signals; `diagnostic_repeat` and `file_churn` were removed to prevent skill sprawl). **`runs[]` is written by the orchestrator's Review-G, so an INLINE run (skill-as-methodology, no orchestrator dispatch) records nothing and is invisible to Learn.** Any run-close path that did not go through Review-G — inline runs, the memory closeout — MUST record the run with `python3 scripts/append_run.py --workdir "$PWD" --run-id <id> --goal "..." --outcome <done|partial|blocked> [--manual-intervention "<phase>:<note>"] [--phase "<id>:<status>"]` (append-only, idempotent on `run_id`). Without it, inline work never accrues toward the `runs[] >= 3` threshold and recurring inline pain (e.g. the user re-prompting for a skipped step) never becomes a `manual_intervention` pattern.
19
- - **Signal 2**: `.build-loop/proposals/enforce-from-retro/*.md` (the post-push retrospective's enforce-candidates) emits `enforce_recurrence` patterns when the same normalized candidate signature appears across ≥ 2 distinct run-ids. The orchestrator may cite `python3 scripts/enforce_retro_signals.py --workdir "$PWD" --json` as pre-computed input to the agent. This delivers "anything prompted/needed repeatedly enforce" **across** sessions, not just within one.
20
- 2. **Filter** — keep only `confidence: high` or `count >= 4`; manual interventions at lower threshold. Dedupe against existing active/experimental skill names. Cap 2 artifacts per scan.
21
- 3. **Draft** — for each kept pattern, dispatch `self-improvement-architect` (Sonnet). Writes to `.build-loop/skills/experimental/<name>/SKILL.md` with an A/B Experiment section including `run_id` and `co_applied_experimental_artifacts[]` schema.
22
- 4. **Signoff** — orchestrator (Opus 4.7) reviews each draft: APPROVE / REVISE (1 retry) / DISCARD.
23
- 5. **Sample review sweep** — for artifacts in `.build-loop/skills/experimental/` from prior runs: if `.build-loop/config.json.autoPromote` is true AND effective (non-confounded) sample ≥ 8 AND target met → eligible for promotion. **Promotion is no longer silent.** Each eligible candidate goes through (a) advisory review by `promotion-reviewer` (Opus, agent), (b) async user confirmation via PushNotification + TaskCreate fallback. The reviewer's variance verdict (approve / rethink / new_approach) becomes the body of the notification. Move from `experimental/` to `active/` happens only after the user confirms via `/build-loop:promote-experiment <name>`. Regressions and inconclusive-at-2N write proposals to `.build-loop/proposals/` for user confirmation — never auto-delete.
24
-
25
- **Promotion-reviewer dispatch protocol** (per advisory-judge design, plan §12 / `agents/promotion-reviewer.md`):
26
- - For each eligible candidate, dispatch `Agent(subagent_type="build-loop:promotion-reviewer", ...)` with brief fields: `artifact_path`, `experiment_log`, `sample_size`, `target_metric`, `triggering_run_id`, `recent_judge_decisions`.
27
- - Append the returned verdict object to the run's `judge_decisions[]` via `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/write_run_entry/__main__.py --judge-decisions-json <verdict.json>` (combined with other Phase 4 verdicts if any).
28
- - Compose the user-facing notification body from the verdict's `variances[]` and `meta_guidance`. Fire `PushNotification` if available; fall back to `TaskCreate` with subject `"[BUILD-LOOP] Promotion candidate <name>: <verdict> — review needed"`.
29
- - Write a marker file at `.build-loop/proposals/<name>.pending.md` with the verdict + how-to-confirm so the user can resume context later (TTL 14 days; lapsed candidates auto-archive to `.build-loop/proposals/<name>.lapsed.md`).
30
- - **Do not move the artifact.** The user-invoked `/build-loop:promote-experiment <name>` command performs the move after reading the pending verdict.
31
-
32
- 6. **Notify** — concise synthesis appended to Review sub-step G report, including: (a) removal command for each artifact moved or proposed, (b) for each pending promotion: the reviewer verdict + confirmation command.
19
+ 1. **Run** — the executable runner reads four bounded sources: `runs[]`, retro enforce-candidates, learning objects, and tool traces. It consolidates memory, detects and deduplicates patterns, caps new work at two, and performs the sample sweep.
20
+ 2. **Read**no patterns means no agent dispatch. Agent-only work appears in `work_orders[]` with the exact role and payload.
21
+ 3. **Dispatch**call only returned roles. Architects draft experimental skills or agents. Implementers realize enforcement specifications. Promotion reviewers judge drafted or sample-eligible artifacts.
22
+ 4. **Attest** — attach repository-relative artifacts and reviewer verdicts with the CLI. Pending or failed work keeps Phase 6 open.
23
+ 5. **Close** — emit `learn_line`, enforce `run_close_lint.py --require-learn`, and leave promotion to explicit `/build-loop:promote-experiment` confirmation.
33
24
 
34
25
  **Always-run + report gating (v0.30.0)**
35
26
 
@@ -52,6 +43,8 @@ Phase 6 has NO "skip entirely" condition. Three outcome states cover every run:
52
43
 
53
44
  - Consumer default — learned drafts route to `~/.build-loop-extensions/pending/` via `scripts/extensions_route.py --name <ext-slug> --file <draft>`; they do not load until `scripts/extensions_approve.py` moves them into `plugin/`. (Maintainer routing: P2.)
54
45
 
46
+ **Retrospective finding capture — ownership (2026-08-29).** build-loop is the DEFAULT owner of the retrospective-finding-filing flow (`scripts/retrospective/file_findings.py`; see `AGENTS.md` §"Retrospective finding capture" for the exact `plan`/`apply`/`lint` commands and filing ladder). The `ai-assistant` and `ambient agent` projects may also invoke or guide this same flow, but only through those same `file_findings.py` commands — never a parallel reimplementation. This pointer lives in build-loop's own docs only: `ai-assistant` and `ambient agent` are NOT edited by this change.
47
+
55
48
  **What this phase will NOT do**:
56
49
  - Modify the build-loop plugin repo
57
50
  - Promote artifacts cross-project without explicit `/build-loop:promote-experiment <name>`
@@ -0,0 +1,254 @@
1
+ <!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
2
+
3
+ # Privileged-request broker — naming, coalescing, and recording admin prompts
4
+
5
+ Load this when a build touches a command that asks macOS for an administrator
6
+ password, when a user reports unexplained password dialogs, or when changing
7
+ `scripts/privileged_commands.json`.
8
+
9
+ Scope: RUNTIME privileged requests across concurrent agent tasks. The separate
10
+ background-item identity work — giving persistent login items recognizable names
11
+ — is a different problem and is untouched here.
12
+
13
+ ---
14
+
15
+ ## The incident this exists for
16
+
17
+ **2026-08-20, 01:29:11 and 01:29:25 PDT.** A Codex task ran `sfltool dumpbtm`
18
+ twice. macOS showed two administrator-password dialogs naming only `sfltool` —
19
+ no app, no repository, no reason. Parent chain: ChatGPT/Codex → zsh → sfltool.
20
+
21
+ Evidence, from `~/.codex/sessions/2026/08/20/`:
22
+
23
+ | Session | UTC | Command |
24
+ |---|---|---|
25
+ | `01a01e31` | 08:04:07 | `sfltool dumpbtm` (bare, inside a 4-way `Promise.all`) |
26
+ | `01a01e46` | 08:29:11 | `sfltool dumpbtm 2>/dev/null \| rg -n -C 2 '…' \| sed -n '1,260p'` |
27
+ | `01a01e46` | 08:29:25 | `set -o pipefail`⏎`sfltool dumpbtm \| sed -n '1,120p'`⏎`rc=$?` |
28
+ | `01a01e4b` | 08:30:59 | probing where `sfltool` lives (no `dumpbtm`) |
29
+
30
+ The 08:29 pair share a session AND a `turn_id`. Both returned **empty output**
31
+ after 10.6 s and 30.6 s of wall clock — the time the dialog sat on screen.
32
+
33
+ ### Three separable faults
34
+
35
+ **1 — Anonymity.** `sfltool dumpbtm` requires root and is **undocumented**:
36
+ `sfltool(1)` describes only `sfltool archive`. macOS names the leaf binary in the
37
+ dialog and nothing else, so the user could not tell which of several concurrent
38
+ agent tasks was asking, or why.
39
+
40
+ **2 — A failure shaped like a result.** A refused privileged read returns empty
41
+ stdout, which is indistinguishable from "the grep matched nothing". The agent
42
+ could not tell denial from no-results, so it retried 14 seconds later with a
43
+ different wrapper (`set -o pipefail`, `rc=$?`) purely to get diagnostics. **The
44
+ retry was rational.** The second dialog was caused by the first one's outcome
45
+ being unreadable, not by carelessness.
46
+
47
+ **3 — No shared broker.** Three sessions reached for the same host fact inside
48
+ 27 minutes. Nothing coalesced them, named them, or recorded that a prompt
49
+ occurred.
50
+
51
+ ### Baseline, measured
52
+
53
+ `python3 scripts/privileged_audit.py report` over 4,169 transcript files:
54
+
55
+ | metric | before | projected |
56
+ |---|---:|---:|
57
+ | privileged invocations | 13 | 13 |
58
+ | OS prompts | 10 | 7 |
59
+ | coalesced | 0 | 3 |
60
+ | retries | 1 | 0 |
61
+ | unattributed | 13 | 0 |
62
+ | distinct requests | 6 | 6 |
63
+
64
+ `projected` replays the same observed trace through the coalescing rules. It is a
65
+ counterfactual on real input, not a measurement; the measured column fills in from
66
+ the broker's own ledger as traffic routes through it.
67
+
68
+ ---
69
+
70
+ ## What was built
71
+
72
+ | Piece | File | Job |
73
+ |---|---|---|
74
+ | Registry | `scripts/privileged_commands.json` | Which commands are privileged, their scope, mutability, TTL. Data, not code. |
75
+ | Coordinator | `scripts/privileged_broker.py` | Attribution, single-flight, TTL cache, state machine, hash-chained ledger. |
76
+ | Forensics | `scripts/privileged_audit.py` | Read-only. Reconstructs the baseline from transcripts; before/after counts. |
77
+ | Enforcement | `scripts/hooks/pre_bash_privileged.py` | PreToolUse:Bash gate. Redirects a raw privileged command to the broker. |
78
+
79
+ ---
80
+
81
+ ## Using it
82
+
83
+ ```bash
84
+ # What in this command needs root?
85
+ python3 scripts/privileged_broker.py classify --command "sfltool dumpbtm | head" --json
86
+
87
+ # Run it through the coordinator. --purpose is MANDATORY.
88
+ python3 scripts/privileged_broker.py request \
89
+ --purpose "enumerate background-task items to name unlabeled login items" \
90
+ --task-id "$RUN_ID" --repo "$PWD" --initiating-app "Claude Code" \
91
+ --argv sfltool dumpbtm
92
+
93
+ # What is in flight, what is cached, is the ledger intact?
94
+ python3 scripts/privileged_broker.py status --json
95
+ python3 scripts/privileged_broker.py verify-ledger --json
96
+
97
+ # Cancelled a dialog and now want to allow it? Drop the cached answer.
98
+ # This can only ever CAUSE a prompt, never skip one. An in-flight key is left alone.
99
+ python3 scripts/privileged_broker.py forget --key <key-or-prefix> --json
100
+
101
+ # Before/after counts.
102
+ python3 scripts/privileged_audit.py report --window 300
103
+ ```
104
+
105
+ Exit codes for `request`: `0` completed · `1` denied/cancelled/timeout/failed ·
106
+ `2` refused by the broker (bad request, password-capture shape, attempt cap).
107
+
108
+ ### What the user sees before the dialog
109
+
110
+ ```
111
+ ┌ ADMIN PASSWORD REQUEST ─────────────────────────────────────
112
+ │ macOS is about to ask for your admin password for: sfltool
113
+ │ Who Codex · task d71397a3 · thread 01a01e46
114
+ │ Where build-loop (worktree run-864834) · branch main
115
+ │ What /usr/bin/sfltool dumpbtm
116
+ │ Why enumerate background-task items to name unlabeled login items
117
+ │ Scope btm:read · read-only · trust=local-admin
118
+ │ Shared yes — identical read-only requests reuse this for 900s, 2 task(s) waiting
119
+ │ When 2026-08-20T08:29:11Z · request 4f2a…
120
+ └─────────────────────────────────────────────────────────────
121
+ ```
122
+
123
+ ---
124
+
125
+ ## The rules
126
+
127
+ ### Coalescing is narrow
128
+
129
+ Two requests share one authorization only when **all** of these are identical:
130
+ resolved `argv`, `scope`, `trust_domain`, `mutating`, uid, and registry entry.
131
+ Anything different is a different key and inherits nothing.
132
+
133
+ The identity is the **argv**, not the shell string. That is what makes it work on
134
+ the real incident: `sfltool dumpbtm 2>/dev/null | rg …` and `set -o pipefail`⏎
135
+ `sfltool dumpbtm | sed …` are different strings and the same request.
136
+
137
+ ### Mutating never coalesces
138
+
139
+ A mutating request gets a private key directory, never reads the cache, never
140
+ writes one. One request, one prompt, no inheritance — in either direction.
141
+
142
+ ### A negative is remembered; a negative is never upgraded
143
+
144
+ Denial, cancellation, and timeout are cached for `negative_ttl_seconds`
145
+ (default 300 s, 600 s for `sfltool dumpbtm`). During that window an identical
146
+ request is refused **from cache, without a dialog**. This is the control that
147
+ kills the observed retry. A cached terminal state replays verbatim; no branch
148
+ turns a `denied` into a `completed`.
149
+
150
+ The negative cache must not become a trap, so `forget --key` drops a cached
151
+ answer on demand. It removes an answer; the next request has to earn a new one.
152
+
153
+ ### A cap is a rate limit, never a lockout
154
+
155
+ When a result ages out and nobody owns the key, the TTL window rolls: the cached
156
+ result and the prompt-attempt counter are cleared **together**. They have to move
157
+ as a unit — a counter that outlived its window would leave a key that once hit
158
+ the cap permanently `denied_exhausted`.
159
+
160
+ ### The password is never touched
161
+
162
+ macOS performs the authentication. The broker decides who triggers it and shares
163
+ the resulting *output*. It refuses `sudo -S`, `--stdin`, `-A`, `--askpass`, a set
164
+ `SUDO_ASKPASS`, and any `--password=` argument, and never gives the child a piped
165
+ stdin. Nothing password-shaped is ever written to the store.
166
+
167
+ ### A crashed owner cannot strand or storm
168
+
169
+ The owner heartbeats while the command runs. A waiter whose owner has a stale
170
+ heartbeat **and** a dead pid takes the lease over — once. `max_prompt_attempts`
171
+ (default 2) bounds how many dialogs one key may open in a TTL window; past it the
172
+ key goes terminal as `denied_exhausted` and every waiter gets that answer.
173
+
174
+ ### Ambient observes; Ambient never decides
175
+
176
+ Durable visibility is `ledger.jsonl` — append-only and hash-chained, so a deleted
177
+ or edited record is detectable (`verify-ledger`). Live visibility is an optional
178
+ `ambient.notify_command` that receives each event on stdin. **The return value is
179
+ discarded and never inspected**, so no Ambient state can approve, deny, terminate,
180
+ or widen a request. A hostile sink is a covered test case.
181
+
182
+ To surface the event in RossLabs Ambient Agent, run its local daemon and configure
183
+ the broker with its `ambientctl` binary and state directory. The receiver accepts
184
+ only the redacted event on standard input; it records the purpose, requesting app,
185
+ risk class, and broker event id in Ambient activity. It never receives command
186
+ arguments, command output, or a password.
187
+
188
+ ```json
189
+ {
190
+ "ambient": {
191
+ "mode": "live",
192
+ "notify_command": ["/absolute/path/to/ambientctl", "--state-dir", "/absolute/path/to/ambient-state", "systemAccessRequest"],
193
+ "notify_timeout_seconds": 3
194
+ }
195
+ }
196
+ ```
197
+
198
+ ### Unavailability is never approval
199
+
200
+ | Risk class | Coordinator unavailable | Ambient unavailable |
201
+ |---|---|---|
202
+ | read-only | proceed **uncoalesced**, attribution still printed, gap receipt written | proceed; gap receipt |
203
+ | mutating | **refuse** — never run a privileged mutation with no record | proceed; gap receipt |
204
+ | unknown | proceed uncoalesced, never coalesce; gap receipt | proceed; gap receipt |
205
+
206
+ Every receipt carries `unattributed_possible: true`. An empty ledger means *no
207
+ brokered traffic*, never *no privileged request*. `privileged_audit.py` counts
208
+ gaps as `unattributed` for exactly this reason.
209
+
210
+ ---
211
+
212
+ ## Adding a command
213
+
214
+ Edit `scripts/privileged_commands.json`. Never special-case a command in the
215
+ broker.
216
+
217
+ ```json
218
+ {
219
+ "id": "sfltool-dumpbtm",
220
+ "executable": "sfltool",
221
+ "argv_prefix": ["dumpbtm"],
222
+ "scope": "btm:read",
223
+ "mutating": false,
224
+ "cacheable": true,
225
+ "ttl_seconds": 900,
226
+ "negative_ttl_seconds": 600,
227
+ "confidence": "observed",
228
+ "notes": "…"
229
+ }
230
+ ```
231
+
232
+ Longest matching `argv_prefix` wins, so `csrutil status` (`"privileged": false`)
233
+ beats the `csrutil` catch-all. Set `"prompts": false` for a privileged command
234
+ that cannot open a dialog (`sudo -n`) — it is still attributed and recorded, just
235
+ never counted as a prompt. `confidence` is one of `observed` (seen prompting here,
236
+ evidence on file), `documented` (vendor/man page says root), `inferred`
237
+ (behaviour follows from the command class; unverified here).
238
+
239
+ When in doubt, leave `mutating: true`. A read wrongly marked mutating costs one
240
+ extra dialog; a mutation wrongly marked read-only inherits an approval it should
241
+ never have had.
242
+
243
+ ## Known limits
244
+
245
+ - `prompt_opened` is a **proxy**: the broker counts the times it invoked a
246
+ privileged command, because it cannot observe SecurityAgent directly.
247
+ - `sudo` keeps its own sudoers timestamp cache, independent of this broker.
248
+ Consecutive `sudo` calls inside that window may show fewer real dialogs than
249
+ the baseline counts. The SecurityAgent commands have no such cache.
250
+ - The PreToolUse gate covers **Claude Code Bash calls**. Codex sessions are
251
+ covered by the `AGENTS.md` protocol, which is instruction-level, not enforced.
252
+ - `ambient.mode` defaults to `ledger-only`; live push stays unconfigured until a
253
+ `notify_command` is set, and that state is reported once as a coverage gap
254
+ rather than silently.
@@ -0,0 +1,183 @@
1
+ <!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
2
+
3
+ # Resource-Aware Execution
4
+
5
+ This is the canonical token, CPU, execution-profile, and context-conservation
6
+ contract. It is internal. The user still has one Build Loop entry point and no
7
+ resource-mode choices to manage.
8
+
9
+ ## Automatic execution profile
10
+
11
+ Run `scripts/review_trigger.py` in Assess and again after Plan has concrete file
12
+ and line estimates. Persist the last envelope at
13
+ `state.json.execution.resourceProfile`.
14
+
15
+ | Profile | Trigger | Required path |
16
+ |---|---|---|
17
+ | `skip` | Small single-file/config change with no risk signal | Execute directly; deterministic validation only; do not start the full loop |
18
+ | `standard` | Multi-file, non-trivial, or 20+ line work with no high-risk signal | One independent auditor, deterministic validation, report, cheap Learn outcome; fact-check/security/simplify only when their signal exists |
19
+ | `high` | Auth, security, network, persistence, architecture, runtime, model/tool, dependency, large-diff, or ambiguous-risk signal | Full Review and cross-vendor review when reachable |
20
+
21
+ Profiles never bypass production, destructive-delete, secret, security, owed-
22
+ verification, or user-impact gates. A later high-risk signal promotes the run to
23
+ `high`; profiles never demote during a run.
24
+
25
+ ## Resource-aware fan-out
26
+
27
+ Resolve the concrete model first. Then run:
28
+
29
+ ```bash
30
+ python3 "${CLAUDE_PLUGIN_ROOT}/scripts/parallelism.py" \
31
+ --workdir "$PWD" --model "$MODEL" --provider "$PROVIDER" \
32
+ --segment "$SEGMENT" --tier "$TIER" \
33
+ --execution-location "$LOCATION" --output-size "$OUTPUT_SIZE" \
34
+ --agent implementer \
35
+ --independent-items "$READY_CHUNKS" --shared-capacity "$SHARED_CAPACITY" \
36
+ --active-elsewhere "$ACTIVE_ELSEWHERE" --describe --json
37
+ ```
38
+
39
+ Persist the envelope at `state.json.execution.fanout`. `effective_max` is
40
+ capacity, not a dispatch target. Pass it to `autonomy_supervisor.py fanout`;
41
+ the supervisor applies provider/host/cost/failure backpressure and chooses the
42
+ next wave. Dispatch only across a MECE partition. The absolute safety ceiling
43
+ is 150, while every lower live cap remains binding.
44
+
45
+ The role supplies an advisory effort when `--effort` is omitted. Today
46
+ `agentic_execution/T3` prefers `high`, so Codex execution resolves to Terra-high
47
+ and Claude execution resolves to Sonnet-high. Passing `--effort` remains an
48
+ explicit override.
49
+
50
+ ## Accuracy-first token efficiency
51
+
52
+ Minimize tokens only among approaches expected to meet the same acceptance
53
+ criteria. Use this order:
54
+
55
+ 1. Run deterministic scripts for repeatable checks, transforms, inventories,
56
+ and schema validation.
57
+ 2. Use keyword or semantic retrieval to narrow source context before any model
58
+ reads it.
59
+ 3. Route bounded scanning and classification to Pattern-tier or local models
60
+ when a deterministic verifier can judge the output.
61
+ 4. Read the relevant implementation and tests before proposing complex code.
62
+ Early source grounding is cheaper than rework and repeated troubleshooting.
63
+ 5. Use measured ledger rows to tune prompts, effort, and fan-out after quality
64
+ passes. Never count an unmatched or lower-quality run as a token win.
65
+
66
+ ### Adaptive backpressure
67
+
68
+ - Start with a bounded ramp of at most four workers.
69
+ - Reduce admissions after repeated 429s, worker errors, memory pressure,
70
+ serious thermal state, low disk, or 80% cost use.
71
+ - Pause new work at critical thermal/memory/disk pressure or the cost ceiling.
72
+ - Recover one worker only after two stable telemetry windows.
73
+ - External cooling changes measured thermal stability; it does not bypass CPU,
74
+ token, cost, ownership, or provider limits.
75
+
76
+ Every tool call and result reconciles into
77
+ `.build-loop/telemetry/tool-traces.jsonl` as an OTel-shaped, bounded, redacted
78
+ span. The supervisor consumes error, retry, 429, and latency summaries; Phase 6
79
+ consumes the same signals for recursive learning.
80
+
81
+ ### Synthetic load safety
82
+
83
+ Never launch an unbounded background CPU loop. Run load-sensitive checks through
84
+ `build-loop-load-probe`, which caps admission, names every worker, gives each
85
+ worker an internal hard deadline, and verifies cleanup:
86
+
87
+ ```bash
88
+ build-loop-load-probe --workers 4 --duration-seconds 30 -- npm test -- --runInBand
89
+ ```
90
+
91
+ The lifecycle receipt contains only a fixed product/purpose, opaque run id, PID
92
+ birth identity, process group, timestamps, and cleanup result. It must never
93
+ contain prompts, URLs, secrets, repository paths, or the wrapped command line.
94
+ Host-wide cleanup may signal a probe only when its owned receipt, PID birth
95
+ identity, process-group identity, marker, and expired deadline all match.
96
+ Unknown or ambiguous processes remain advisory.
97
+
98
+ ### Cloud inference: token-led
99
+
100
+ 1. Use the median measured raw tokens for the same model and agent from the
101
+ cost ledger when available.
102
+ 2. Otherwise use the model/output/effort T-shirt estimate.
103
+ 3. Divide the wave token budget by per-worker demand.
104
+ 4. Apply configuration, CPU headroom, and hard-ceiling caps as secondary limits.
105
+
106
+ Default heuristic demand before output/effort multipliers:
107
+
108
+ | Model size | Typical role | Tokens/worker |
109
+ |---|---|---:|
110
+ | small | Pattern/utility | 8,000 |
111
+ | medium | Code/workhorse | 16,000 |
112
+ | large | Thinking | 24,000 |
113
+ | xlarge | Frontier | 32,000 |
114
+
115
+ Output multipliers are small `0.5`, medium `1.0`, large `1.75`. Effort
116
+ multipliers are low `0.75`, medium `1.0`, high `1.25`, xhigh `1.75`, max
117
+ `2.25`, ultra `3.0`. These values are routing heuristics, not pricing claims.
118
+ Measured data replaces them automatically.
119
+
120
+ ### Local inference: CPU-led
121
+
122
+ Local workers reserve CPU according to model size: small `1`, medium `2`, large
123
+ `4`, xlarge `8` cores per worker. The resolver keeps two cores for the lead and
124
+ OS. Token limits apply to local inference only when the caller supplies one;
125
+ local token throughput does not silently override CPU safety.
126
+
127
+ ### Unknown location
128
+
129
+ Pass the provider/location when known. `auto` recognizes Ollama, MLX, LM Studio,
130
+ llama.cpp, and explicit local adapters. Other models default to cloud so an
131
+ unknown provider receives the conservative token-led path.
132
+
133
+ ## Token telemetry
134
+
135
+ `cost_ledger_hook.py` always records dispatch identity, run, phase, execution
136
+ location, model/output T-shirt sizes, and a heuristic token estimate. Provider
137
+ adapters enrich the same task id through `write_cost_ledger_row.py` with:
138
+
139
+ - `input_tokens`
140
+ - `output_tokens`
141
+ - `cache_read_input_tokens`
142
+ - `cache_creation_input_tokens`
143
+ - `phase`, `fanout_limit`, and `fanout_primary_constraint`
144
+
145
+ Keep measured buckets separate from `tokens_estimate`. Benchmark conclusions
146
+ use measured rows only.
147
+
148
+ ## Bounded context
149
+
150
+ - Capture each assembled brief once under `.build-loop/briefs/<run>/<chunk>.md`.
151
+ - Pass goal, ownership, interface, acceptance criteria, falsifier, and file
152
+ pointers. Do not paste full shared documents into every worker.
153
+ - Preserve stable prefixes for provider caching.
154
+ - Use the resolved model's `prompting_profile`; compressed/standard profiles
155
+ remove repeated examples and rationale while keeping safety and acceptance
156
+ contracts.
157
+ - Prefer one context for sequential/cross-cutting work. Fan-out must earn its
158
+ repeated brief cost through genuinely independent chunks.
159
+
160
+ ## Proposal maintenance
161
+
162
+ Before Phase 6 pattern detection, run the reversible consumer once:
163
+
164
+ ```bash
165
+ python3 "${CLAUDE_PLUGIN_ROOT}/scripts/drain_self_review_proposals.py" \
166
+ --workdir "$PWD" --archive --stamp "$RUN_ID" --json
167
+ ```
168
+
169
+ This archives superseded, stale, and non-actionable proposals before any model
170
+ reads the queue. It never applies findings and never deletes evidence.
171
+
172
+ ## Benchmark
173
+
174
+ Use `evals/token-efficiency/tasks.jsonl` as the starter task set. Record results
175
+ for identical task id, repository snapshot, and model, then compare with:
176
+
177
+ ```bash
178
+ python3 scripts/token_efficiency_benchmark.py --results results.jsonl \
179
+ --baseline current --candidate resource-aware --json
180
+ ```
181
+
182
+ The harness excludes estimates and unmatched tasks from the A/B token claim.
183
+ Quality must remain non-inferior before a token reduction counts as a win.
@@ -8,7 +8,7 @@ A run is **self-recursive** when the build-loop working tree IS the loaded runti
8
8
  Recommended: pass the working tree directly to Claude Code at session start.
9
9
 
10
10
  ```sh
11
- claude --plugin-dir ~/dev/git-folder/build-loop
11
+ claude --plugin-dir <path-to-your-local-checkout>
12
12
  ```
13
13
 
14
14
  `--plugin-dir` takes session precedence over any cached marketplace copy, and Claude Code sets `CLAUDE_PLUGIN_ROOT` to that directory. The detector reads it. No symlink, no `~/.claude/` mutation.
@@ -16,7 +16,7 @@ claude --plugin-dir ~/dev/git-folder/build-loop
16
16
  Convenience alias (optional, in `~/.zshrc` or `~/.bashrc`):
17
17
 
18
18
  ```sh
19
- alias claude-bl='claude --plugin-dir ~/dev/git-folder/build-loop'
19
+ alias claude-bl='claude --plugin-dir <path-to-your-local-checkout>'
20
20
  ```
21
21
 
22
22
  Use the alias when you intend to dogfood build-loop changes; use plain `claude` for normal work that should run against the released cache version.