@tyroneross/build-loop 0.30.3 → 0.35.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 (171) hide show
  1. package/.agents/plugins/marketplace.json +2 -2
  2. package/.claude-plugin/marketplace.json +4 -4
  3. package/.claude-plugin/plugin.json +1 -1
  4. package/.codex-plugin/plugin.json +1 -1
  5. package/AGENTS.md +11 -2
  6. package/README.md +8 -7
  7. package/agents/advisor.md +111 -0
  8. package/agents/alignment-checker.md +11 -0
  9. package/agents/assessment-orchestrator.md +1 -1
  10. package/agents/build-orchestrator.md +28 -33
  11. package/agents/fact-checker.md +1 -1
  12. package/agents/fix-critique.md +1 -1
  13. package/agents/independent-auditor.md +1 -1
  14. package/agents/overfitting-reviewer.md +1 -1
  15. package/agents/plan-critic.md +8 -6
  16. package/agents/promotion-reviewer.md +1 -1
  17. package/agents/retrospective-synthesizer.md +20 -3
  18. package/agents/scope-auditor.md +1 -1
  19. package/agents/security-reviewer.md +1 -1
  20. package/agents/self-improvement-architect.md +1 -1
  21. package/commands/{handoff.md → compose-handoff.md} +4 -4
  22. package/commands/{optimize.md → optimize-run.md} +1 -1
  23. package/commands/{agent-rally-point.md → rally-point.md} +3 -3
  24. package/commands/{research.md → research-run.md} +1 -1
  25. package/commands/setup-memory.md +32 -0
  26. package/commands/{plan-verify.md → verify-plan.md} +1 -1
  27. package/docs/agent-surface-policy.md +38 -20
  28. package/docs/memory-setup.md +19 -14
  29. package/hooks/_resolve_python.sh +28 -0
  30. package/hooks/closeout.sh +58 -0
  31. package/hooks/git/pre-push +69 -6
  32. package/hooks/hooks.json +34 -13
  33. package/hooks/post-push-closeout.sh +73 -0
  34. package/hooks/session-start-closeout.sh +69 -0
  35. package/hooks/session-start-memory.sh +27 -0
  36. package/hooks/session-start-plugin-heal.sh +33 -0
  37. package/hooks/test_closeout.sh +124 -0
  38. package/package.json +7 -4
  39. package/plugin-artifacts/codex/.codex-plugin/plugin.json +41 -0
  40. package/plugin-artifacts/codex/AGENTS.md +507 -0
  41. package/plugin-artifacts/codex/BUILD-ARTIFACT.md +5 -0
  42. package/plugin-artifacts/codex/LICENSE +202 -0
  43. package/plugin-artifacts/codex/README.md +404 -0
  44. package/plugin-artifacts/codex/docs/agent-surface-policy.md +63 -0
  45. package/plugin-artifacts/codex/references/advisor-dispatch-ladder.md +62 -0
  46. package/plugin-artifacts/codex/references/agent-role-taxonomy.md +135 -0
  47. package/plugin-artifacts/codex/references/autonomous-and-per-commit-modes.md +161 -0
  48. package/plugin-artifacts/codex/references/autonomy-config.md +231 -0
  49. package/plugin-artifacts/codex/references/capability-routing.md +182 -0
  50. package/plugin-artifacts/codex/references/codex-subagents.md +106 -0
  51. package/plugin-artifacts/codex/references/coordination-file-template.md +181 -0
  52. package/plugin-artifacts/codex/references/coordination-rules.md +283 -0
  53. package/plugin-artifacts/codex/references/dogfood-reload-checkpoint.md +112 -0
  54. package/plugin-artifacts/codex/references/halt-and-ask-protocol.md +102 -0
  55. package/plugin-artifacts/codex/references/implementer-envelope-schema.md +302 -0
  56. package/plugin-artifacts/codex/references/intent-capability-pack.md +257 -0
  57. package/plugin-artifacts/codex/references/intent-exploration-prompts.md +96 -0
  58. package/plugin-artifacts/codex/references/leadership.md +72 -0
  59. package/plugin-artifacts/codex/references/memory-systems.md +238 -0
  60. package/plugin-artifacts/codex/references/memory.md +299 -0
  61. package/plugin-artifacts/codex/references/model-tier-mapping.md +257 -0
  62. package/plugin-artifacts/codex/references/modular-systems-pack.md +96 -0
  63. package/plugin-artifacts/codex/references/phase-1-assess.md +231 -0
  64. package/plugin-artifacts/codex/references/phase-2-plan.md +78 -0
  65. package/plugin-artifacts/codex/references/phase-3-execute.md +49 -0
  66. package/plugin-artifacts/codex/references/phase-4-review.md +322 -0
  67. package/plugin-artifacts/codex/references/phase-5-iterate.md +71 -0
  68. package/plugin-artifacts/codex/references/phase-6-learn.md +56 -0
  69. package/plugin-artifacts/codex/references/recent-design-structures.md +274 -0
  70. package/plugin-artifacts/codex/references/research-trigger-policy.md +140 -0
  71. package/plugin-artifacts/codex/references/runtime-smoke-triggers.md +42 -0
  72. package/plugin-artifacts/codex/references/self-review.md +234 -0
  73. package/plugin-artifacts/codex/references/single-writer-commit-protocol.md +90 -0
  74. package/plugin-artifacts/codex/references/task-capture-policy.md +68 -0
  75. package/plugin-artifacts/codex/references/ui-io-contract.md +116 -0
  76. package/plugin-artifacts/codex/references/ui-spotcheck-protocol.md +65 -0
  77. package/plugin-artifacts/codex/skills/build-loop/SKILL.md +372 -0
  78. package/plugin-artifacts/codex/skills/build-loop/detect-plugins.mjs +82 -0
  79. package/plugin-artifacts/codex/skills/build-loop/eval-guide.md +65 -0
  80. package/plugin-artifacts/codex/skills/build-loop/fallbacks.md +549 -0
  81. package/plugin-artifacts/codex/skills/build-loop/phases/fact-check.md +42 -0
  82. package/plugin-artifacts/codex/skills/build-loop/phases/ui-validation.md +267 -0
  83. package/plugin-artifacts/codex/skills/build-loop/references/advisor-dispatch-ladder.md +62 -0
  84. package/plugin-artifacts/codex/skills/build-loop/references/apple-native-planning.md +439 -0
  85. package/plugin-artifacts/codex/skills/build-loop/references/autonomous-and-per-commit-modes.md +161 -0
  86. package/plugin-artifacts/codex/skills/build-loop/references/capability-routing.md +182 -0
  87. package/plugin-artifacts/codex/skills/build-loop/references/codex-subagents.md +106 -0
  88. package/plugin-artifacts/codex/skills/build-loop/references/coordination.md +161 -0
  89. package/plugin-artifacts/codex/skills/build-loop/references/correction-aware-capture.md +177 -0
  90. package/plugin-artifacts/codex/skills/build-loop/references/independent-auditor.md +72 -0
  91. package/plugin-artifacts/codex/skills/build-loop/references/intent-capability-pack.md +257 -0
  92. package/plugin-artifacts/codex/skills/build-loop/references/intent-exploration-prompts.md +96 -0
  93. package/plugin-artifacts/codex/skills/build-loop/references/leadership.md +72 -0
  94. package/plugin-artifacts/codex/skills/build-loop/references/memory.md +299 -0
  95. package/plugin-artifacts/codex/skills/build-loop/references/modular-systems-pack.md +96 -0
  96. package/plugin-artifacts/codex/skills/build-loop/references/output-style.md +129 -0
  97. package/plugin-artifacts/codex/skills/build-loop/references/pay-it-forward-arch.md +98 -0
  98. package/plugin-artifacts/codex/skills/build-loop/references/phase-1-assess.md +231 -0
  99. package/plugin-artifacts/codex/skills/build-loop/references/phase-2-plan.md +78 -0
  100. package/plugin-artifacts/codex/skills/build-loop/references/phase-3-execute.md +49 -0
  101. package/plugin-artifacts/codex/skills/build-loop/references/phase-4-review.md +322 -0
  102. package/plugin-artifacts/codex/skills/build-loop/references/phase-5-iterate.md +71 -0
  103. package/plugin-artifacts/codex/skills/build-loop/references/phase-6-learn.md +56 -0
  104. package/plugin-artifacts/codex/skills/build-loop/references/recent-design-structures.md +274 -0
  105. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/ASSESSMENT.md +85 -0
  106. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/STANDALONE_TEST_RUN.md +149 -0
  107. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/01-simple-bugfix.md +32 -0
  108. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/02-ui-build-with-iteration.md +48 -0
  109. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/03-multi-failure-escalation.md +60 -0
  110. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/04-ui-build-ibr-absent.md +51 -0
  111. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/05-refactor-navgator-absent.md +71 -0
  112. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/06-recurring-bug-debugger-absent.md +52 -0
  113. package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/trace-comparison.md +202 -0
  114. package/plugin-artifacts/codex/skills/build-loop/references/self-recursive-dev.md +77 -0
  115. package/plugin-artifacts/codex/skills/build-loop/references/self-review.md +234 -0
  116. package/plugin-artifacts/codex/skills/build-loop/references/ui-io-contract.md +116 -0
  117. package/plugin-artifacts/codex/skills/build-loop/scanners/audit-design-rules.mjs +476 -0
  118. package/plugin-artifacts/codex/skills/build-loop/scanners/require-visual-evidence.mjs +239 -0
  119. package/plugin-artifacts/codex/skills/build-loop/templates/backlog-item.md +35 -0
  120. package/plugin-artifacts/codex/skills/build-loop/templates/codex-worker-prompt.md +100 -0
  121. package/plugin-artifacts/codex/skills/build-loop/templates/ui-subagent-prompt.md +179 -0
  122. package/plugin-artifacts/codex/skills/build-loop/templates/ux-fix-plan.md +40 -0
  123. package/scripts/_paths.py +59 -13
  124. package/scripts/build_codex_plugin_artifact.py +314 -0
  125. package/scripts/check_cache_sync.py +1 -1
  126. package/scripts/install_memory.py +11 -3
  127. package/scripts/prune_plugin_cache.py +225 -11
  128. package/scripts/sync_navgator_lessons.py +25 -0
  129. package/scripts/sync_plugin_cache.py +66 -36
  130. package/skills/agent-rally-point/SKILL.md +1 -1
  131. package/skills/agent-rally-watcher/SKILL.md +1 -1
  132. package/skills/build-loop/SKILL.md +11 -155
  133. package/skills/build-loop/references/advisor-dispatch-ladder.md +62 -0
  134. package/skills/build-loop/references/autonomous-and-per-commit-modes.md +161 -0
  135. package/skills/build-loop/references/capability-routing.md +4 -3
  136. package/skills/build-loop/references/codex-subagents.md +8 -0
  137. package/skills/build-loop/references/coordination.md +1 -1
  138. package/skills/build-loop/references/intent-capability-pack.md +88 -1
  139. package/skills/build-loop/references/memory.md +17 -2
  140. package/skills/build-loop/references/phase-1-assess.md +13 -0
  141. package/skills/build-loop/references/phase-2-plan.md +2 -1
  142. package/skills/build-loop/references/phase-3-execute.md +4 -2
  143. package/skills/build-loop/references/phase-4-review.md +12 -0
  144. package/skills/build-loop/references/phase-6-learn.md +1 -1
  145. package/skills/build-loop/references/self-review.md +4 -2
  146. package/skills/build-loop/templates/codex-worker-prompt.md +45 -34
  147. package/skills/handoff/SKILL.md +3 -3
  148. package/skills/loop-builder/SKILL.md +98 -0
  149. package/skills/loop-builder/presets/active-project-evidence.yaml +97 -0
  150. package/skills/loop-builder/presets/generic-artifact-loop.yaml +95 -0
  151. package/skills/loop-builder/presets/presentation-audit.yaml +96 -0
  152. package/skills/loop-builder/presets/research-synthesis.yaml +96 -0
  153. package/skills/loop-builder/presets/source-ingestion-raw-data-audit.yaml +96 -0
  154. package/skills/loop-builder/references/spec-format.md +80 -0
  155. package/skills/loop-builder/scripts/loop_builder.py +346 -0
  156. package/skills/model-tiering/SKILL.md +65 -40
  157. package/skills/optimize/SKILL.md +2 -2
  158. package/skills/plan-verify/SKILL.md +1 -1
  159. package/skills/plugin-builder/references/distribution.md +8 -0
  160. package/skills/research/SKILL.md +33 -6
  161. package/skills/runtime-parity-verification/SKILL.md +51 -0
  162. package/skills/spec-writing/SKILL.md +19 -0
  163. package/templates/memory/README.md +65 -0
  164. package/templates/memory/charter.md.template +46 -0
  165. package/templates/memory/manifest.json +24 -4
  166. package/codex-skills/debug-loop/SKILL.md +0 -18
  167. package/codex-skills/handoff/SKILL.md +0 -22
  168. package/codex-skills/knowledge/SKILL.md +0 -21
  169. package/codex-skills/optimize/SKILL.md +0 -18
  170. package/codex-skills/research/SKILL.md +0 -18
  171. /package/commands/{knowledge-review.md → review-knowledge.md} +0 -0
