@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.
- package/.agents/plugins/marketplace.json +2 -2
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor/rules/build-loop-surface.mdc +12 -11
- package/.cursor/rules/skill-index.mdc +33 -0
- package/AGENTS.md +213 -34
- package/README.md +99 -31
- package/agents/advisor.md +4 -4
- package/agents/alignment-checker.md +2 -2
- package/agents/architecture-scout.md +4 -4
- package/agents/build-orchestrator.md +38 -36
- package/agents/database-assessor.md +11 -5
- package/agents/design-contract-specialist.md +8 -8
- package/agents/fact-checker.md +13 -3
- package/agents/fix-critique.md +2 -2
- package/agents/independent-auditor.md +60 -7
- package/agents/leak-scanner.md +82 -0
- package/agents/overfitting-reviewer.md +2 -2
- package/agents/plan-critic.md +1 -1
- package/agents/promotion-reviewer.md +5 -5
- package/agents/retrospective-synthesizer.md +138 -35
- package/agents/scope-auditor.md +82 -11
- package/agents/security-reviewer.md +56 -2
- package/agents/self-improvement-architect.md +17 -3
- package/agents/transcript-pattern-miner.md +5 -5
- package/agents/ui-validator.md +1 -1
- package/bin/build-loop-debugger.js +143 -0
- package/bin/build-loop-install.js +1 -4
- package/bin/build-loop-load-probe.js +345 -0
- package/codex-skills/build-loop/SKILL.md +28 -6
- package/commands/feedback.md +37 -0
- package/dist/src/interactive-verifier.d.ts +1 -14
- package/dist/src/interactive-verifier.d.ts.map +1 -1
- package/dist/src/interactive-verifier.js +6 -113
- package/dist/src/interactive-verifier.js.map +1 -1
- package/dist/src/quality.d.ts +5 -0
- package/dist/src/quality.d.ts.map +1 -0
- package/dist/src/quality.js +81 -0
- package/dist/src/quality.js.map +1 -0
- package/dist/src/storage.d.ts.map +1 -1
- package/dist/src/storage.js +37 -3
- package/dist/src/storage.js.map +1 -1
- package/docs/agent-surface-policy.md +35 -31
- package/docs/memory-setup.md +19 -0
- package/hooks/git/pre-push +65 -4
- package/hooks/hooks.json +95 -38
- package/hooks/pre-commit +20 -1
- package/hooks/pre-edit-rally-point.sh +10 -3
- package/hooks/session-start-codex-hook-trust.sh +30 -0
- package/hooks/session-start-git-hooks.sh +3 -1
- package/hooks/session-start-rally-point.sh +52 -4
- package/hooks/session-start-worktree-gc.sh +47 -94
- package/hooks/stop-transcript-sweep.sh +173 -0
- package/hooks/test_closeout.sh +14 -2
- package/package.json +8 -7
- package/scripts/README.md +1 -1
- package/scripts/_paths.py +65 -0
- package/scripts/groundwork_exchange.py +1012 -0
- package/scripts/install_memory.py +33 -1
- package/scripts/lessons_index/ingest.py +13 -2
- package/scripts/lessons_index/query.py +36 -13
- package/scripts/memory_context/__init__.py +108 -14
- package/scripts/memory_graph/__init__.py +5 -1
- package/scripts/project_resolver.py +42 -36
- package/scripts/sync_plugin_cache.py +37 -2
- package/skills/agent-rally-point/SKILL.md +46 -0
- package/skills/api-registry-bridge/SKILL.md +1 -1
- package/skills/architecture/dead/SKILL.md +1 -1
- package/skills/architecture/impact/SKILL.md +1 -1
- package/skills/architecture/review/SKILL.md +1 -1
- package/skills/architecture/rules/SKILL.md +3 -3
- package/skills/architecture/scan/SKILL.md +1 -1
- package/skills/architecture/trace/SKILL.md +1 -1
- package/skills/attribution-standard/SKILL.md +6 -6
- package/skills/auto-decision-capture/SKILL.md +31 -2
- package/skills/auto-finding-capture/SKILL.md +28 -1
- package/skills/build-loop/SKILL.md +131 -23
- package/skills/build-loop/fallbacks.md +16 -21
- package/skills/build-loop/phases/ui-validation.md +2 -2
- package/skills/build-loop/references/advisor-dispatch-ladder.md +1 -1
- package/skills/build-loop/references/apple-native-planning.md +1 -1
- package/skills/build-loop/references/autonomous-and-per-commit-modes.md +11 -5
- package/skills/build-loop/references/autonomy-dashboard.md +115 -0
- package/skills/build-loop/references/capability-routing.md +24 -2
- package/skills/build-loop/references/coordination.md +24 -6
- package/skills/build-loop/references/experiment-results-template.md +15 -3
- package/skills/build-loop/references/leadership.md +1 -1
- package/skills/build-loop/references/memory.md +14 -3
- package/skills/build-loop/references/modular-systems-pack.md +8 -0
- package/skills/build-loop/references/output-style.md +86 -0
- package/skills/build-loop/references/phase-1-assess.md +102 -2
- package/skills/build-loop/references/phase-2-plan.md +9 -1
- package/skills/build-loop/references/phase-3-execute.md +5 -2
- package/skills/build-loop/references/phase-4-review.md +85 -8
- package/skills/build-loop/references/phase-5-iterate.md +76 -8
- package/skills/build-loop/references/phase-6-learn.md +10 -17
- package/skills/build-loop/references/privileged-request-broker.md +254 -0
- package/skills/build-loop/references/resource-aware-execution.md +183 -0
- package/skills/build-loop/references/self-recursive-dev.md +2 -2
- package/skills/build-loop/references/status-output-format.md +207 -0
- package/skills/build-loop/references/verify-dispatch.md +56 -2
- package/skills/building-with-deepagents/SKILL.md +1 -1
- package/skills/claim-scope/SKILL.md +185 -0
- package/skills/color-engine/SKILL.md +103 -0
- package/skills/color-engine/_core.py +464 -0
- package/skills/color-engine/color_engine.py +175 -0
- package/skills/cost-rca/SKILL.md +61 -0
- package/skills/data-plane-worktrees/SKILL.md +139 -0
- package/skills/data-plane-worktrees/agents/openai.yaml +4 -0
- package/skills/database-practice/SKILL.md +200 -0
- package/skills/database-practice/references/diagnostic-queries.sql +126 -0
- package/skills/database-practice/references/vector-and-graph-tuning.md +208 -0
- package/skills/database-practice/scripts/db_table_map.py +1244 -0
- package/skills/database-practice/scripts/test_db_table_map.py +514 -0
- package/skills/debug-loop/SKILL.md +36 -6
- package/skills/debugging-memory/SKILL.md +32 -430
- package/skills/debugging-memory/references/pattern-extraction.md +4 -4
- package/skills/debugging-memory/references/search.md +32 -120
- package/skills/debugging-memory/references/store.md +32 -126
- package/skills/debugging-memory/references/subagent-integration.md +1 -1
- package/skills/decision-queue/SKILL.md +251 -0
- package/skills/decision-queue/assets/template.html +1242 -0
- package/skills/decision-queue/references/example-large-queue-batching.md +164 -0
- package/skills/decision-queue/scripts/regen_template_constants.py +160 -0
- package/skills/defenseclaw-bridge/SKILL.md +2 -2
- package/skills/defenseclaw-bridge/references/dc-config-mapping.md +2 -9
- package/skills/drain-proposals/SKILL.md +53 -0
- package/skills/focused-loop-builder/SKILL.md +31 -0
- package/skills/focused-loop-builder/references/spec-format.md +27 -0
- package/skills/handoff/SKILL.md +169 -8
- package/skills/ibr-bridge/SKILL.md +4 -1
- package/skills/knowledge/SKILL.md +26 -14
- package/skills/knowledge/references/review-mode.md +2 -3
- package/skills/knowledge/templates/madr-minimal.md +1 -1
- package/skills/mcp-builder/SKILL.md +1 -1
- package/skills/model-bakeoff/SKILL.md +48 -10
- package/skills/model-tiering/SKILL.md +92 -31
- package/skills/native-ax-driver/SKILL.md +38 -5
- package/skills/native-ax-driver/scripts/native_driver.py +278 -22
- package/skills/native-ax-driver/scripts/test_native_driver.py +227 -0
- package/skills/optimize/SKILL.md +1 -1
- package/skills/plugin-builder/SKILL.md +48 -1
- package/skills/plugin-builder/references/build-loop-phase-guidance.md +3 -4
- package/skills/plugin-builder/references/distribution.md +13 -2
- package/skills/plugin-builder/references/plugin-hygiene-lessons.md +2 -2
- package/skills/plugin-tests/SKILL.md +2 -2
- package/skills/recursive-retrospective/SKILL.md +1 -1
- package/skills/repo-closeout/SKILL.md +17 -0
- package/skills/repo-closeout/agents/openai.yaml +4 -0
- package/skills/repo-maintenance/SKILL.md +179 -0
- package/skills/repo-maintenance/agents/openai.yaml +4 -0
- package/skills/repo-maintenance/references/pre-public-hygiene.md +134 -0
- package/skills/repo-maintenance/references/repository-taxonomy.md +161 -0
- package/skills/repo-maintenance/references/safety-protocol.md +106 -0
- package/skills/repo-maintenance/references/stack-profiles.md +138 -0
- package/skills/repo-maintenance/scripts/audit_repo_maintenance.py +1198 -0
- package/skills/repo-maintenance/scripts/test_audit_repo_maintenance.py +506 -0
- package/skills/repository-intelligence/SKILL.md +189 -0
- package/skills/repository-intelligence/agents/openai.yaml +4 -0
- package/skills/repository-intelligence/references/assessment-rubric.md +88 -0
- package/skills/repository-intelligence/scripts/repository_inventory.py +347 -0
- package/skills/research/SKILL.md +12 -2
- package/skills/root-cause-analysis/SKILL.md +1 -1
- package/skills/runtime-parity-verification/SKILL.md +36 -1
- package/skills/security-methodology/SKILL.md +23 -10
- package/skills/security-methodology/references/agentic-handoff-templates.md +220 -0
- package/skills/security-methodology/references/cross-source-matrix.md +1 -1
- package/skills/security-methodology/references/owasp-agentic-top-10.md +1 -1
- package/skills/security-scan/SKILL.md +55 -15
- package/skills/self-improve/SKILL.md +70 -50
- package/skills/silent-assumptions/SKILL.md +341 -0
- package/skills/silent-assumptions/references/elicitation-detectors.md +342 -0
- package/skills/spec-writing/SKILL.md +128 -24
- package/skills/spec-writing/scripts/check_checklist.py +114 -15
- package/skills/ui-design/SKILL.md +6 -4
- package/skills/ui-design/references/color-engine.md +132 -0
- package/skills/ui-design/references/design-preferences-from-owned-apps.md +8 -8
- package/skills/ui-design/references/ui-guidance-sources.md +1 -1
- package/skills/ui-design/references/universal-design-principles.alt.md +2 -2
- package/plugin-artifacts/codex/.codex-plugin/plugin.json +0 -41
- package/plugin-artifacts/codex/AGENTS.md +0 -560
- package/plugin-artifacts/codex/BUILD-ARTIFACT.md +0 -5
- package/plugin-artifacts/codex/LICENSE +0 -202
- package/plugin-artifacts/codex/README.md +0 -313
- package/plugin-artifacts/codex/assets/build-loop-plugin-icon.png +0 -0
- package/plugin-artifacts/codex/docs/agent-surface-policy.md +0 -63
- package/plugin-artifacts/codex/references/advisor-dispatch-ladder.md +0 -62
- package/plugin-artifacts/codex/references/agent-role-taxonomy.md +0 -135
- package/plugin-artifacts/codex/references/autonomous-and-per-commit-modes.md +0 -161
- package/plugin-artifacts/codex/references/autonomy-config.md +0 -231
- package/plugin-artifacts/codex/references/backlog-system.md +0 -285
- package/plugin-artifacts/codex/references/capability-routing.md +0 -231
- package/plugin-artifacts/codex/references/codex-subagents.md +0 -106
- package/plugin-artifacts/codex/references/coordination-file-template.md +0 -181
- package/plugin-artifacts/codex/references/coordination-rules.md +0 -552
- package/plugin-artifacts/codex/references/dogfood-reload-checkpoint.md +0 -112
- package/plugin-artifacts/codex/references/halt-and-ask-protocol.md +0 -102
- package/plugin-artifacts/codex/references/implementer-envelope-schema.md +0 -302
- package/plugin-artifacts/codex/references/intent-capability-pack.md +0 -257
- package/plugin-artifacts/codex/references/intent-exploration-prompts.md +0 -96
- package/plugin-artifacts/codex/references/leadership.md +0 -72
- package/plugin-artifacts/codex/references/memory-systems.md +0 -261
- package/plugin-artifacts/codex/references/memory.md +0 -313
- package/plugin-artifacts/codex/references/model-tier-mapping.md +0 -296
- package/plugin-artifacts/codex/references/modular-systems-pack.md +0 -96
- package/plugin-artifacts/codex/references/phase-1-assess.md +0 -249
- package/plugin-artifacts/codex/references/phase-2-plan.md +0 -86
- package/plugin-artifacts/codex/references/phase-3-execute.md +0 -49
- package/plugin-artifacts/codex/references/phase-4-review.md +0 -341
- package/plugin-artifacts/codex/references/phase-5-iterate.md +0 -72
- package/plugin-artifacts/codex/references/phase-6-learn.md +0 -58
- package/plugin-artifacts/codex/references/recent-design-structures.md +0 -274
- package/plugin-artifacts/codex/references/research-trigger-policy.md +0 -140
- package/plugin-artifacts/codex/references/runtime-smoke-triggers.md +0 -42
- package/plugin-artifacts/codex/references/self-review.md +0 -234
- package/plugin-artifacts/codex/references/single-writer-commit-protocol.md +0 -90
- package/plugin-artifacts/codex/references/task-capture-policy.md +0 -68
- package/plugin-artifacts/codex/references/ui-io-contract.md +0 -116
- package/plugin-artifacts/codex/references/ui-spotcheck-protocol.md +0 -65
- package/plugin-artifacts/codex/references/verify-dispatch.md +0 -85
- package/plugin-artifacts/codex/skills/build-loop/SKILL.md +0 -381
- package/plugin-artifacts/codex/skills/build-loop/detect-plugins.mjs +0 -82
- package/plugin-artifacts/codex/skills/build-loop/eval-guide.md +0 -65
- package/plugin-artifacts/codex/skills/build-loop/fallbacks.md +0 -549
- package/plugin-artifacts/codex/skills/build-loop/phases/fact-check.md +0 -42
- package/plugin-artifacts/codex/skills/build-loop/phases/ui-validation.md +0 -267
- package/plugin-artifacts/codex/skills/build-loop/references/advisor-dispatch-ladder.md +0 -62
- package/plugin-artifacts/codex/skills/build-loop/references/apple-native-planning.md +0 -439
- package/plugin-artifacts/codex/skills/build-loop/references/autonomous-and-per-commit-modes.md +0 -161
- package/plugin-artifacts/codex/skills/build-loop/references/capability-routing.md +0 -231
- package/plugin-artifacts/codex/skills/build-loop/references/codex-subagents.md +0 -106
- package/plugin-artifacts/codex/skills/build-loop/references/coordination.md +0 -161
- package/plugin-artifacts/codex/skills/build-loop/references/correction-aware-capture.md +0 -177
- package/plugin-artifacts/codex/skills/build-loop/references/experiment-results-template.md +0 -101
- package/plugin-artifacts/codex/skills/build-loop/references/independent-auditor.md +0 -72
- package/plugin-artifacts/codex/skills/build-loop/references/intent-capability-pack.md +0 -257
- package/plugin-artifacts/codex/skills/build-loop/references/intent-exploration-prompts.md +0 -96
- package/plugin-artifacts/codex/skills/build-loop/references/leadership.md +0 -72
- package/plugin-artifacts/codex/skills/build-loop/references/memory.md +0 -313
- package/plugin-artifacts/codex/skills/build-loop/references/modular-systems-pack.md +0 -96
- package/plugin-artifacts/codex/skills/build-loop/references/output-style.md +0 -222
- package/plugin-artifacts/codex/skills/build-loop/references/pay-it-forward-arch.md +0 -98
- package/plugin-artifacts/codex/skills/build-loop/references/phase-1-assess.md +0 -249
- package/plugin-artifacts/codex/skills/build-loop/references/phase-2-plan.md +0 -86
- package/plugin-artifacts/codex/skills/build-loop/references/phase-3-execute.md +0 -49
- package/plugin-artifacts/codex/skills/build-loop/references/phase-4-review.md +0 -341
- package/plugin-artifacts/codex/skills/build-loop/references/phase-5-iterate.md +0 -72
- package/plugin-artifacts/codex/skills/build-loop/references/phase-6-learn.md +0 -58
- package/plugin-artifacts/codex/skills/build-loop/references/recent-design-structures.md +0 -274
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/ASSESSMENT.md +0 -85
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/STANDALONE_TEST_RUN.md +0 -149
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/01-simple-bugfix.md +0 -32
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/02-ui-build-with-iteration.md +0 -48
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/03-multi-failure-escalation.md +0 -60
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/04-ui-build-ibr-absent.md +0 -51
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/05-refactor-navgator-absent.md +0 -71
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/scenarios/06-recurring-bug-debugger-absent.md +0 -52
- package/plugin-artifacts/codex/skills/build-loop/references/refactor-history/trace-comparison.md +0 -202
- package/plugin-artifacts/codex/skills/build-loop/references/self-recursive-dev.md +0 -77
- package/plugin-artifacts/codex/skills/build-loop/references/self-review.md +0 -234
- package/plugin-artifacts/codex/skills/build-loop/references/ui-io-contract.md +0 -116
- package/plugin-artifacts/codex/skills/build-loop/references/verify-dispatch.md +0 -85
- package/plugin-artifacts/codex/skills/build-loop/scanners/audit-design-rules.mjs +0 -476
- package/plugin-artifacts/codex/skills/build-loop/scanners/require-visual-evidence.mjs +0 -239
- package/plugin-artifacts/codex/skills/build-loop/templates/backlog-item.md +0 -35
- package/plugin-artifacts/codex/skills/build-loop/templates/codex-worker-prompt.md +0 -100
- package/plugin-artifacts/codex/skills/build-loop/templates/ui-subagent-prompt.md +0 -179
- package/plugin-artifacts/codex/skills/build-loop/templates/ux-fix-plan.md +0 -40
- 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
|
|
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
|
|
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
|
|
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(
|
|
224
|
-
and bool(re.search(r"\bU-\d+\b",
|
|
225
|
-
and bool(re.search(r"\bF-\d+\b",
|
|
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(
|
|
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(
|
|
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+",
|
|
256
|
-
oq_body =
|
|
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
|
|
274
|
-
adr_headings_exist = bool(_ADR_HEADING_RE.search(
|
|
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
|
|
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.
|
|
26
|
-
8.
|
|
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
|
-
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
}
|