@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
@@ -9,12 +9,13 @@ and checks whether each required item is answered (not blank, not
9
9
  the literal placeholder text, and not omitted entirely).
10
10
 
11
11
  Exit codes:
12
- 0 — all required items answered (Items 15 and 17 are conditional on UI files in scope)
12
+ 0 — all required items answered (Items 15 and 17 are conditional on UI files in scope;
13
+ Item 16 is optional when no high-consequence boundary is identified)
13
14
  1 — one or more items missing or unanswered
14
15
  2 — verifier error (file not found, parse failure)
15
16
 
16
17
  Usage:
17
- python3 check_checklist.py --plan docs/plans/my-feature.md [--json] [--quiet]
18
+ python3 check_checklist.py --plan .build-loop/plans/my-feature.md [--json] [--quiet]
18
19
  """
19
20
  from __future__ import annotations
20
21
 
@@ -47,6 +48,11 @@ ITEMS: list[tuple[str, str]] = [
47
48
  ("item_15_synthesis_dimensions", "Item 15 — Synthesis dimensions"),
48
49
  ("item_16_risk_reason", "Item 16 — Risk reason"),
49
50
  ("item_17_ui_io_contract", "Item 17 — UI input/output contract"),
51
+ ("item_18_dispatch_tier", "Item 18 — Dispatch tier per work item"),
52
+ ("item_19_env_var_manifest", "Item 19 — Env-var manifest"),
53
+ ("item_20_capability_gap_map", "Item 20 — Capability gap map"),
54
+ ("item_21_single_shot_guardrails", "Item 21 — Single-shot build guardrails"),
55
+ ("item_22_read_before_edit_map", "Item 22 — Read-before-edit map"),
50
56
  ]
51
57
 
52
58
  # Values that count as "not answered" — case-insensitive, stripped
@@ -113,7 +119,7 @@ def is_answered(value: str) -> bool:
113
119
 
114
120
 
115
121
  # ---------------------------------------------------------------------------
116
- # Structural validators for items 9-14
122
+ # Structural validators for higher-order checklist items
117
123
  # ---------------------------------------------------------------------------
118
124
 
119
125
  # ID patterns: U-NN, F-NN, D-NN, S-NN, T-NN, A-NN
@@ -155,6 +161,29 @@ _UI_IO_REQUIRED_TERMS = (
155
161
  "state", "modality", "validation", "traceability",
156
162
  )
157
163
 
164
+ # Items 20-22 — implementation accuracy checks.
165
+ _IMPLEMENTATION_SCOPE_RE = re.compile(
166
+ r"""
167
+ (
168
+ ^##\s+Six-Commit\s+Table\b
169
+ |\bCommit\s+subject\b
170
+ |\bFiles\s+owned\b
171
+ |\bmodifies_api\s*:
172
+ |\bdispatch_tier\s*:
173
+ )
174
+ """,
175
+ re.IGNORECASE | re.MULTILINE | re.VERBOSE,
176
+ )
177
+ _CAPABILITY_GAP_SECTION_RE = re.compile(
178
+ r"^##\s+Capability\s+Gap\s+Map\b", re.IGNORECASE | re.MULTILINE)
179
+ _SINGLE_SHOT_GUARDRAILS_SECTION_RE = re.compile(
180
+ r"^##\s+Single-Shot\s+Build\s+Guardrails\b", re.IGNORECASE | re.MULTILINE)
181
+ _READ_BEFORE_EDIT_SECTION_RE = re.compile(
182
+ r"^##\s+Read-Before-Edit\s+Map\b", re.IGNORECASE | re.MULTILINE)
183
+ _CAPABILITY_GAP_REQUIRED_TERMS = ("current", "target", "gap", "validation")
184
+ _SINGLE_SHOT_REQUIRED_TERMS = ("guardrail", "prevents", "evidence")
185
+ _READ_BEFORE_EDIT_REQUIRED_TERMS = ("read first", "why", "edit after")
186
+
158
187
 
159
188
  def check_item_15_synthesis_dimensions(plan_text: str) -> tuple[str, str | None]:
160
189
  """OK if no UI in scope; else require synthesis_dimensions block w/ all keys."""
@@ -194,6 +223,71 @@ def check_item_17_ui_io_contract(plan_text: str) -> tuple[str, str | None]:
194
223
  return ("OK", None)
195
224
 
196
225
 
226
+ def _section_body(section_re: re.Pattern, text: str) -> str | None:
227
+ """Return the section body after a matched level-2 heading, or None if absent."""
228
+ m = section_re.search(text)
229
+ if not m:
230
+ return None
231
+ section_start = m.end()
232
+ next_heading = re.search(r"^##\s+", text[section_start:], re.MULTILINE)
233
+ return (
234
+ text[section_start: section_start + next_heading.start()]
235
+ if next_heading else text[section_start:]
236
+ )
237
+
238
+
239
+ def _accuracy_section_findings(text: str) -> list[dict]:
240
+ """Warn when implementation plans omit sections that prevent rework."""
241
+ body_text = CHECKLIST_RE.sub("", text)
242
+ if not _IMPLEMENTATION_SCOPE_RE.search(body_text):
243
+ return []
244
+
245
+ findings: list[dict] = []
246
+ section_specs = [
247
+ (
248
+ "item_20_capability_gap_map",
249
+ "Item 20 — Capability gap map",
250
+ _CAPABILITY_GAP_SECTION_RE,
251
+ _CAPABILITY_GAP_REQUIRED_TERMS,
252
+ "Implementation scope detected but no `## Capability Gap Map` section found.",
253
+ ),
254
+ (
255
+ "item_21_single_shot_guardrails",
256
+ "Item 21 — Single-shot build guardrails",
257
+ _SINGLE_SHOT_GUARDRAILS_SECTION_RE,
258
+ _SINGLE_SHOT_REQUIRED_TERMS,
259
+ "Implementation scope detected but no `## Single-Shot Build Guardrails` section found.",
260
+ ),
261
+ (
262
+ "item_22_read_before_edit_map",
263
+ "Item 22 — Read-before-edit map",
264
+ _READ_BEFORE_EDIT_SECTION_RE,
265
+ _READ_BEFORE_EDIT_REQUIRED_TERMS,
266
+ "Implementation scope detected but no `## Read-Before-Edit Map` section found.",
267
+ ),
268
+ ]
269
+ for item_id, label, section_re, required_terms, missing_message in section_specs:
270
+ section = _section_body(section_re, body_text)
271
+ if section is None:
272
+ findings.append({
273
+ "item_id": item_id,
274
+ "label": label,
275
+ "status": "warn",
276
+ "message": missing_message,
277
+ })
278
+ continue
279
+ lower = section.lower()
280
+ missing_terms = [term for term in required_terms if term not in lower]
281
+ if missing_terms:
282
+ findings.append({
283
+ "item_id": item_id,
284
+ "label": label,
285
+ "status": "warn",
286
+ "message": "Section is present but missing term(s): " + ", ".join(missing_terms),
287
+ })
288
+ return findings
289
+
290
+
197
291
  def _structural_findings(text: str, plan_path: Path) -> list[dict]:
198
292
  """