@@ -0,0 +1,234 @@
1
+ <!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
2
+
3
+ # Self-Review — Periodic Autonomous Self-Improvement
4
+
5
+ Single source of truth for the build-loop self-review subsystem: purpose, light/deep model, config schema, launchd schedule, graceful degradation, and the headless apply prompt.
6
+
7
+ ---
8
+
9
+ ## Purpose
10
+
11
+ Self-review mines recent build-loop runs for recurring issues and efficiency signals, produces a human-readable digest, and (in deep mode) automatically applies safe improvements via the normal build-loop pipeline. It closes the loop between observations captured during builds and durable fixes that land in the repo — without requiring the user to manually schedule or trigger a review.
12
+
13
+ Two cadences balance cost against coverage:
14
+
15
+ | Mode | Default cadence | Scope | Auto-apply |
16
+ |---|---|---|---|
17
+ | **light** | Daily (09:00) | Issues in the last 7 days; proposal cap 10 | No — digest + queue only |
18
+ | **deep** | Weekly (Sunday 03:00) | Issues in the last 30 days; uncapped | Yes — SAFE proposals auto-routed through build-loop |
19
+
20
+ ---
21
+
22
+ ## Config schema
23
+
24
+ Add a `selfReview` block to `.build-loop/config.json` (all fields optional; defaults shown):
25
+
26
+ ```json
27
+ {
28
+ "selfReview": {
29
+ "enabled": true,
30
+ "autonomy": "apply_push",
31
+ "light": "daily",
32
+ "deep": "weekly"
33
+ }
34
+ }
35
+ ```
36
+
37
+ | Field | Values | Meaning |
38
+ |---|---|---|
39
+ | `enabled` | `true` / `false` | `false` disables the launchd jobs and is a no-op for the installer |
40
+ | `autonomy` | `apply_push` \| `apply_local` \| `propose` | `apply_push` — apply SAFE items and push main; `apply_local` — apply but do not push; `propose` — queue only, no auto-apply |
41
+ | `light` | `daily` \| `weekly` \| `disabled` | Cadence for the light job |
42
+ | `deep` | `daily` \| `weekly` \| `disabled` | Cadence for the deep job |
43
+
44
+ Cadence values map to launchd `StartCalendarInterval`. `daily` → every day at the job's configured hour. `weekly` → once per week on the configured weekday. `disabled` skips installing that job.
45
+
46
+ ---
47
+
48
+ ## How it works
49
+
50
+ ### Data-gathering layer (scripts/self_review/ package — frozen CLI)
51
+
52
+ `python3 scripts/self_review/__main__.py --mode {light|deep} [--workdir <repo>] [--days N] [--dry-run] --json`
53
+
54
+ Always exits 0. Writes:
55
+ - `.build-loop/self-review/<UTCdate>-<mode>.md` — human digest
56
+ - `.build-loop/proposals/self-review-*.md` — one file per candidate improvement, each with `classify_hint: SAFE|RISKY|DECISION` frontmatter
57
+
58
+ Returns JSON to stdout:
59
+ ```json
60
+ {
61
+ "mode": "light|deep",
62
+ "window_days": 7,
63
+ "mined": {"corrections": [], "rituals": [], "sequences": []},
64
+ "efficiency_findings": [],
65
+ "self_simplification": [],
66
+ "digest_path": ".build-loop/self-review/2026-05-29-deep.md",
67
+ "queued": [".build-loop/proposals/self-review-foo.md"],
68
+ "errors": [],
69
+ "dry_run": false
70
+ }
71
+ ```
72
+
73
+ **`self_simplification[]`** (deep mode, self-recursive only): a list of proactive simplification findings for build-loop's own code. Each entry has the shape:
74
+
75
+ ```json
76
+ {
77
+ "target": "self",
78
+ "file": "<relative path>",
79
+ "finding": "<one-line description>",
80
+ "classify_hint": "SAFE|RISKY|DECISION",
81
+ "proposed_action": "<what to do>"
82
+ }
83
+ ```
84
+
85
+ `target: self` marks a proposal as targeting build-loop's own code (plugin repo or `build-loop-memory`). These proposals are subject to the SELF-MODIFICATION SAFETY GATE (see §"Self-modification of the restricted repo" below) — they are never processed by the standard reactive-fix path.
86
+
87
+ Deep mode digests include an `## Apply plan` section that separates SAFE-to-auto-apply items from RISKY-to-surface items. When `self_simplification[]` is non-empty, the digest also includes a `## Self-simplification proposals` section listing each `target: self` finding.
88
+
89
+ ### Scheduling layer (launchd)
90
+
91
+ `python3 scripts/install_self_review.py install` writes two plists to `~/Library/LaunchAgents/`:
92
+
93
+ - `com.build-loop.selfreview-light.plist` — daily at 09:00, invokes `scripts/self_review_run.sh light`
94
+ - `com.build-loop.selfreview-deep.plist` — weekly Sunday at 03:00, invokes `scripts/self_review_run.sh deep`
95
+
96
+ `install` and `uninstall` also unload + remove any jobs still installed under the pre-rename legacy labels (developer-prefixed `*.buildloop.selfreview-*`), so an existing machine transitions to the neutral labels on the next run.
97
+
98
+ Both jobs write output to `.build-loop/self-review/launchd-{light,deep}.log`.
99
+
100
+ ### Wrapper layer (scripts/self_review_run.sh)
101
+
102
+ Invoked by launchd (or manually). Runs the gatherer, saves the JSON snapshot to `.build-loop/self-review/last-<mode>.json`, appends a timestamped line to `.build-loop/self-review/run.log`, and (for deep mode with `autonomy` in `{apply_push, apply_local}`) invokes the headless apply prompt via `claude -p`.
103
+
104
+ ---
105
+
106
+ ## Install / uninstall / status
107
+
108
+ ```bash
109
+ # Install both launchd jobs
110
+ python3 scripts/install_self_review.py install
111
+
112
+ # Remove launchd jobs and plists
113
+ python3 scripts/install_self_review.py uninstall
114
+
115
+ # Check loaded/not-loaded
116
+ python3 scripts/install_self_review.py status
117
+
118
+ # JSON output for any subcommand
119
+ python3 scripts/install_self_review.py status --json
120
+ ```
121
+
122
+ Or via the slash command: `/build-loop:self-review --install` / `--uninstall` / `--status`.
123
+
124
+ ---
125
+
126
+ ## Graceful degradation
127
+
128
+ If the `claude` CLI is not installed or not on PATH when the deep wrapper fires, the wrapper logs the skip reason and exits 0. The digest and queued proposals are still produced — the user can process them manually via `/build-loop:run` or `/build-loop:self-review deep`.
129
+
130
+ The queue accumulates across skipped deep runs. On the next successful headless invocation, all queued SAFE proposals are processed.
131
+
132
+ ---
133
+
134
+ ---
135
+
136
+ ## Self-modification of the restricted repo
137
+
138
+ The self-review/self-heal loop is authorized to write to the restricted repo — build-loop's own plugin repo and the `build-loop-memory` durable repo (lessons and skills). This is normally a guarded action because it edits the running runtime.
139
+
140
+ **The SELF-MODIFICATION SAFETY GATE is MANDATORY and non-negotiable for ANY change to build-loop's own code.** It is the load-bearing safety for this authorization.
141
+
142
+ ### Gate protocol (every self-modification commit must pass all steps)
143
+
144
+ **Step 1 — Bundle first (reversibility):**
145
+ ```bash
146
+ git bundle create .build-loop/bundles/pre-selfmod-$(date +%Y%m%dT%H%M%S).bundle --all
147
+ ```
148
+ Always bundle before any self-modification. This is the rollback point.
149
+
150
+ **Step 2 — Self-recursive / per-commit mode:**
151
+ Self-modifications use the existing per-commit mode machinery (one commit at a time, reviewed before the next). `selfRecursive.enabled` is `true` when the working directory IS build-loop's own repo. Do not batch multiple self-modification commits without a gate pass between each.
152
+
153
+ **Step 3 — Verify gate (MANDATORY before commit):**
154
+ ```bash
155
+ python3 scripts/self_mod_verify.py \
156
+ --workdir "$PWD" \
157
+ --scope auto \
158
+ --changed-files <space-separated file list> \
159
+ --auto-revert \
160
+ --json
161
+ ```
162
+ `--scope auto` runs mapped tests for small changes and broader tests for multi-file/core changes (practical default). Use `--scope full` for the slow exhaustive option (900s, parallel when pytest-xdist is present).
163
+
164
+ `verdict: pass` → the self-modification may commit.
165
+ `verdict: fail` → the gate AUTO-REVERTS the change and writes the finding to `.build-loop/proposals/failed-gate/`. The change is NEVER committed. Do not retry a failed gate verdict without diagnosing the root cause.
166
+
167
+ **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: `self_mod_verify.py --scope auto --auto-revert` must return `verdict: pass` (tests are the oracle; a failed gate auto-reverts the change). Build-loop never halts a planned self-modification for human approval. Oversight is post-hoc, not a gate: (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 so the human sees results at the end. The loop stays on task and reports once, at the end.
168
+
169
+ **Step 4 — SAFE-only auto-apply:**
170
+ Only changes that `classify_action.py` classifies as SAFE auto-apply through this path. Structural or architectural self-modifications — new phase, changed dispatch contract, agent-role change — surface as DECISION and are never auto-applied. They are queued to `.build-loop/proposals/needs-decision/` for explicit user action.
171
+
172
+ ### Authorized targets
173
+
174
+ - Build-loop's own plugin repo (files under the build-loop working directory when `selfRecursive.enabled`)
175
+ - `build-loop-memory` durable repo: lessons, skills, and project-scoped memory entries written via `scripts/memory_writer.py`
176
+
177
+ ### What is NOT authorized without user confirmation
178
+
179
+ - Promotion of project-local skills to `~/.claude/skills/` (global scope — confirm first)
180
+ - Changes to `agents/build-orchestrator.md` phase contracts or MECE ownership rules (structural — DECISION; surface as DECISION, never auto-apply)
181
+
182
+ ---
183
+
184
+ ## APPLY PROMPT
185
+
186
+ This is the exact prompt text fed to `claude -p` by `scripts/self_review_run.sh` for deep auto-apply. Do not paraphrase — the wrapper reads this file and extracts the block between the `BEGIN_APPLY_PROMPT` and `END_APPLY_PROMPT` markers.
187
+
188
+ <!-- BEGIN_APPLY_PROMPT -->
189
+ You are running headlessly as part of a scheduled build-loop self-review. Your job is to apply safe improvements identified by the periodic self-review.
190
+
191
+ Step 1 — Read the context:
192
+ - Read `.build-loop/self-review/last-deep.json` (the data-gatherer output).
193
+ - For each path listed in `queued[]`, read the proposal file. Take only proposals where `classify_hint: SAFE`.
194
+ - Skip any proposal where `classify_hint` is `RISKY` or `DECISION` — leave those files untouched.
195
+ - Separately, collect every entry in `self_simplification[]` where `classify_hint: SAFE` AND `target: self`. These are proactive self-simplifications of build-loop's own code and require the SELF-MODIFICATION SAFETY GATE in Step 2b.
196
+
197
+ Step 2a — Apply each SAFE non-self proposal:
198
+ For each SAFE proposal without `target: self`, route it through `/build-loop:run` with a goal derived from the proposal's title and body. Build-loop handles apply + commit + collapse. Its own autonomy gate and deployment policy govern what lands — do not bypass them.
199
+
200
+ Step 2b — Apply SAFE `target: self` proposals (self-modification path):
201
+ Self-modifications execute — they do not stop the loop. For each SAFE `target: self` proposal, apply the change, then — BEFORE committing — run the MANDATORY SAFETY GATE:
202
+ ```bash
203
+ python3 scripts/self_mod_verify.py \
204
+ --workdir "$PWD" \
205
+ --scope auto \
206
+ --changed-files <the files you changed> \
207
+ --auto-revert \
208
+ --json
209
+ ```
210
+ - `verdict: pass` → commit the change via the normal per-commit mode (one commit per self-modification; do not batch). The self-modification is recorded for the end-of-run readback.
211
+ - `verdict: fail` → the gate has already auto-reverted the change. Move the proposal to `.build-loop/proposals/failed-gate/` and continue with the next proposal. NEVER commit a failed-gate self-modification.
212
+ - Skip any `target: self` proposal that `classify_action.py` does not classify as SAFE (RISKY → isolate to worktree-branch + log; DECISION → queue to `.build-loop/proposals/needs-decision/`, do not apply).
213
+
214
+ Do NOT stop the loop for any self-modification, including those that touch the gate scripts, tests, or the self-improvement loop. The test-suite gate is the oracle; if it passes, the change commits and is reported at the end.
215
+
216
+ Step 3 — Determine push behavior:
217
+ Read `.build-loop/config.json` key `selfReview.autonomy` (default `apply_push`).
218
+ - If `apply_push`: after all SAFE proposals have been routed and landed, run `git push origin main` for the accumulated commits. Build-loop's deployment_policy still gates this; if the push is blocked by policy, log the block and exit 0 — do not force.
219
+ - If `apply_local`: do not push. Commits land locally; the user pushes manually.
220
+
221
+ Step 4 — Report:
222
+ Print a short summary: how many SAFE proposals were processed (split: standard vs `target: self`), how many RISKY/DECISION items were left queued, how many `target: self` proposals were gated/reverted by a failed test gate, and the push status (pushed / local-only / skipped by policy / n/a).
223
+
224
+ Include a `## Self-modifications (readback)` section listing every self-modification that landed this run: file, one-line what/why, test-gate verdict, and the additional-review finding (pass/flag). If no self-modifications occurred, omit the section.
225
+
226
+ Constraints:
227
+ - Never apply a RISKY or DECISION proposal autonomously.
228
+ - Never apply a `target: self` proposal without running `self_mod_verify.py` first.
229
+ - Never commit a change that `self_mod_verify.py` returned `verdict: fail` for.
230
+ - Never stop the loop for a self-modification — including those that touch the gate, tests, or self-improvement loop scripts. The test gate is the oracle; pass → commit and continue; fail → auto-revert and continue. Report at the end.
231
+ - Never bypass build-loop's commit auditor or autonomy gate.
232
+ - If build-loop is not available as a slash command, log the unavailability and exit 0 — the queue stays intact.
233
+ - This is a local developer tool; there are no users to protect other than the repo owner.
234
+ <!-- END_APPLY_PROMPT -->
@@ -0,0 +1,90 @@
1
+ <!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
2
+
3
+ # Single-Writer Git Commit Protocol
4
+
5
+ _Linked from `agents/build-orchestrator.md` §Phase 3 Execute._
6
+
7
+ Build-loop's commit-step protocol introduced 2026-05-07 to eliminate the parallel-commit race condition that lost 3 of 4 commits in round-3 fan-out testing. Implementers no longer call `git add` or `git commit` (per `agents/implementer.md` Hard rule 4); the orchestrator owns `.git/` as a single-writer resource. After **each parallel batch returns**, run this step before dispatching the next wave or proceeding to Phase 4.
8
+
9
+ For each implementer return envelope with `status: fixed | partial | completed`:
10
+
11
+ (For `status: "blocked"`, see `references/halt-and-ask-protocol.md` — that branch fires BEFORE the commit step and may iterate up to 3 times before producing a commit-eligible envelope.)
12
+
13
+ 00. **Pre-commit context snapshot** (NEW 2026-05-28 - non-blocking resume evidence): before staging, write the boundary state:
14
+ ```bash
15
+ python3 ${CLAUDE_PLUGIN_ROOT}/scripts/context_snapshot.py \
16
+ --workdir "$PWD" \
17
+ --trigger pre_commit \
18
+ --phase execute \
19
+ --agent orchestrator \
20
+ --run-id "$RUN_ID" \
21
+ --chunk-id "<chunk_id>" \
22
+ --status committing \
23
+ --message "<commit_subject>" \
24
+ --file "<file-from-files_changed>" \
25
+ --json
26
+ ```
27
+ The helper writes `.build-loop/context/current.md`, a JSON snapshot, and a row in `.build-loop/context/commit-boundaries.jsonl`. Failure is a WARN only; do not bypass or alter the commit protocol because a snapshot failed.
28
+
29
+ 0. **Verify no staged residue** (NEW 2026-05-12 — closes the index-leak class seen in a prior 2026-05-11 private-app run): `git status --porcelain` and inspect the staged column (character 1 of each XY line). Implementers are contracted to leave working-tree changes only — they NEVER call `git add` (per `agents/implementer.md` Hard rule 4). Any non-space character in the staged column means an implementer violated that rule and the index is dirty before the orchestrator's own `git add`. ABORT this dispatch with: `Implementer left staged residue in the index; refusing to proceed. Files staged: <list>`. Route the offending implementer's plan back to Iterate with `additional_context: "Hard rule 4 violation — staged the index"`. Do NOT auto-clean and continue; the residue indicates the implementer's commit envelope can no longer be trusted.
30
+
31
+ 1. **Verify scope**: `git status --porcelain` — every modified/untracked file must appear in some implementer's `files_changed`. Files not claimed by any implementer = orchestrator-side scope-leak; investigate before committing.
32
+ 2. **Stage exactly that implementer's files**: `git add -- <files_changed_list>`. Use absolute paths to avoid relative-path ambiguity when multiple worktrees coexist.
33
+ 3. **Commit with the implementer's message metadata, not agent authorship**: `git commit -m "<commit_subject>" -m "<commit_body>"`. Do not pass `--author`, change `GIT_AUTHOR_*` / `GIT_COMMITTER_*`, or otherwise set the official git/GitHub author, committer, 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 belongs in the commit body, run notes, `.build-loop` context, judge decisions, or other auxiliary metadata only. The pre-commit hook runs HERE (full-project tsc, lint-staged, betterer-strict — whatever the project has). If the hook fails, do NOT pass `--no-verify`; instead, capture the failure and route the implementer's plan back to Iterate with `additional_context: "<hook output>"`.
34
+ 4. **Verify commit landed**: `git log -1 --oneline` confirms the SHA. If `git status` after the commit still shows the implementer's files as modified, the commit didn't land — investigate.
35
+ 4a. **Post-commit context snapshot** (NEW 2026-05-28): after the SHA is known, write the landed boundary:
36
+ ```bash
37
+ python3 ${CLAUDE_PLUGIN_ROOT}/scripts/context_snapshot.py \
38
+ --workdir "$PWD" \
39
+ --trigger post_commit \
40
+ --phase execute \
41
+ --agent orchestrator \
42
+ --run-id "$RUN_ID" \
43
+ --chunk-id "<chunk_id>" \
44
+ --status completed \
45
+ --message "<commit_subject>" \
46
+ --commit-sha "<sha>" \
47
+ --file "<file-from-files_changed>" \
48
+ --json
49
+ ```
50
+ This is the canonical handoff record for "what changed right before/after commit." It is generated runtime state under `.build-loop/context/` and is never durable memory by itself.
51
+ 5. **Attestation lint** (NEW 2026-05-07 — synthesis-decision drift catcher): immediately after the commit lands, persist the implementer's envelope to a temp path and run `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/attestation_lint.py --diff "<sha>~1..<sha>" --envelope <envelope.json>` where `<sha>` is the commit just verified. The lint cross-checks every `synthesis_attestation` entry against the actual diff for the deterministic dimensions (`placement`, `cta_tier`, `visual_weight`); subjective dims (`copy_tone`, `empty_state`) return `unverifiable` and don't grade.
52
+ - **Exit 0** — every applied claim verified or only-unverifiable-with-some-pass: proceed silently to step 6.
53
+ - **Exit 1** — at least one entry FAILED: a synthesis claim is contradicted by the diff. Default action: revert the commit and route to Iterate with the lint output as `additional_context` (option a). Do not stop and ask the user — this is the kind of issue the loop is built to handle. Two failure modes warrant escalation: (i) Iterate has already retried this same lint failure 3 times without clearing it, in which case surface the failing entries via `AskUserQuestion` and offer all three options (revert, accept with override, amend envelope); (ii) the synthesis claim is on a dimension the user explicitly named in the original plan as load-bearing for user-visible behavior, in which case ask before reverting because reverting destroys evidence the user wants to inspect. Otherwise: revert, iterate, keep going.
54
+ - **Exit 2** — only unverifiable results (every dim was subjective or bare-string form): log a one-line warning to terminal output (e.g. `[Attestation] ⚠️ envelope had no graded claims — synthesis drift undetected this commit`), then proceed. This is informational, not blocking; it tells the operator the lint added zero coverage and the envelope should be richer next time.
55
+ 6. **Synthesis critic** (NEW 2026-05-07 — model-based grader for the subjective dims `attestation_lint.py` cannot verify): immediately after step 5 settles, decide whether to dispatch `synthesis-critic`.
56
+ - **UI-file gate (skip-if-no-UI-files)**: inspect the implementer's `files_changed`. If **none** of the paths match `*.tsx`, `*.jsx`, `*.vue`, or `*.svelte`, skip this step entirely and proceed to step 7 — the subjective dims (`copy_tone`, `empty_state`) only meaningfully apply to commits that change user-visible UI. Backend-only, infra-only, methodology-only, and doc-only commits never invoke the critic. Log one line: `[SynthesisCritic] skipped — no UI files in commit`.
57
+ - **Dispatch when UI files are present**: `Agent(subagent_type="build-loop:synthesis-critic", prompt=...)` with three context blocks in the prompt: (a) the unified diff (`git diff <sha>~1..<sha>`); (b) the plan's `synthesis_dimensions` block verbatim (so the critic has the claimed phrasing); (c) the implementer's `synthesis_attestation` and `notes` from the envelope. The critic returns one JSON object: `{verdict: "pass" | "flag", flagged: [{dimension, claimed, observed, reasoning}], notes: "..."}`.
58
+ - **`verdict: "pass"`**: log one line: `[SynthesisCritic] ✅ pass — N subjective dim(s) graded`. Proceed to step 7.
59
+ - **`verdict: "flag"`**: log a WARN line per flagged dimension (e.g. `[SynthesisCritic] ⚠️ copy_tone — claimed "calm-precision, no exclamation points"; observed "Done!" in NewsBanner.tsx`). Append the full JSON to `.build-loop/state.json.synthesisCriticFlags[]` for Phase 6 Learn pattern detection. **Do NOT block.** Do NOT route to Iterate. Do NOT alter the implementer's `f_criteria`. The critic is WARN-only by contract — flagged dims surface for the operator to triage but never gate the build.
60
+ - **Critic outage** (subagent dispatch fails or returns non-JSON): log `[SynthesisCritic] ⚠️ critic unavailable — subjective dims ungraded this commit` and proceed. Same WARN-only posture.
61
+ 7. **Commit-auditor advisory verdict** (NEW 2026-05-12, plan §12.7 P5): after step 5 settles, decide whether to dispatch `commit-auditor` (Opus, advisory).
62
+
63
+ **Trivial bypass** (skip dispatch when ALL of these hold):
64
+ - `(lines_added + lines_removed) < 20` for this commit (`git diff --shortstat <sha>~1..<sha>`)
65
+ - No spec-touch trigger present in the chunk's metadata (`contract_change`, `layer_crossing`, `destructive_op` all false)
66
+ - `state.json.planVerify.exit == 0` (last known)
67
+ - `state.json.scopeAudit.last_verdict == "green"` (last known)
68
+
69
+ When bypassed: append `{judge_id: "commit-auditor", checkpoint_id: "<run_id>:<chunk_id>:pre-commit", verdict: "approve", confidence: 1.0, spec_alignment: "aligned", variances: [], bypass_reason: "trivial", policy_refs: []}` directly to a temp `judge_decisions.json` (collected for Phase 4 Review-F `--judge-decisions-json` flush). Log one line: `[CommitAuditor] bypass — trivial (lines=N, no spec-touch)`.
70
+
71
+ **Otherwise dispatch**: `Agent(subagent_type="build-loop:commit-auditor", prompt=...)` with the brief shape documented in `agents/commit-auditor.md` (chunk_id, diff_sha, diff_stat, files_owned, plan_path, rubric_criteria_ids, constitution_loaded_rule_ids, triggers, recent_judge_decisions). Run in parallel with step 6 synthesis-critic when both are firing — they read the diff independently and write to non-overlapping state fields.
72
+
73
+ **Verdict routing** (advisory only — NEVER blocks):
74
+ - `approve` — log one line, append to `judge_decisions[]`, proceed.
75
+ - `rethink` — log WARN per variance; surface to the implementer's next-iteration brief if Phase 5 fires; do not auto-revert. Implementer's eventual response goes in `implementer_response` field of the same judge_decisions entry (orchestrator updates after Phase 5 attempt or commit).
76
+ - `new_approach` — log WARN, surface to Phase 4 Report's `## Notes from judges`, route to next phase normally. If the implementer disputes and proceeds, that's a logged disagreement, not a halt. Two consecutive `new_approach` on the same chunk → orchestrator surfaces via PushNotification + TaskCreate "[BUILD-LOOP] Judge requesting re-plan on chunk <id> — your review needed" but the build continues independent chunks; chunk-id's dependents pause until user input or the next phase transition allows them to resume.
77
+
78
+ **Auditor outage** (dispatch fails or returns non-JSON): log `[CommitAuditor] ⚠️ unavailable — chunk un-audited this commit` and proceed. Same advisory posture.
79
+
80
+ 8. **Repeat sequentially** for each remaining implementer in this batch. Sequential by design — the pre-commit hook is the only serializer; implementers' parallel work landed on a clean working tree, but the commits themselves serialize through the hook.
81
+
82
+ ## Concurrency contract
83
+
84
+ - Implementer side: writes to working tree, never to `.git/`. Returns `commit_subject` + `commit_body` + `files_changed` in envelope.
85
+ - Orchestrator side: reads `.git/` (status, log, diff) freely; writes to `.git/` (add, commit) only here, sequentially.
86
+ - Single writer = no race. Round-3's lost-commits issue is structurally prevented.
87
+
88
+ ## Recovery from legacy implementer behavior
89
+
90
+ If you discover an implementer that ignored Hard rule 4 and called `git commit`: the working tree may show some files committed, others uncommitted. Run `git log -<N> --oneline | head` to enumerate the unexpected commits, then commit the remaining files with their owning implementer's metadata. Surface the rule-4 violation in Review-G so we can refine the implementer prompt for next run.
@@ -0,0 +1,68 @@
1
+ <!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
2
+
3
+ # Task Capture Policy
4
+
5
+ Build-loop does not add a new durable task ledger by default. The active task
6
+ view is derived from existing surfaces through:
7
+
8
+ ```bash
9
+ python3 scripts/task_surface.py --workdir "$PWD" --json
10
+ ```
11
+
12
+ This answers "what is still open for this repo/branch?" without creating
13
+ another freeform cross-repo tracker.
14
+
15
+ ## Current Surfaces
16
+
17
+ | Surface | Lifecycle | Owner |
18
+ |---|---|---|
19
+ | Plan `T-N` IDs | Planned work inside a specific build | Phase 2 plan + `plan_verify.py` |
20
+ | `.build-loop/state.json.execution` | Active run queue/in-flight/completed chunks | Orchestrator |
21
+ | Implementer working state | Current task/file/status while a worker is active | Implementer |
22
+ | Cost ledger `task_id` | Dispatch/return correlation and cost analysis | Orchestrator |
23
+ | Rally task heartbeat | Long-running task liveness and still-on-task health | Active terminal |
24
+ | `.build-loop/ux-queue/` | Review-discovered UX/test-coverage work for Phase 5 | Review-D/Iterate |
25
+ | `.build-loop/issues/` | Repo-local open issues detected during runs | Review/Learn |
26
+ | `.build-loop/followup/` | Deferred current-run items that should drain later | Report/queue drain |
27
+ | `.build-loop/backlog/` | Repo-local backlog items | Queue continuation |
28
+ | `.build-loop/proposals/` | Candidate self-review/improvement ideas, opt-in only | Learn/self-review |
29
+ | `build-loop-memory/projects/<slug>/backlog.md` | Durable project backlog | Memory writer / human backlog |
30
+ | TaskCreate/TaskUpdate list | Host-visible user-facing mirror | Orchestrator/session |
31
+
32
+ ## Decision
33
+
34
+ Use `scripts/task_surface.py` as the canonical active view. It reads the
35
+ current repo's execution state, local queues, and project-scoped memory backlog,
36
+ then emits a priority-sorted JSON list with
37
+ `decision: "derived-active-view-no-new-ledger"`. It is read-only and writes no
38
+ ledger. Proposals are excluded by default because they are candidates, not open
39
+ tasks; pass `--include-proposals` for self-review sweeps.
40
+
41
+ Do not add `.build-loop/tasks.jsonl` until there is evidence that the derived
42
+ view cannot answer a real Phase 1 or coordination question. The failure mode to
43
+ avoid is a second source of truth where tasks close in one place and remain open
44
+ elsewhere.
45
+
46
+ ## Promotion Rules
47
+
48
+ - Transient checklist items stay in the host task list and current run state.
49
+ - Deferred work becomes `.build-loop/followup/` or `.build-loop/backlog/` using
50
+ the existing queue rules.
51
+ - Durable project work goes to `build-loop-memory/projects/<slug>/backlog.md`
52
+ or milestones. Do not persist every subtask into memory.
53
+ - Completed/superseded tasks archive with rationale through the owning surface
54
+ (followup/backlog archive, milestone, or decision), not silent deletion.
55
+
56
+ ## Phase 1 Contract
57
+
58
+ Phase 1 may answer open-work questions by running:
59
+
60
+ ```bash
61
+ python3 scripts/task_surface.py --workdir "$PWD" --json
62
+ ```
63
+
64
+ If `open_count > 0`, surface the top active items by priority:
65
+ in-flight/queued chunks, UX queue, issues, followups, repo backlog, memory
66
+ backlog. Do not scan sibling project backlogs. Include proposals only when the
67
+ current task is specifically self-review, improvement triage, or proposal
68
+ cleanup.
@@ -0,0 +1,116 @@
1
+ <!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
2
+
3
+ # UI Input/Output Contract
4
+
5
+ Use this contract for any build-loop task that adds, modifies, or validates a user-facing UI surface. It turns "build the component" into an explicit inventory of what the user can provide, what the system returns, and which UI pattern must handle each data shape.
6
+
7
+ ## When It Applies
8
+
9
+ Apply this when `uiTarget != null` and the task changes any screen, component, form, table, chart, voice/audio affordance, file workflow, generated output, or streamed response. Skip only for copy-only changes that do not alter the available inputs, outputs, states, or operations.
10
+
11
+ ## Required Plan Section
12
+
13
+ Every UI plan must include a `## UI Input/Output Contract` section before implementation. Use one row per affected screen or component, and keep each field concrete.
14
+
15
+ | Field | Required Answer |
16
+ |---|---|
17
+ | Surface | Screen/component name plus file path |
18
+ | User inputs | Every value the user can provide |
19
+ | System outputs | Every value the user receives or decides from |
20
+ | Data taxonomy | Structural type, content format, persistence intent |
21
+ | Operation model | CRUD operation plus any domain verb |
22
+ | Component mapping | Exact input control and output renderer |
23
+ | State matrix | Empty, populated, focused, disabled, loading, success, error, and streaming/abort when relevant |
24
+ | Modality | Text, voice, file, vision, chart, map, AI/generated, or streaming; include fallback |
25
+ | Validation/security | Presentation, application, and domain validation; sanitization; auth/authz display behavior |
26
+ | Traceability | Data schema, API endpoint/method, design-system component, and rationale |
27
+
28
+ ## Data Taxonomy
29
+
30
+ Classify each input and output before choosing UI controls:
31
+
32
+ - **Structural type**: scalar, structured object/array, binary, stream.
33
+ - **Content format**: plain text, Markdown, rich text, HTML, JSON tree, chart data, audio, image, map/geospatial.
34
+ - **Persistence intent**: persisted CRUD data, transient session state, real-time stream, computed/derived output.
35
+
36
+ ## Operation Model
37
+
38
+ Name the operation the UI performs:
39
+
40
+ - **Create**: POST, form, wizard, inline add.
41
+ - **Read**: GET, table, card, detail view, chart.
42
+ - **Update**: PUT/PATCH, edit form, inline edit, toggle.
43
+ - **Delete**: DELETE, destructive button, confirmation.
44
+ - **Domain verbs**: submit, approve, publish, escalate, cancel, refund, reorder, filter, sort, export, download.
45
+
46
+ Do not hide domain verbs inside generic "update" language when rules, side effects, or affordances differ.
47
+
48
+ ## Component Mapping
49
+
50
+ Choose components from the data shape, not habit.
51
+
52
+ | Data Shape | Input Control | Output Renderer |
53
+ |---|---|---|
54
+ | Short string | Single-line input | Text with overflow/copy behavior |
55
+ | Long plain text | Textarea with sizing policy | Paragraph or preformatted text |
56
+ | Markdown | Split write/preview editor | Sanitized Markdown renderer |
57
+ | Rich text | Schema-backed editor | Paired rich-text viewer |
58
+ | JSON/object | Schema-aware JSON editor/tree | Collapsible tree or raw/parsed toggle |
59
+ | Number | Number input, slider, or stepper | Locale-aware number display |
60
+ | Boolean | Toggle, checkbox, or yes/no radio | Explicit state label |
61
+ | Date/time | Date/time/range picker | Locale/timezone-aware display |
62
+ | Enum | Select, radio group, or searchable select when options exceed seven | Label/chip/list value |
63
+ | File/binary | Upload/dropzone with progress | Preview/download with file metadata |
64
+ | Voice/audio | Mic button with waveform and text fallback | Audio player/TTS plus transcript |
65
+ | Tabular data | Filters/search feeding table | Sort/filter/paginated table |
66
+ | Chart data | Form/filter inputs feeding visualization | Named chart type plus table fallback |
67
+ | Streaming/AI output | Prompt or structured input | Token/partial renderer with abort and retry |
68
+ | Geospatial | Address/map controls | Map with markers/clusters and fallback text |
69
+
70
+ ## State Matrix
71
+
72
+ Document the states each component must render:
73
+
74
+ - Default/empty.
75
+ - Populated/filled.
76
+ - Focused.
77
+ - Hover on pointer devices.
78
+ - Active/pressed.
79
+ - Disabled/permission-blocked.
80
+ - Loading.
81
+ - Success.
82
+ - Error/invalid.
83
+ - Empty result.
84
+ - Streaming/partial with abort and retry behavior when relevant.
85
+
86
+ ## Modalities
87
+
88
+ When a modality exists, it needs its own UI and failure path:
89
+
90
+ - **Text**: text input, textarea, rich text, text/Markdown renderer.
91
+ - **Voice**: push-to-talk or wake-word trigger, ASR provider/threshold if known, transcript fallback, TTS controls.
92
+ - **File**: upload control, MIME/size rules, preview/download, copy-text fallback.
93
+ - **Vision/image**: image upload/camera, viewer/annotation, alt-text fallback.
94
+ - **Chart/graph**: chart type, data schema, axis labels, colorblind-safe palette, table fallback.
95
+ - **AI/generated output**: output type contract, response schema/template, streaming vs complete mode, abort/retry behavior.
96
+
97
+ ## Validation And Security
98
+
99
+ Validation must be named by layer:
100
+
101
+ - **Presentation**: required fields, max length, pattern, type, inline field errors.
102
+ - **Application**: cross-field and business-rule errors, form-level/toast surface.
103
+ - **Domain**: invariant failures, system-error surface, and whether repeated domain failures indicate a spec gap.
104
+ - **Sanitization**: allowed subset for Markdown, rich text, HTML, JSON, and generated content.
105
+ - **Auth/authz**: permission required for create/update/delete/domain verbs, and UI behavior when denied: hidden, disabled, or 403/empty view.
106
+
107
+ ## Traceability
108
+
109
+ Each UI element that accepts or returns data must trace to:
110
+
111
+ - Data model or schema version.
112
+ - API endpoint/method or local data source.
113
+ - Design-system component or explicit net-new rationale.
114
+ - Test or validation evidence.
115
+
116
+ If the trace cannot be named, the plan is incomplete.
@@ -0,0 +1,65 @@
1
+ <!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
2
+
3
+ # UI Spot-Check Protocol (Phase 3 chunk-close)
4
+
5
+ _Linked from `agents/build-orchestrator.md` §Phase 3 Execute and §"Phase 3 UI spot-check (between chunks)"._
6
+
7
+ After the commit step closes for a chunk **and before the next chunk dispatches**, fire `ui-validator` whenever the just-closed chunk's `uiTouched` signal is true. Catches UI regressions inside the chunk that introduced them instead of letting them ride to end-of-Phase-4.
8
+
9
+ This is the procedural complement to `agents/ui-validator.md` (the agent contract).
10
+
11
+ ## `uiTouched` signal
12
+
13
+ Compute at chunk-close from the envelope's `files_changed`:
14
+
15
+ | Trigger | `uiTouched` |
16
+ |---|---|
17
+ | Any file under `(app\|components)/**/*.tsx` | `true` |
18
+ | `tailwind.config.{js,ts}` or theme/global-style files | `true` |
19
+ | Style helpers under `lib/(theme\|styles)/**` | `true` |
20
+ | Test files only (`tests/**`, `*.test.*`) | `false` |
21
+ | Schema / API route only (no UI files in the chunk) | `false` |
22
+
23
+ Cache the verdict on `state.json.execution.completed_chunks[<chunk_id>].uiTouched` so resume picks it up.
24
+
25
+ ## Dispatch
26
+
27
+ Sonnet tier; see `agents/ui-validator.md` for the agent contract:
28
+
29
+ ```python
30
+ Agent(
31
+ subagent_type="build-loop:ui-validator",
32
+ prompt=brief({
33
+ triggerPoint: "phase3-chunk-close",
34
+ changedFiles: envelope.files_changed,
35
+ baseUrl: state.devServer.baseUrl, # captured by detect_runtime_server
36
+ priorBaselineDir: ".build-loop/ui-baselines/" + run_id + "/",
37
+ signInForm: state.devServer.signInForm, # null if no auth fixture
38
+ })
39
+ )
40
+ ```
41
+
42
+ Cost ledger (M3) applies — emit `--agent ui-validator` rows at dispatch and return.
43
+
44
+ ## Routing on return
45
+
46
+ | envelope.status | Action |
47
+ |---|---|
48
+ | `pass` | Continue to next chunk dispatch. Persist envelope to `.build-loop/subagent-results/<run_id>/ui-spotcheck-<chunk_id>.json`. |
49
+ | `fail` | Treat `envelope.failing_assertion` as a rubric and route the chunk back to Iterate (same routing as Review-B failure path). Do NOT dispatch downstream chunks in the same batch — drain the queue first by serializing the next batch after the iterate fix. |
50
+ | `skipped` | Continue. `skip_reason` distinguishes: `auth-gap` (mark `⚠️ ui-spotcheck skipped — auth fixture missing` in Review-G), `no-dev-server` (mark `⚠️ untested ui — no dev server`), `no-routes-implicated` (silent skip — implementer touched no public render path). |
51
+
52
+ ## Iteration budget
53
+
54
+ UI-spot-check failures consume the global 5x classic (or 25 autonomous) Iterate cap. They do not get a separate budget.
55
+
56
+ ## Skip conditions
57
+
58
+ Skip the dispatch entirely when:
59
+
60
+ - `uiTouched: false` (no UI files in chunk)
61
+ - `state.devServer.runtimeServer: false` (library-only project, no dev server to scan against)
62
+
63
+ ## Render-path fallback
64
+
65
+ If no browser/simulator/native-AX render path is available, `ui-validator` returns `skipped` with the reason and the orchestrator records the evidence gap. Review-D then falls back to `audit-design-rules.mjs` plus the static checks in `skills/build-loop/fallbacks.md#web-ui`. IBR is not an automatic fallback; run `build-loop:ibr-bridge` only when the user explicitly asks for IBR / Interface Built Right / `.ibr-test.json`.