199
293
  Run structural checks for higher-order checklist items against the full plan text.
@@ -202,9 +296,10 @@ def _structural_findings(text: str, plan_path: Path) -> list[dict]:
202
296
  These supplement — they do not replace — the checklist block checks.
203
297
  """
204
298
  findings = []
299
+ body_text = CHECKLIST_RE.sub("", text) # strip the <!-- checklist --> block
205
300
 
206
301
  # Item 9: P0 lines must have at least one T- reference
207
- p0_lines = [ln for ln in text.splitlines() if _P0_LINE_RE.search(ln)]
302
+ p0_lines = [ln for ln in body_text.splitlines() if _P0_LINE_RE.search(ln)]
208
303
  if p0_lines:
209
304
  p0_without_test = [ln for ln in p0_lines if not _T_ID_RE.search(ln)]
210
305
  if p0_without_test:
@@ -220,9 +315,9 @@ def _structural_findings(text: str, plan_path: Path) -> list[dict]:
220
315
  else:
221
316
  # Also verify at least one full trace chain appears (U-, F-, T-)
222
317
  has_chain = (
223
- bool(_ID_RE.search(text))
224
- and bool(re.search(r"\bU-\d+\b", text))
225
- and bool(re.search(r"\bF-\d+\b", text))
318
+ bool(_ID_RE.search(body_text))
319
+ and bool(re.search(r"\bU-\d+\b", body_text))
320
+ and bool(re.search(r"\bF-\d+\b", body_text))
226
321
  )
227
322
  if not has_chain:
228
323
  findings.append({
@@ -236,7 +331,7 @@ def _structural_findings(text: str, plan_path: Path) -> list[dict]:
236
331
  })
237
332
 
238
333
  # Item 10: ## Spec Object (JSON) section must exist
239
- if not _JSON_SPEC_SECTION_RE.search(text):
334
+ if not _JSON_SPEC_SECTION_RE.search(body_text):
240
335
  findings.append({
241
336
  "item_id": "item_10_json_spec_object",
242
337
  "label": "Item 10 — JSON spec object",
@@ -248,12 +343,15 @@ def _structural_findings(text: str, plan_path: Path) -> list[dict]:
248
343
  })
249
344
 
250
345
  # Item 11: Open Questions entries must carry blocking-test: annotation
251
- oq_match = _OPEN_Q_SECTION_RE.search(text)
346
+ oq_match = _OPEN_Q_SECTION_RE.search(body_text)
252
347
  if oq_match:
253
348
  # Extract the Open Questions section (up to the next ## heading)
254
349
  oq_start = oq_match.end()
255
- next_heading = re.search(r"^##\s+", text[oq_start:], re.MULTILINE)
256
- oq_body = text[oq_start: oq_start + next_heading.start()] if next_heading else text[oq_start:]
350
+ next_heading = re.search(r"^##\s+", body_text[oq_start:], re.MULTILINE)
351
+ oq_body = (
352
+ body_text[oq_start: oq_start + next_heading.start()]
353
+ if next_heading else body_text[oq_start:]
354
+ )
257
355
  # Count question lines (non-empty, non-heading lines)
258
356
  q_lines = [ln.strip() for ln in oq_body.splitlines()
259
357
  if ln.strip() and not ln.strip().startswith("#")]
@@ -270,8 +368,8 @@ def _structural_findings(text: str, plan_path: Path) -> list[dict]:
270
368
  })
271
369
 
272
370
  # Item 12: Low-reversibility decision mentions must have ADR link
273
- low_rev_lines = [ln for ln in text.splitlines() if _LOW_REV_RE.search(ln)]
274
- adr_headings_exist = bool(_ADR_HEADING_RE.search(text))
371
+ low_rev_lines = [ln for ln in body_text.splitlines() if _LOW_REV_RE.search(ln)]
372
+ adr_headings_exist = bool(_ADR_HEADING_RE.search(body_text))
275
373
  if low_rev_lines and not adr_headings_exist:
276
374
  findings.append({
277
375
  "item_id": "item_12_low_reversibility_adrs",
@@ -284,7 +382,6 @@ def _structural_findings(text: str, plan_path: Path) -> list[dict]:
284
382
  })
285
383
 
286
384
  # Item 13: Analytical lens line must appear in the plan body (outside the checklist block)
287
- body_text = CHECKLIST_RE.sub("", text) # strip the <!-- checklist --> block
288
385
  if not _LENS_LINE_RE.search(body_text):
289
386
  findings.append({
290
387
  "item_id": "item_13_analytical_lens",
@@ -306,7 +403,7 @@ def _structural_findings(text: str, plan_path: Path) -> list[dict]:
306
403
  "status": "warn",
307
404
  "message": (
308
405
  f"Sibling handoff file '{handoff_path.name}' not found. "
309
- "Generate docs/plans/<slug>.handoff.md alongside the plan."
406
+ "Generate .build-loop/plans/<slug>.handoff.md alongside the plan."
310
407
  ),
311
408
  })
312
409
 
@@ -330,6 +427,8 @@ def _structural_findings(text: str, plan_path: Path) -> list[dict]:
330
427
  "message": msg_17,
331
428
  })
332
429
 
430
+ findings.extend(_accuracy_section_findings(text))
431
+
333
432
  return findings
334
433
 
335
434
 
@@ -22,8 +22,10 @@ Use this skill when `uiTarget != null` and the work is not copy-only:
22
22
  4. Run a Calm Precision core-consideration pass before selecting style: name the principles most relevant to the surface, the perceptual foundation behind each one, and the concrete implication for this build.
23
23
  5. Load project-local visual evidence: current screens, screenshots, tokens, components, selected mockups, and existing `.build-loop/app-contract/ui.md`.
24
24
  6. Select only the guidance sources needed for the surface from `references/ui-guidance-sources.md`.
25
- 7. Choose the design direction from product fit: user job, workflow frequency, data shape, information density, platform, accessibility risk, error cost, and the Calm Precision core-consideration pass.
26
- 8. Have `design-contract-specialist` write the decision to `.build-loop/app-contract/ui.md`.
25
+ 7. Derive colour from the engine, never by hand load `references/color-engine.md` before writing any hex, generating a palette, or accepting an inherited one (including a mode brief's). Check for the Groundwork colour engine first (`$GROUNDWORK_ROOT` env var, else the checkout path `references/color-engine.md` names) — when it's present, use it as documented there. When it's absent, `references/color-engine.md`'s own "No Groundwork checkout" fallback section is the design route instead of hand-picking hex values: it distills the same rules (one accent, two stops, contrast verified per role) into a checkout-free procedure. Either way, declare in `.build-loop/app-contract/ui.md` which path produced the palette — engine or fallback. A palette is a relationship vector, not a list of colours: contrast is solved per role and verified in both the light and dark twin. One accent, status hues reserved, colour only where it encodes state.
26
+ 8. Choose the design direction from product fit: user job, workflow frequency, data shape, information density, platform, accessibility risk, error cost, and the Calm Precision core-consideration pass.
27
+ 9. Have `design-contract-specialist` write the decision to `.build-loop/app-contract/ui.md`.
28
+ 10. When the work updates, compares, or audits a renderable UI design, invoke headless IBR as the primary visual verifier when installed. Follow `../../references/ibr-ui-verification-policy.md`; record the platform fallback when IBR is unavailable.
27
29
 
28
30
  ## Design Layers
29
31
 
@@ -34,7 +36,7 @@ Think in layers, not competing design systems:
34
36
  3. **Calm Precision core considerations** — the baseline rules and perceptual-science foundations that every design direction must satisfy or explicitly except.
35
37
  4. **Project surface** — existing tokens, components, brand, screenshots, and selected mockups.
36
38
  5. **Structure or style mode** — recent design structures such as Conversational Command Surface, Bento Operating Dashboard, Pipeline Wizard, Outcome Ledger, Pyramid Detail, Glass Workspace, Warm Craft, Data Narrative, native mobile, or AI Artifact Canvas.
37
- 6. **Validation evidence** — `ui-validator`, design-rule scanner, browser/simulator screenshots, and contract traceability.
39
+ 6. **Validation evidence** — IBR comparison/scan evidence when installed, then `ui-validator`, design-rule scanner, browser/simulator screenshots, and contract traceability.
38
40
 
39
41
  Calm Precision is not just one optional theme or reference. It is a core design gate. Every non-trivial UI decision should be checked against the relevant Calm Precision principles before selecting structure, style mode, token treatment, motion, or interaction behavior. A Glass, Warm Craft, Aurora, Data Narrative, or native mobile direction can change surface treatment, density, and mood, but it must not override Calm Precision's hierarchy, accessibility, motion, interaction, and real-data rules unless the app contract records an explicit exception.
40
42
 
@@ -66,7 +68,7 @@ Implementers should read the app contract and UI input/output contract, not the
66
68
 
67
69
  ## Guardrails
68
70
 
69
- - Do not route to IBR unless the user explicitly asks for IBR, Interface Built Right, or an IBR-specific artifact.
71
+ - Route every renderable UI design update, comparison, or audit through the automatic IBR policy in `../../references/ibr-ui-verification-policy.md`. Interactive IBR viewers and persistent sessions remain explicit-only.
70
72
  - Do not force recent structures. They are options, not requirements.
71
73
  - Do not treat Calm Precision as a citation, theme, or surface style. Use it as the shared baseline and decision gate under the selected mode.
72
74
  - Do not load broad vault/research folders into implementation prompts. Select one to three relevant sources and synthesize them.
@@ -0,0 +1,132 @@
1
+ # Colour: use the engine, don't pick hexes
2
+
3
+ Short version: **choosing a palette by choosing colours is the wrong move.** Groundwork
4
+ owns a colour engine that derives palettes from a *relationship vector* and verifies every
5
+ role's contrast mathematically. Build-loop routes colour decisions there instead of
6
+ duplicating the theory. This file is the pointer plus the handful of rules that matter
7
+ when you are mid-build and don't want to leave the loop.
8
+
9
+ Canonical docs (if you have the checkout): `$GROUNDWORK_ROOT/designer/color/README.md`
10
+ Engine: `designer/color/relationships.py` · Elicitation: `designer/decide/color_dimensions.py`
11
+
12
+ ## Checkout detection
13
+
14
+ The engine lives in a separate Groundwork checkout, not inside build-loop. Resolve it before running anything below, in order:
15
+
16
+ 1. `$GROUNDWORK_ROOT` env var, if set — use it directly.
17
+ 2. Else, a sibling checkout next to your other repos (commonly `groundwork` alongside build-loop) — use it only if `designer/color/relationships.py` actually exists under it.
18
+ 3. Else, no checkout is available — skip "The 60-second path" below and go straight to "No Groundwork checkout" further down. Do not fall through to hand-picked hex values; that is exactly the mistake this file exists to prevent.
19
+
20
+ Whichever branch resolves, declare it in `.build-loop/app-contract/ui.md` (`palette_source: engine` or `palette_source: fallback (no groundwork checkout)`).
21
+
22
+ ## The one idea
23
+
24
+ A palette is a vector of relationships — contrast targets, chroma structure, hue deltas —
25
+ not a list of colours. Fix the relationships, rotate the anchor hue, and you get an
26
+ infinite family of equally valid systems. `preview.py --sweep-hue 12` demonstrates it:
27
+ same vector, twelve hues, all passing.
28
+
29
+ **So the hue is the least load-bearing decision in the palette.** What carries the design:
30
+ one accent, two stops (light + dark), contrast verified per role, status hues untouched.
31
+ If a build is stuck arguing indigo vs teal, that argument is not the blocker.
32
+
33
+ ## When to reach for it
34
+
35
+ - Any new product surface that needs a palette.
36
+ - Any time you are about to type a hex into a component, mockup, or token file.
37
+ - Any inherited palette you have not verified (mode briefs, design docs, an existing app).
38
+
39
+ ## The 60-second path
40
+
41
+ ```bash
42
+ GW="$GROUNDWORK_ROOT" # resolved above — only reached when the checkout was found
43
+
44
+ # Verify a palette you already have — returns solved replacements, same hue + chroma
45
+ PYTHONPATH=$GW python3 -m designer.color.combos ingest \
46
+ --name <slug> --surface '#0b0b0f' --text '#f4f4f5' --accent '#818cf8'
47
+
48
+ # Or generate: both twins from one vector (light 0.985 / dark 0.16)
49
+ PYTHONPATH=$GW python3 -m designer.color.preview --sweep-hue 6 \
50
+ --params '{"energy":"balanced","contrast_feel":"crisp","accent_intensity":"clear",
51
+ "harmony":"analogous","anchor_hue":277,"surface_L":0.16}' > /tmp/p.html
52
+ ```
53
+
54
+ Use the returned `surface / on_surface / muted / accent / on_accent` roles verbatim.
55
+
56
+ ## Rules worth memorising
57
+
58
+ 1. **One accent.** Status hues are reserved — success/green, warning/amber, error/red. An
59
+ accent that collides with one destroys the signal: if the brand accent *is* the success
60
+ green, "success" stops meaning anything. Check the status set before choosing an anchor.
61
+ 2. **Two stops, always.** An accent can clear AA on near-black and fail badly on white.
62
+ Solve both twins from the same vector; never invert one and assume.
63
+ 3. **`clipped: true` is not a choice.** It means sRGB cannot render that chroma, so it will
64
+ render duller than the brief promises. Lower `energy` or `accent_intensity` instead.
65
+ 4. **The accent is the anchor rotated by the harmony delta**, not the anchor. Default
66
+ split-complementary turns a cool 250° anchor into an orange accent. Want the accent in
67
+ the anchor family? `harmony: analogous`.
68
+ 5. **Colour encodes state, not decoration.** An accent-coloured kicker or eyebrow carries
69
+ no meaning — drop it. Recorded owner preference, not a style opinion.
70
+ 6. **Never claim a preference that wasn't elicited.** If `designer.decide.profile show`
71
+ is empty, there is no recorded colour taste — say so rather than inferring one.
72
+ 7. **Label polarity matches the mode.** `on_accent_prefer` defaults to `auto` → a light
73
+ label on a dark surface. Left to ratio alone the solver picks a near-black label for a
74
+ dark-mode accent: it passes 4.5:1 and reads as inverted, because every other foreground
75
+ on that surface is light. Buying the right polarity may trade fill contrast down to
76
+ `accent_contrast_floor` (3.0) — legal, since a fill is a non-text component under WCAG
77
+ 1.4.11. The result flags `accent_contrast_relaxed: true`.
78
+ 8. **Look at the render, not only the report.** Contrast is a scalar and scores
79
+ white-on-indigo and black-on-indigo identically, so `all_contrast_targets_met: true` is
80
+ a floor, not a verdict. Measure every ratio you show with `contrast_hex()` against the
81
+ hexes actually rendered — never copy a row between options, never round from memory.
82
+
83
+ ## No Groundwork checkout
84
+
85
+ Reached only when "Checkout detection" above found neither `$GROUNDWORK_ROOT` nor a sibling checkout. Do not hand-pick hex values — apply the same relationship-vector rules manually instead, and declare the fallback in the app contract (`palette_source: fallback (no groundwork checkout)`), not just the resulting hexes:
86
+
87
+ 1. **One accent, status hues reserved.** Same as rule 1 above: pick a single accent hue; never let it collide with success/warning/error.
88
+ 2. **Two stops, always.** Same as rule 2 above: solve a light surface and a dark surface from the same accent; don't invert one and assume the other passes.
89
+ 3. **Verify contrast per role with a script, not by eye or memory.** Without the engine's `contrast_hex()` you still owe every foreground/background pairing a real number: WCAG relative luminance and contrast ratio, text ≥4.5:1, large text/non-text UI components ≥3:1 (WCAG 1.4.11). Compute it, don't estimate it:
90
+
91
+ ```python
92
+ def _lin(c):
93
+ c /= 255
94
+ return c / 12.92 if c <= 0.03928 else ((c + 0.055) / 1.055) ** 2.4
95
+
96
+ def luminance(hex_color):
97
+ r, g, b = (int(hex_color[i:i + 2], 16) for i in (1, 3, 5))
98
+ return 0.2126 * _lin(r) + 0.7152 * _lin(g) + 0.0722 * _lin(b)
99
+
100
+ def contrast(hex_a, hex_b):
101
+ l1, l2 = sorted((luminance(hex_a), luminance(hex_b)), reverse=True)
102
+ return (l1 + 0.05) / (l2 + 0.05)
103
+ ```
104
+
105
+ 4. **Colour encodes state, not decoration.** Same as rule 5 above — no accent-coloured kickers or eyebrows without a status meaning.
106
+ 5. **Never claim an unelicited preference.** If there's no recorded colour taste for this project (no mode brief, no existing tokens), pick one sensible neutral+accent pair, verify it with the script above, and say plainly it's a fallback default, not a recorded preference.
107
+
108
+ This produces a *valid* palette, not an *equivalent* one — it skips the OKLCH relationship-vector math, the sweep-hue family, and taste-profile accumulation the real engine gives you. Record that gap in the app contract rather than treating the fallback as parity with the engine.
109
+
110
+ ## Feeding what you learn back
111
+
112
+ Palette decisions made during a build should not evaporate when the run ends:
113
+
114
+ ```bash
115
+ # Record an accepted system (or a new relationship pattern you invented)
116
+ PYTHONPATH=$GW python3 -m designer.color.combos add --name <slug> \
117
+ --params '<vector>' --intent "<where it fits>" --source mine
118
+
119
+ # Fold elicited dimensions into the cross-project taste profile
120
+ PYTHONPATH=$GW python3 -m designer.decide.profile record-dims '{"contrast_feel":"crisp"}'
121
+ ```
122
+
123
+ This is the mechanism that lets the system accumulate favourites and new vector
124
+ arrangements over time. Skipping it is why the profile stays empty and every project
125
+ re-asks settled questions.
126
+
127
+ ## Known trap
128
+
129
+ The flow that most often breaks the rule is **mockup authoring**, because typing a hex
130
+ into HTML feels like design work. It isn't — it's guessing with extra steps, and a mode
131
+ brief's hexes were authored for *that brief's* context, not the surface you're building.
132
+ Validate or regenerate before use.
@@ -7,7 +7,7 @@
7
7
  > Sourced from `.build-loop/design-evidence/*.md` (8 apps scanned 2026-05-26). Every claim in this file traces to a specific evidence file. The evidence files are the ground truth — when this doc and an evidence file disagree, the evidence file wins.
8
8
  >
9
9
  > **Primary preferred references** (per intent.md): Sample Voice iOS, Sample Timer (iPad primary), Sample Reader, Sample Product App.
10
- > **Secondary / directional** (note what works AND what user dislikes): Secrets Vault macOS, Sample Decision App, Sample Offline iOS, Sample Onboarding App.
10
+ > **Secondary / directional** (note what works AND what user dislikes): Sample Secrets App (macOS), Sample Decision App, Sample Offline iOS, Sample Onboarding App.
11
11
 
12
12
  ---
13
13
 
@@ -16,7 +16,7 @@
16
16
  **Universal non-negotiable:** *"Visual hierarchy is one-glance recoverable"* (alt doc §2.12) + Calm Precision's *"Title (14-16px bold) → Description (12-14px) → Metadata (11-12px muted)"*.
17
17
 
18
18
  **What works (primary apps):**
19
- - **Secrets Vault** — verbatim CP 6.4.1 implementation in `VaultTypography.swift` (evidence: `secrets-vault-macos.md`). Token comment in source code: *"L1: Title 15px medium high contrast → L2: Description 13px regular medium contrast → L3: Metadata 11px regular low contrast."* This is the textbook reference.
19
+ - **Sample Secrets App** — verbatim CP 6.4.1 implementation in a dedicated typography token file (evidence: `sample-secrets-app.md`). Three named tiers (title/description/metadata) map directly to size + contrast rung. This is the textbook reference.
20
20
  - **Sample Timer App** — `TextRole` enum (`Theme.swift:689-721` per `sample-timer.md`) ladders seven named roles (display/title/headline/subheadline/body/caption/micro) with explicit baseSize + defaultWeight per rung. Tokens cite role purpose: *"display: 30pt — single largest element on a screen."*
21
21
  - **Sample Voice App** — nine named typography tokens (`Theme.swift:31-35,70-75` per `sample-voice-ios.md`) including `fontTabular` (10pt mono-equivalent for numerics) — a use-case that single-purpose token sets miss.
22
22
 
@@ -34,7 +34,7 @@
34
34
  **What works (primary apps):**
35
35
  - **Sample Product App** — strictest single-accent enforcement in inventory: `--primary === --accent === --ring === #f0b65e` (`index.css:18,22,26` per `sample-product.md`). The entire palette is warm-monochromatic; the only "second color" is `--success: #7bc67e` (muted sage) and `--destructive: #e06356` (warm red-orange, not pure red — palette discipline holds even on error).
36
36
  - **Sample Reader** — explicit semantic separation: `--color-error-bg` and `--color-error-border` exist for tinted alert containers, but they are tokens distinct from `--status-error` (the foreground text color). Container surfaces are gated to reading flow where text-color-only would underread (`sample-reader.md` cites the divergence with rationale).
37
- - **Secrets Vault** — three-tier text contrast (`textPrimary / textSecondary / textMuted` = stone-900 / stone-600 / stone-400 in light; stone-100 / stone-300 / stone-450 in dark, per `secrets-vault-macos.md`). Each tier maps directly to L1/L2/L3 of the typography ladder — text size + text contrast move together.
37
+ - **Sample Secrets App** — three-tier text contrast (primary/secondary/muted = stone-900 / stone-600 / stone-400 in light; stone-100 / stone-300 / stone-450 in dark, per `sample-secrets-app.md`). Each tier maps directly to L1/L2/L3 of the typography ladder — text size + text contrast move together.
38
38
 
39
39
  **Anti-pattern (secondary apps):**
40
40
  - **Sample Decision App theme-toggle pattern** — three switchable themes (F default, A "Case File," B "Conversation") via `[data-theme="A"|"B"]` on `<html>` (evidence: `sample-decision-app.md`). Each theme owns the same 6 token names but different brand colors. *Works for*: keeping semantic meaning constant across visual presentation. *Fails for*: brand identity — a brand that can become blue or terracotta or red is brand-fungible. Likely user-dislike: the existence of the toggle dilutes the canonical voice (Theme F).
@@ -86,7 +86,7 @@
86
86
  **What works (primary apps):**
87
87
  - **Sample Decision App** — `@media (prefers-reduced-motion: reduce)` overrides all animations to 0.01ms at the globals level (`app/globals.css:65-71` per `sample-decision-app.md`). Single CSS rule covers the whole app.
88
88
  - **Sample Voice App** — `@Environment(\.accessibilityReduceMotion)` honored on HomeView; first-time onboarding animation gated to once per AppStorage flag (`HomeView.swift:16,47` per `sample-voice-ios.md`).
89
- - **Secrets Vault** — stagger animation capped at 400ms total (`60ms × N items, max 400ms`) — prevents the long-list "wave" anti-pattern (per project CLAUDE.md cited in `secrets-vault-macos.md`).
89
+ - **Sample Secrets App** — stagger animation capped at 400ms total (`60ms × N items, max 400ms`) — prevents the long-list "wave" anti-pattern (per its project guidance, cited in `sample-secrets-app.md`).
90
90
  - **Sample Onboarding App** — StatusBanner's `phase label itself stays visible briefly after a stage transition so the user sees the most recent phase without flicker` (verbatim from `StatusBanner.swift` per `sample-onboarding-app.md`). Anti-flicker is a documented design decision, encoded in code comments.
91
91
 
92
92
  **Preference recorded:** **`prefers-reduced-motion` / `accessibilityReduceMotion` must be respected by default, not opt-in. Stagger animations have a total-time cap, not just a per-item interval. Anti-flicker behavior is a first-class design concern, not an afterthought.**
@@ -98,7 +98,7 @@
98
98
  **Universal non-negotiable:** *"When something fails, explain what happened, preserve context, give a next step"* (alt doc §1.5 Recover) + *"Resilient to imperfect input"* (alt doc §2.9).
99
99
 
100
100
  **What works (primary apps):**
101
- - **Secrets Vault** — explicit three-part error pattern named in project CLAUDE.md (cited `secrets-vault-macos.md`): *"Errors: what why fix pattern."* Plus voice rule: *"Verb+Object labels, contextual loading ('Deriving encryption key…')"* loading messages name the actual operation.
101
+ - **Sample Secrets App** — explicit three-part error pattern named in its project guidance (cited `sample-secrets-app.md`): what happened, why, and how to fix it. Loading states use verb+object labels naming the actual operation in progress (e.g. a key-derivation step), not a generic "Loading…".
102
102
  - **Sample Offline iOS** — *"Errors surface inline (red footnote) without removing cached rows — offline still shows the last good list"* (`CampsListView.swift` code comment per `sample-offline-ios.md`). On error, the cache is preserved — graceful degradation in action.
103
103
  - **Sample Voice App** — `Haptics.impact(.light)` paired with state change on every CTA tap (`HomeView.swift:81` per `sample-voice-ios.md`) — action feedback via haptic + visible state, not just one or the other.
104
104
 
@@ -122,12 +122,12 @@
122
122
 
123
123
  A new app in this ecosystem should, in priority order:
124
124
 
125
- 1. **Token files first** — `Theme/Colors`, `Theme/Typography` (or `index.css`-equivalent for web) before the first view is written. Use Sample Voice App / Sample Timer App / Secrets Vault as templates.
125
+ 1. **Token files first** — `Theme/Colors`, `Theme/Typography` (or `index.css`-equivalent for web) before the first view is written. Use Sample Voice App / Sample Timer App / Sample Secrets App as templates.
126
126
  2. **One accent. Single. Don't theme-toggle.** Sample Product App is the strictest example.
127
- 3. **Three-line text hierarchy** baked into the typography enum. Secrets Vault's `VaultTypography.title/.description/.metadata` is the textbook.
127
+ 3. **Three-line text hierarchy** baked into the typography enum. Sample Secrets App's title/description/metadata tier naming is the textbook.
128
128
  4. **Touch targets at the component layer.** Sample Product App's `.btn-primary` is the example.
129
129
  5. **`prefers-reduced-motion` / `accessibilityReduceMotion` from day one.** The sample decision app's single-CSS-rule approach is the cheapest implementation.
130
- 6. **Errors are calm, informative, non-destructive.** The sample offline app's offline-preserves-cache + Secrets Vault's what→why→fix pattern combine into a single rule.
130
+ 6. **Errors are calm, informative, non-destructive.** The sample offline app's offline-preserves-cache + Sample Secrets App's what→why→fix pattern combine into a single rule.
131
131
  7. **Multi-form-factor via viewport-scale tokens, not forked themes.** Sample Timer App's `\.viewportScale` is the reference; the multi-pattern framework draft (`design-patterns-multi.md`) is where this becomes formal if/when prototyped.
132
132
 
133
133
  When deviating: name the deviation in the token file's comments, the way Sample Timer App flags off-grid spacing and Sample Reader flags tinted error containers. The discipline is the comment.
@@ -192,7 +192,7 @@ High-signal sources:
192
192
  - `interface-built-right/templates/patterns/`
193
193
  - `interface-built-right/src/ui-guidance/`
194
194
 
195
- Use only when the user explicitly asks for IBR or when a selected IBR artifact is passed to the specialist as evidence. Do not make IBR the default build route.
195
+ Use IBR automatically as the verifier for renderable UI design updates, comparisons, and audits under `../../../references/ibr-ui-verification-policy.md`. IBR does not own design direction; pass its evidence to the specialist and keep viewer/dashboard surfaces explicit-only.
196
196
 
197
197
  ## Mockup Gallery
198
198
 
@@ -39,7 +39,7 @@ These ten apply to every artifact produced or reviewed.
39
39
  - *Cited precedent:* Sample Product App uses a single accent (`--primary === --accent === --ring === #f0b65e`) and warm-monochromatic palette discipline — strictest single-accent in inventory. See `sample-product.md`. Counter-pattern: the sample decision app's three-theme toggle (`[data-theme="A"|"B"]`) preserves semantic meaning across visual presentation but dilutes brand voice — see `sample-decision-app.md`.
40
40
  11. **Content fits its container, or the container fits the content.** Clipping, truncation without recovery, awkward wraps, and overflow are design failures. Decide which side flexes (fixed container with overflow recovery, or fluid container that grows). Critical content never shrinks below its reading threshold to fit.
41
41
  12. **Visual hierarchy is one-glance recoverable.** A user reading at speed knows what is most important, what is next, what is supporting — from position, size, weight, contrast, and spacing alone. If color is removed, the hierarchy still holds.
42
- - *Cited precedent:* Secrets Vault's `VaultTypography.title/.description/.metadata` (15/13/11pt) maps role names directly to L1/L2/L3 — see `.build-loop/design-evidence/secrets-vault-macos.md`. Anti-pattern: the sample onboarding app's inline pixel sizes across one view (12/13/14/15/16/18/20/34) — see `sample-onboarding-app.md`.
42
+ - *Cited precedent:* Sample Secrets App's title/description/metadata tier naming (15/13/11pt) maps role names directly to L1/L2/L3 — see `.build-loop/design-evidence/sample-secrets-app.md`. Anti-pattern: the sample onboarding app's inline pixel sizes across one view (12/13/14/15/16/18/20/34) — see `sample-onboarding-app.md`.
43
43
  13. **Fit form to information.** Prose, bullets, table, chart, diagram, checklist, form, callout, or slide rhythm chosen for the reading task — not the template.
44
44
  14. **Native primitives over visual fakes.** Use the medium's semantic structures: UI components, slide placeholders, document styles, table geometry, chart objects, alt text, headings, source notes. Don't fake them with glyphs, manual spacing, or screenshots.
45
45
  15. **Verify the rendered artifact.** Inspect the real output surface before declaring done. Screenshots for UI; rendered pages for docs and decks; live render for charts.
@@ -48,7 +48,7 @@ These ten apply to every artifact produced or reviewed.
48
48
 
49
49
  - **Interaction targets match input precision.** Touch needs more area than mouse; mouse more than keyboard focus; watch, remote, and voice each have their own envelope. The principle: a target the user can hit on the first try, comfortably, with the device in hand. Specific minimums live in platform skills (`accessibility-review`, platform HIGs).
50
50
  - **Motion serves comprehension, not decoration.** Animate when it explains origin, destination, or state change. Duration short enough not to delay, long enough to be perceived. Respects reduced-motion preferences.
51
- - *Cited precedent:* The sample decision app's single CSS rule overrides all animations to 0.01ms under `prefers-reduced-motion` (`app/globals.css:65-71`) — see `sample-decision-app.md`. Secrets Vault caps stagger at 400ms total (60ms × N items) — see `secrets-vault-macos.md`. The sample onboarding app documents anti-flicker behavior in code comments — see `sample-onboarding-app.md`.
51
+ - *Cited precedent:* The sample decision app's single CSS rule overrides all animations to 0.01ms under `prefers-reduced-motion` (`app/globals.css:65-71`) — see `sample-decision-app.md`. Sample Secrets App caps stagger at 400ms total (60ms × N items) — see `sample-secrets-app.md`. The sample onboarding app documents anti-flicker behavior in code comments — see `sample-onboarding-app.md`.
52
52
  - **Multi-form-factor via viewport-scale tokens.** When one codebase ships across iPhone, iPad, Mac, and Watch, scale a single hierarchy by a runtime env var rather than forking themes per platform.
53
53
  - *Cited precedent:* Sample Timer App's `\.viewportScale` env (1.0× iPhone → 1.5× iPad → live-window-resize Mac → separate watch palette + AOD dim variants); see `sample-timer.md`. Formalized as Pattern 1 / Pattern 4 in the multi-pattern framework draft at `skills/ui-design/references/design-patterns-multi.md`.
54
54
 
@@ -1,41 +0,0 @@
1
- {
2
- "name": "build-loop",
3
- "version": "0.36.0",
4
- "description": "Multi-phase build orchestration with native debugging: assess, plan, execute, review, iterate. Plan-verify gate on Phase 2. Optional UI design gates. Native debug-loop, debugging-memory, and logging-tracer skills provide root-cause investigation without a bundled MCP server. Orchestrator owns when-to-fire; bundled skills own procedural detail; bridges are optional escalation hops to supporting plugins for extended capability.",
5
- "author": {
6
- "name": "Tyrone Ross",
7
- "url": "https://github.com/tyroneross"
8
- },
9
- "homepage": "https://github.com/tyroneross/build-loop#readme",
10
- "repository": "https://github.com/tyroneross/build-loop",
11
- "license": "Apache-2.0",
12
- "keywords": [
13
- "development",
14
- "orchestration",
15
- "evaluation",
16
- "iteration",
17
- "build",
18
- "tdd",
19
- "fact-checking",
20
- "code-quality",
21
- "ui-validation",
22
- "accessibility",
23
- "design-rules",
24
- "debug-loop",
25
- "debugging",
26
- "causal-tree",
27
- "incident-memory"
28
- ],
29
- "skills": "./skills",
30
- "interface": {
31
- "displayName": "Build Loop",
32
- "shortDescription": "Multi-phase build orchestration with review gates, UI validation, debugging, and a Codex subagent adapter.",
33
- "longDescription": "Multi-phase build orchestration with native debugging: assess, plan, execute, review, iterate. Plan-verify gate on Phase 2. Optional UI design gates. Native debug-loop, debugging-memory, and logging-tracer skills provide root-cause investigation without a bundled MCP server. Orchestrator owns when-to-fire; bundled skills own procedural detail; bridges are optional escalation hops to supporting plugins for extended capability.",
34
- "developerName": "Ross Labs",
35
- "category": "Coding",
36
- "capabilities": [
37
- "Read",
38
- "Write"
39
- ]
40
- }
41
- }