@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
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
3. **Set sub-routers**: `uiTarget` (web / mobile / **macos** / null), `platform` (web / apple / react-native / null), `migrationSource` (replit / lovable / bolt / v0 / null). See the Capability Routing §Sub-routers rules. **macOS desktop is a first-class `uiTarget`** — distinct from `mobile` — because macOS has no simulator and routes visual-verify to `native-ax-driver` (or IBR `scan_macos` when present), never to `xcrun simctl`. Folding macOS into `mobile` was the routing bug from session-findings 2026-06-04.
|
|
55
55
|
4. **Detect available tools**: test runners (`package.json` scripts, `pytest.ini`, etc.), linters, deploy targets.
|
|
56
56
|
- **Deployment policy**: read `.build-loop/config.json.deploymentPolicy` if present. Defaults are `preview: auto`, `testflight: auto`, `production: confirm`, `unknown: confirm`. Use `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/deployment_policy.py --workdir "$PWD" --command "<candidate push/deploy command>"` before any push/deploy. Treat helper errors as `confirm`.
|
|
57
|
+
4a. **Automatic execution profile**: load `references/resource-aware-execution.md`, run `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/review_trigger.py --context .build-loop/state.json --json`, and persist the envelope at `state.json.execution.resourceProfile`. `skip` exits the full loop after deterministic validation; `standard` uses one independent audit plus signal-triggered heavy checks; `high` keeps the full review path. Recompute after Plan has concrete changed-file and line estimates. Profiles are internal routing data, never user-facing options.
|
|
57
58
|
5. **Map architecture** using best available approach:
|
|
58
59
|
- If `.navgator/architecture/index.json` exists → invoke `Skill("build-loop:architecture-scan")` to refresh data, then `Skill("build-loop:architecture-impact")` on up to 5 highest-risk components for blast-radius. Output goes to `.build-loop/state.json.architecture.{scan,impact}`. Phase 2 Plan consults this for scoping. Flags high-fan-in hotspots, 2-hop dependents, layer-crossing risks, and prompts-in-scope when `triggers.promptAuthoring` is true.
|
|
59
60
|
- Else if `gator:*` is available → use those commands.
|
|
@@ -67,7 +68,7 @@
|
|
|
67
68
|
|
|
68
69
|
6a. **Runtime-server detection** (informational, no changes): run `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/detect_runtime_server.py --workdir "$PWD" --json` and write the result to `.build-loop/state.json.triggers.runtimeServer` (boolean) plus `.build-loop/state.json.runtimeServerInfo` (full envelope: `server_module`, `sse_route`, `default_port`, `embedded_ui_module`, `event_handler_locations[]`, `evidence[]`). Phase 4 sub-step B Validate consults these for the live HTTP/SSE smoke gate. Helper failure → treat as `runtimeServer: false` and log a one-line warning; never blocks. Silent default for CLIs, libraries, plugins, and static-render web apps. Implements decision `_unscoped/0003` (live smoke required when build-loop touches a runtime server) — closes the pytest-with-mocks blind spot that let example-app ship 27 commits with two real bugs.
|
|
69
70
|
7. **Debugger context priming** (always; native to build-loop): invoke `Skill("build-loop:debugging-memory")` with `{ intent: "list-recent", project: "<current>" }` to summarize recent incidents in this project. One-line output; no action. If cross-project Coding Debugger is installed, the skill may use it; otherwise it falls through to `fallbacks.md#bug-memory`.
|
|
70
|
-
8. **Capture UI state** (if web/mobile): host browser/screenshot tooling or simulator/native-AX evidence
|
|
71
|
+
8. **Capture UI state** (if web/mobile): when a renderable UI design is being updated, compared, or audited, invoke headless IBR first when installed per `../../../references/ibr-ui-verification-policy.md`; otherwise use host browser/screenshot tooling or simulator/native-AX evidence → showcase capture → manual screenshot.
|
|
71
72
|
8a. **UI input/output inventory** (if `uiTarget != null`): load `skills/build-loop/references/ui-io-contract.md` and identify every affected user input and system output before component choices are made. Classify each by structural type, content format, persistence intent, operation/domain verb, component mapping, state matrix, modality fallback, validation/security layer, and traceability. Mirror a compact summary to `.build-loop/state.json.uiIOContract` when practical; the full contract is finalized in Phase 2.
|
|
72
73
|
|
|
73
74
|
8b. **Load short-term working context (Pillar 0 — structurally loaded first, inside memory bootstrap)**: `context_bootstrap.build_packet()` calls `load_current(workdir)` at its very entry, before any heavier memory work, and attaches the result as `packet['working_context']` (a serialized `WorkingContextEnvelope`). The working context is therefore available as part of the Phase-1 packet without a separate CLI step.
|
|
@@ -122,6 +123,14 @@
|
|
|
122
123
|
|
|
123
124
|
**Supersedes** the legacy `ps aux | grep -c "[c]laude$"` advisory below — Rally Point presence is the canonical signal. Keep the legacy line as a fallback only when Rally Point is unavailable (older plugin cache without `scripts/rally_point/`).
|
|
124
125
|
|
|
126
|
+
9b. **Data-plane worktree router**: Inspect the goal and repo signals using
|
|
127
|
+
`references/capability-routing.md` § `data-plane-worktrees`. When any signal
|
|
128
|
+
fires, set `state.json.triggers.dataPlaneWorktree: true` and load
|
|
129
|
+
`Skill("build-loop:data-plane-worktrees")` before Phase 2. Inventory every
|
|
130
|
+
mutable non-Git surface in the baseline manifest created by step 9a, then require
|
|
131
|
+
manifest validation before the first write. No signal means the baseline empty
|
|
132
|
+
manifest is an explicit source-only run record.
|
|
133
|
+
|
|
125
134
|
10. **Load PRD if present** (strategic frame check): load `build-loop:prd-bridge`, run its Phase 1 Assess step. If `docs/prd-*.md` exists, the bridge reads frontmatter (`core_principles`, `load_when`, `evolves_when`), Navigation Map, and Section Index, mirrors them to `.build-loop/state.json.prd`, and surfaces staleness signals. If no PRD exists, the bridge writes a one-line recommendation in `state.json.prd.recommendation` pointing to `prd-builder` skill / `/build-loop:start-prd` command — surfaces in Sub-step G Report's `## Held` section, doesn't block. Step 11 below uses PRD as primary source of truth when present; falls back to fresh capture when absent.
|
|
126
135
|
11. **Capture north star + update intent**: When `state.json.prd.core_principles` is non-empty (a PRD was loaded by step 10), use it as the strategic frame; `intent.md` cites the PRD path + revision rather than re-deriving. Otherwise use `references/intent-capability-pack.md` to identify app/repo purpose, primary users, core jobs, update intent, user value, and non-goals fresh. Write `.build-loop/intent.md` and mirror compact fields to `.build-loop/state.json.intent`.
|
|
127
136
|
|
|
@@ -179,12 +188,103 @@
|
|
|
179
188
|
This is the canonical active view over existing state, queue, and
|
|
180
189
|
project-scoped memory backlog surfaces. Do not create a second task ledger by
|
|
181
190
|
default. See `references/task-capture-policy.md`.
|
|
191
|
+
14b. **Groundwork request intake** (blocking when present): when
|
|
192
|
+
`GROUNDWORK_BUILD_REQUEST` is set or `.designdoc/build-request.json` exists,
|
|
193
|
+
validate the request and its adjacent canonical Spec before planning:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
request="${GROUNDWORK_BUILD_REQUEST:-$PWD/.designdoc/build-request.json}"
|
|
197
|
+
spec="${GROUNDWORK_SPEC:-$(dirname "$request")/spec.json}"
|
|
198
|
+
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/groundwork_exchange.py" validate-request \
|
|
199
|
+
--request "$request" --spec "$spec" \
|
|
200
|
+
--output "$PWD/.build-loop/groundwork-request.json"
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Exit 0 binds `specDigest`, the ordered `taskDigest`, and the self-digested
|
|
204
|
+
request; carry its task IDs, acceptance criteria, dependencies, and manual
|
|
205
|
+
boundaries into the plan without rewriting Groundwork's desired state. Exit
|
|
206
|
+
2 is a Phase 1 failure: stop this request path and report the exact contract
|
|
207
|
+
error. Never downgrade an invalid or stale request to an ordinary prompt.
|
|
208
|
+
Keep the request and Spec paths for Review-G, where Build Loop returns
|
|
209
|
+
implementation evidence and Groundwork calculates convergence.
|
|
210
|
+
14c. **Outcome-autonomy preflight** (required before autonomous, background,
|
|
211
|
+
headless, `--long`, or resumed queue-drain work): assemble the facts already
|
|
212
|
+
known from intent, goal, plan, credentials, deployment policy, and tool
|
|
213
|
+
detection. Initialize the runtime envelope once, then assess missing facts:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
python3 "${CLAUDE_PLUGIN_ROOT:-.}/scripts/autonomy_supervisor.py" \
|
|
217
|
+
--workdir "$PWD" initialize --run-id "<run_id>" --goal "<outcome>" \
|
|
218
|
+
[--long | --budget 30m] [--autonomous false]
|
|
219
|
+
python3 "${CLAUDE_PLUGIN_ROOT:-.}/scripts/autonomy_supervisor.py" \
|
|
220
|
+
--workdir "$PWD" preflight --request \
|
|
221
|
+
'{"goal":"<outcome>","success_criteria":["<pass condition>"],"scope_roots":["<repo>"],"validation_commands":["<command>"],"external_dependencies":[]}'
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Persist the envelope at `state.json.execution.autonomyPreflight`. Process it
|
|
225
|
+
before Plan:
|
|
226
|
+
|
|
227
|
+
- `questions[]` contains only facts that change production, reversibility,
|
|
228
|
+
authorized scope, or a major user-facing outcome. Ask them together once;
|
|
229
|
+
include `why` and `impact` from the envelope.
|
|
230
|
+
- `assumptions[]` contains reversible gaps. Record every assumption in the
|
|
231
|
+
plan and execute its named `validation` before the first dependent chunk.
|
|
232
|
+
- `task_profile` summarizes prior runs of the same task shape. Use
|
|
233
|
+
`supervision_recommended` to enable checkpointed queue supervision; never
|
|
234
|
+
treat elapsed time as the outcome or a reason to stop useful work.
|
|
235
|
+
|
|
236
|
+
The initializer enforces `--budget` over `--long`, persists one host-neutral
|
|
237
|
+
budget envelope, and marks the deadline as a soft finalization target. The
|
|
238
|
+
run still optimizes for the accepted outcome and related validated work.
|
|
239
|
+
|
|
240
|
+
After closeout, append actual duration, related discoveries/completions, and
|
|
241
|
+
interventions with `autonomy_supervisor.py record-run`. This makes future
|
|
242
|
+
preflight task-specific. No history means `insufficient_history`, never a
|
|
243
|
+
guessed claim.
|
|
182
244
|
15. **Recovery check**: This used to be a phase-level marker. As of v0.11 the canonical recovery surface is the `--resume` argument and the heartbeat-staleness path documented under §Resume Protocol. The pre-Assess resolver already ran by the time Phase 1 starts; if it returned `decision: "prompt_user"` and the user chose "fresh", proceed normally; if they chose `--resume`, you're not in this code path (the agent is in §0 Resume mode instead).
|
|
183
245
|
16. **Workspace concurrency check** (advisory, no blocking — surface as one-line notes):
|
|
184
246
|
- **Concurrent sessions**: `ps aux | grep -c "[c]laude$"`. If `>1`, warn that other sessions on this repo can silently revert each other's work; the checkpoint reactions (severity + reason) tell you whether overlap is `merged_residue` / `squash_landed` / `active_conflict`. See `agents/build-orchestrator.md` §Multi-session concurrency.
|
|
185
247
|
- **Branch divergence**: `git rev-list --count HEAD..origin/main` and `origin/main..HEAD`. If local main is ahead of origin AND a feature branch will be cut, recommend branching from `origin/main` directly (`git checkout -b <name> origin/main`) so unpushed local commits don't ride into the eventual squash and bundle under a misleading title.
|
|
186
248
|
- **Recovery if symptoms appear during build** (file writes vanish, system reminders flag "intentional" reverts, `git status` clean): pause edits, run `ps aux | grep claude` + `git log --oneline -- <affected paths>` to identify the colliding session/squash, then re-apply dropped work on a fresh branch from `origin/main`.
|
|
187
249
|
|
|
250
|
+
### Pre-authorization interview (unattended runs only)
|
|
251
|
+
|
|
252
|
+
Fires when the run is meant to proceed without a human present: autonomous / `--long` mode, a background or headless dispatch, a `ScheduleWakeup` resume, or an explicit "run this unattended / overnight / while I'm out". Skip it entirely for attended interactive runs — the normal gates already work when someone is watching.
|
|
253
|
+
|
|
254
|
+
Collect the standing policy **once, up front**, instead of discovering each stop mid-run. Four questions, asked together in a single `AskUserQuestion`:
|
|
255
|
+
|
|
256
|
+
1. **Repo scope** — which repos/paths may this run write to?
|
|
257
|
+
2. **Irreversible-action policy** — `skip_and_record` (skip and log the exact command) · `surface_and_wait` · `never_attempt`.
|
|
258
|
+
3. **Conditional gates** — any action pre-authorized *only when a measurement clears a threshold*. This is the one that carries weight: *"deploy only if contrast measures ≥ 4.5:1"* authorizes an outcome, not an action.
|
|
259
|
+
4. **Stop rule** — consecutive failures on the same problem, and wall-clock ceiling.
|
|
260
|
+
|
|
261
|
+
Record it:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
python3 "${CLAUDE_PLUGIN_ROOT:-.}/scripts/preauthorization.py" record \
|
|
265
|
+
--run-id "<run_id>" --unattended --repo-scope "$PWD" \
|
|
266
|
+
--irreversible-policy skip_and_record --stop-rule-failures 5 --stop-rule-hours 8 \
|
|
267
|
+
--gate '{"id":"deploy-contrast","action":"deploy","metric":"contrast_ratio","op":">=","threshold":4.5,"measurement_source":"computed from rendered fg/bg","on_fail":"skip_and_record"}' \
|
|
268
|
+
--workdir "$PWD" --json
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
At the moment a gated action comes up, evaluate it against a **measured** value:
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
python3 "${CLAUDE_PLUGIN_ROOT:-.}/scripts/preauthorization.py" evaluate \
|
|
275
|
+
--gate deploy-contrast --measured 4.2045 --workdir "$PWD" --json # exit 1 — refused
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Rules the script enforces, so they cannot erode:
|
|
279
|
+
|
|
280
|
+
- A gate recorded without a `measurement_source` is rejected at record time. An authorization whose evidence source is unnamed cannot be checked later.
|
|
281
|
+
- A gated action with **no measurement supplied** returns `confirm`, never `auto`. The gate existing is not the authorization.
|
|
282
|
+
- Pre-authorization can only relax a `confirm` into an `auto` for an action it explicitly covers with a satisfied condition. It never relaxes a `block`, never covers an action outside `repo_scope`, and an absent `preauthorization.json` authorizes nothing.
|
|
283
|
+
|
|
284
|
+
This is the proactive counterpart to `scripts/question_timeout.py`, which resolves questions reactively once the run is already moving. Both may be active; the interview answers what it can before the run starts, the timeout handles what it could not anticipate.
|
|
285
|
+
|
|
286
|
+
**Why.** 2026-08-07: four questions asked up front converted a run that would have stopped six times into one that ran unattended across three repos. The conditional gate proved its own worth by refusing — the authorized deploy did not fire, because the value it was authorized against measured 4.2045 against a 4.5 threshold. Blanket approval would have shipped it.
|
|
287
|
+
|
|
188
288
|
### UI scope and mockup pre-flight (when uiTarget != null)
|
|
189
289
|
|
|
190
290
|
**UI pre-flight**: If project has `mockups/` or `.mockup-gallery/` and goal references selected mockups, run the design-rule scanner against the mockup HTML/CSS first to surface conflicts before coding:
|
|
@@ -244,6 +344,6 @@
|
|
|
244
344
|
|
|
245
345
|
Write to `state.json.synthesisDensity` as `{count, escalated, reason}`. Routing target is `tier: thinking`, **never a hardcoded model name** (`scripts/model_overrides.py`: repo config → state snapshot → orchestrator frontmatter fallback → fail-loud). When `escalated == true`, do NOT fan out; execute inline at thinking-tier.
|
|
246
346
|
|
|
247
|
-
**Why this shape:** n=6 A/B experiment (2026-05-07,
|
|
347
|
+
**Why this shape:** n=6 A/B experiment (2026-05-07, "synthesis-decision-delegation" — private research note, substance summarized here) showed β catches ~40% of α's novels — real quality gap — but also showed β saves ~33% wall-clock and ~28% tokens, and the C3-C5 backstops catch some leaks. Defaulting Opus universally would erase β's velocity; the `> 5` threshold matches the empirical inflection point where β's recall collapses (C5 at 5 dims surfaced 0 novels vs α's 5). Below that, fan-out is the right speed choice; above it, depth dominates. Plan/chunk-level overrides let the operator pick quality > speed when needed without changing the default. See `agents/build-orchestrator.md` Phase 1 for full procedure.
|
|
248
348
|
|
|
249
349
|
**Output**: Structured state summary + `.build-loop/intent.md` + `.build-loop/goal.md` with criteria. Brief.
|
|
@@ -16,12 +16,13 @@
|
|
|
16
16
|
- `action: "call"`, `skill: "prd-builder"` → greenfield PRD authoring (only when `run_active == false`); outside an active run this row rarely reaches Phase 2.
|
|
17
17
|
- **Fallback** (record absent — older state, or a Codex lead that skipped step 11): apply the router's own logic inline. Compute `plan_status` exactly as the signal is defined — `no-plan` when `.build-loop/plan.md` is absent/empty OR the last `plan-verify` result failed; `plan-valid` otherwise. If `plan_status == no-plan`, invoke `Skill("build-loop:spec-writing")`; otherwise skip to step 1.
|
|
18
18
|
|
|
19
|
-
When spec-writing is invoked it walks the completeness checklist (auth guard, external API contracts, rate-limit criterion, discoverability surfaces, server/client boundary, concurrency mechanism, observability events, input validation, UI input/output contract when UI is in scope,
|
|
19
|
+
When spec-writing is invoked it walks the completeness checklist (auth guard, external API contracts, rate-limit criterion, discoverability surfaces, server/client boundary, concurrency mechanism, observability events, input validation, UI input/output contract when UI is in scope, routing-risk fields, dispatch/env-var fields, capability gap map, single-shot build guardrails, and read-before-edit map), runs `check_checklist.py` + `plan-critic`, writes the plan to `.build-loop/plans/<feature-slug>.md`. Only continue to step 1 once a plan path exists.
|
|
20
20
|
|
|
21
21
|
1. **Invoke `writing-plans` skill** for detailed task breakdown
|
|
22
22
|
2. **Identify parallel-safe tasks** vs sequential dependencies — build a dependency graph
|
|
23
23
|
- If the graph has 2+ independent / parallel-safe chunks, write `parallel_batch:` naming the chunks that will dispatch together.
|
|
24
24
|
- If the graph appears parallelizable but execution must serialize, write `parallel_skipped_reason:` with the specific dependency, tool limit, or coordination constraint.
|
|
25
|
+
2a. **Recompute resource profile**: rerun `scripts/review_trigger.py` with every planned `--changed-file` and `--lines-changed <expected-delta>`. Persist the result at `state.json.execution.resourceProfile`; promote to `high` when either Assess or Plan returned `high`. Carry its `review_steps` into Review instead of dispatching every optional reviewer by default.
|
|
25
26
|
3. **Map each task to intent**: state which user workflow, user-value rule, and north-star outcome it supports. Remove tasks that add complexity without clear user value.
|
|
26
27
|
3a. **Approach Lenses section**: For non-trivial architecture, workflow, dependency, UI/product, or long-lived interface decisions, add `## Approach Lenses` before the task list. Use the Phase 1 `.build-loop/state.json.approachLenses` summary and include:
|
|
27
28
|
- **Clean-sheet best approach**: the use-case-first answer if no prior implementation debt or historical decisions constrained the design.
|
|
@@ -32,6 +33,9 @@
|
|
|
32
33
|
Skip only for narrow single-file fixes, pure config changes, or decisions where the two answers are identical; in that case write `Approach Lenses: n/a - <reason>`.
|
|
33
34
|
3b. **Depends-on (reads-from) section**: For any plan that ships code, add a `## Depends-on (reads-from)` section listing every data path, contract, or invariant the new/changed code reads. Each entry takes the form `- \`<path-or-contract>\` — verified` or `- \`<path-or-contract>\` — unverified`. Mark `verified` when you can confirm something in the repo writes that path or holds that invariant (grep, schema inspection, or test fixture confirms it); mark `unverified` when no writer exists or you cannot confirm. Any `unverified` entry is a BLOCKING unknown that must be resolved — either add the missing writer to the plan, remove the read, or add `override: reads-from-dependency` with rationale. This section is exempt for doc-only and config-only plans that name no source-code paths. Enforced by `plan-verify` rule `reads-from-dependency`.
|
|
34
35
|
3c. **Activation Map section**: For any plan that proposes a new *event-driven or call-site-dependent* component — a stop/SessionStart/PreToolUse/PostToolUse hook, a cron/launchd job, a watcher, a git hook (pre-commit/post-commit), a webhook, or a gate that fires on a host event — add an `## Activation Map` section. This converts build-loop's recurring failure class (machinery built, activation path never verified — a dormant WARN gated on a dict that int()'d to 0, state_finalize reading the wrong phase key, repo-level codex hooks that never fired, run-identity reuse silently skipping records) into a structural plan requirement. Each entry takes the form `- <component> — trigger: <event-or-call-site> — verified-live: yes|pending`. The `trigger:` must name the *concrete* host event or call site (e.g. `PostToolUse:Bash matcher in hooks/hooks.json`, `SessionStart hook`, `pre-commit hook in .pre-commit-config.yaml`), not an aspiration ("runs at review time"). Mark `verified-live: yes` only when you have confirmed the trigger actually fires (a live run exercised it, or a test asserts the host event reaches the handler); mark `verified-live: pending` otherwise. Any `pending` entry must map to a verification task before Report — the plan does not close while a component's activation is unconfirmed. This section is exempt for plans that propose no new event-driven machinery (doc-only, refactor-only, pure inline-logic changes); a `## Activation Map` is not required there. Add `override: activation-map-exempt` with rationale only when the section genuinely does not apply. Enforced by `plan-verify` rule `activation-map-required` (BLOCKER: missing section on a dormant-risk plan, or any entry that names a `trigger:` without a `verified-live:` key).
|
|
36
|
+
3d. **Capability Gap Map section**: For any non-trivial implementation plan, add `## Capability Gap Map` before the F/Q criteria. Map each changed capability or workflow to: current source of truth, target behavior, gap, build action, owned files/contracts, and validation. This is the default home for "current vs target" gap closure; avoid a separate gap-closure plan unless the user asks for one or the map is too large for the main plan.
|
|
37
|
+
3e. **Single-Shot Build Guardrails section**: For any non-trivial implementation plan, add `## Single-Shot Build Guardrails`. Each row names a guardrail, the failure mode it prevents, and the evidence/test that proves compliance. Guardrails must be enforceable: cite a target test, ADR, source file, acceptance criterion, or command. Generic cautions without evidence do not count.
|
|
38
|
+
3f. **Read-Before-Edit Map section**: For any non-trivial implementation plan, add `## Read-Before-Edit Map`. Each work item must name the files, tests, contracts, docs, or search commands the implementer reads first; why those reads matter; and which files are edited after. This keeps execution grounded in current repo state and reduces build-from-memory drift.
|
|
35
39
|
|
|
36
40
|
4. **Partition tasks and files MECE**: Use one grouping dimension per level (domain, layer, workflow, bounded context, adapter, or test surface). Every changed file gets exactly one owner; every required behavior, state, migration, test, and user-facing surface gets an owner.
|
|
37
41
|
5. **Define subagent integration points**: Where do agents need to coordinate? Where must outputs be tested together? Record interface contracts and checkpoints for every boundary.
|
|
@@ -50,6 +54,7 @@
|
|
|
50
54
|
|
|
51
55
|
**Optimization checklist** (review the plan for these before proceeding):
|
|
52
56
|
- Can more tasks run in parallel? Unnecessary sequential bottlenecks?
|
|
57
|
+
- Does planned fan-out fit `references/resource-aware-execution.md` — token-led for cloud, CPU-led for local, measured usage before T-shirt fallback?
|
|
53
58
|
- Can subagent context be smaller? Shared reads that should be done once?
|
|
54
59
|
- Missing dependencies, interface mismatches, env assumptions?
|
|
55
60
|
- Changes that could conflict with each other (oscillation risk)?
|
|
@@ -58,6 +63,9 @@
|
|
|
58
63
|
- Define coordination checkpoints where subagents must sync
|
|
59
64
|
- UI/API/data choices that add options, mocks, or complexity without user value?
|
|
60
65
|
- UI plans missing input/output coverage, state coverage, modality fallbacks, validation/security layers, or schema/API traceability?
|
|
66
|
+
- Missing capability gap rows: any target behavior without a current source of truth, named gap, owner, and validation?
|
|
67
|
+
- Missing single-shot guardrails: known failure modes without enforceable evidence/tests?
|
|
68
|
+
- Missing read-before-edit entries: any implementation chunk whose required current-state reads are implicit?
|
|
61
69
|
- MECE gaps or overlaps: unowned responsibilities, shared file ownership, or mixed grouping dimensions?
|
|
62
70
|
- Boundaries that are too tight, too broad, or missing a stable interface?
|
|
63
71
|
- If the plan chooses a simpler/integrated path over modularity, is there a documented `MODULARITY EXCEPTION`?
|
|
@@ -8,15 +8,18 @@
|
|
|
8
8
|
|
|
9
9
|
**Goal**: Implement the plan using parallel subagents where possible.
|
|
10
10
|
|
|
11
|
+
0. **External-source gate** — when a chunk's plan entry names an external repository, vendored tree, or unfamiliar library as the source of its APPROACH (`adapts` / `ports` / `vendors` / `mirrors`), load `Skill("build-loop:repository-intelligence")` and scan the pinned source BEFORE dispatch. Pin repo, branch or tag, and `git rev-parse HEAD` into the implementer brief alongside the portable concepts and each concept's evidence state (`source-confirmed` / `issue-reported` / `inferred`). An `inferred` concept may not carry a load-bearing design decision. Set `triggers.externalSourceAdaptation` so Review-D grades the diff against the same SHA. Ordinary dependency use does NOT fire this: calling a package's documented API is `api-registry` / Context7 territory, and the distinction is whether you read someone else's source to decide your own structure. The skill is read-only and never executes the source, so the gate costs a scan rather than a build.
|
|
11
12
|
1. **Use `subagent-driven-development`** — dispatch subagents per task
|
|
12
|
-
2. **Model assignment**:
|
|
13
|
-
3. **
|
|
13
|
+
2. **Model assignment**: Resolve each agent through `scripts/resolve_agent_model.py <agent> --workdir "$PWD" --json`. Use its supported `preferred_effort` unless an explicit dispatch effort overrides it. Start Sonnet/Terra execution at `high`; use `xhigh` only after a verifier establishes a quality miss, and `max` only after a controlled comparison shows material gain. Haiku has no effort control: keep it bounded and escalate the model when necessary. Consult `Skill("build-loop:model-tiering")` for task-specific defaults and escalation triggers.
|
|
14
|
+
3. **Resource-aware parallel agents** where the dependency graph allows. Load `references/resource-aware-execution.md`, resolve the concrete model, then call `autonomy_supervisor.py fanout` with independent-item count, shared-session capacity, provider/location, output-size, effort, and live signals. Persist the capacity and admission envelopes at `state.json.execution.fanout`; dispatch no more than `admission.next_concurrency`. Cloud inference is token-led; local inference is CPU-led. Both retain MECE, shared-capacity, live backpressure, and the absolute ceiling of 150. Batch with `plan_batches()` when chunk count exceeds the result.
|
|
14
15
|
|
|
15
16
|
**Maximize parallel-safe chunks**: the partition should expose the maximum number of independent chunks (one file-owner each) so fan-out scales to the available `effective_max`. Serializing parallelizable work requires a `parallel_skipped_reason:` entry in the plan record.
|
|
16
17
|
|
|
17
18
|
**MECE pre-dispatch gate (NEW)**: before fanning out, validate the partition is *mutually exclusive* — `python3 scripts/parallelism.py --check-partition <{agent:[owned_paths]} JSON>` (exit 1 + overlap report if any file is claimed by >1 agent). A non-empty overlap means two writers would race the shared worktree — fix the partition (or give the overlapping agent `isolation:"worktree"`) before dispatch. Complements `brief_mece_validator.py` (which checks a single brief *has* the seven ownership fields) by checking they are disjoint *across* the fan-out — closing the file-race / fan-out scope-blindness class.
|
|
18
19
|
4. **Each agent gets**: minimal context + clear integration contract + relevant doc context for external APIs + the intent packet from `.build-loop/intent.md` + the MECE ownership packet from the plan (`owns`, `does not own`, `interface contract`, `integration checkpoint`, `allowed tools`, `denied tools`, `acceptance criteria`)
|
|
19
20
|
|
|
21
|
+
**Bounded context**: capture the assembled brief once, then pass file pointers instead of copying shared document bodies. Use the resolved model's `prompting_profile`. Fan-out is inappropriate for sequential or cross-cutting work when repeated brief cost exceeds the concurrency benefit.
|
|
22
|
+
|
|
20
23
|
**`acceptance criteria` (7th field)**: the testable conditions the returning envelope must satisfy — a per-chunk oracle the verifier reads instead of re-deriving one from the diff. Linted by `scripts/brief_mece_validator.py`; a write-handoff brief missing it now lints invalid. *Recovery-path was deliberately rejected as an 8th field — recovery stays centralized in the orchestrator's status-routing + stuck-cascade, not duplicated per handoff.*
|
|
21
24
|
4a. **Implementers do NOT commit** (NEW 2026-05-07 — single-writer git contract). Implementers modify the working tree and return `files_changed` + `commit_subject` + `commit_body` in their envelope. The orchestrator commits sequentially after each parallel batch returns: `git add -- <files>` + `git commit -m <subject> -m <body>`, one implementer at a time through the pre-commit hook. This prevents the parallel-commit race that lost 3 of 4 commits in example-app round 3 (2026-05-07). See `agents/build-orchestrator.md` §"Phase 3 commit step" for the full procedure.
|
|
22
25
|
4b. **Halt-and-ask backstop for architectural-class decisions** (NEW — C5). When an implementer encounters a synthesis-class decision NOT in the plan's `synthesis_dimensions` AND it's architectural-class (where a phase lives, defensive contract shape, error-propagation policy, persistence boundary, hard-fail counters), the implementer returns `status: "blocked"` with the decision in `novel_decisions[]` and does NOT commit. The orchestrator dispatches each blocked decision to the configured Thinking-tier resolver (per `references/model-tier-mapping.md` — never a hardcoded model name), persists resolutions to `state.json.novelDecisionResolutions[]`, and re-dispatches the implementer with resolutions appended to its brief. Hard-fail counter N=3 per chunk; exhausted chunks surface as ❓ Unfixed in Review-F. C3's attestation lint and C4's synthesis-critic still cover what they can grade — C5 catches what falls outside both. Full procedure: `agents/build-orchestrator.md` §"Phase 3 halt-and-ask branch".
|
|
@@ -15,15 +15,32 @@ Review runs every time we need an evaluation (initial post-Execute, and again af
|
|
|
15
15
|
Catch scope drift, patch-over-root-cause, missed edge cases, and rubric violations before spending tokens on full validation. Uses a separate read-only agent with no incentive to sandbag.
|
|
16
16
|
|
|
17
17
|
0. **Quality-gate trigger profile (QM v0.13.0, single source of truth — F4)**: run `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/review_trigger.py --context .build-loop/state.json $(git diff --name-only origin/main..HEAD | sed 's/^/--changed-file /') --json`. The returned `{independent_review_required, cross_vendor_required, reasons}` is the **single source** for when adversarial/cross-vendor review fires — don't invent separate heuristics. Triggers cover `riskSurfaceChange`, architecture-boundary crossing, new dependency/runtime, auth/file/network/persistence/security/model-tool changes, and low-confidence critic output.
|
|
18
|
-
1. **Dispatch `independent-auditor`** at `scope: "build"` against the full build diff (`<pre_build_sha>..HEAD`). Consolidated 2026-05-23 — single source of truth replacing both retired `commit-auditor` (chunk + build scope) and earlier retired `sonnet-critic`. The auditor has tools=[Read, Grep, Glob, Bash] (Bash for `git diff`), no Edit/Write.
|
|
18
|
+
1. **Dispatch `independent-auditor`** at `scope: "build"` against the full build diff (`<pre_build_sha>..HEAD`). Consolidated 2026-05-23 — single source of truth replacing both retired `commit-auditor` (chunk + build scope) and earlier retired `sonnet-critic`. The auditor has tools=[Read, Grep, Glob, Bash] (Bash for `git diff`), no Edit/Write.
|
|
19
|
+
|
|
20
|
+
**Dispatch the auditor CONTAINED (Lever 5, 2026-08-07).** Pass `isolation: "worktree"` to the Agent tool, and brief the auditor that every git call routes through `python3 scripts/audit_git.py <args>` — a refuse-by-default read-only front door — with bare `git` prohibited. `tools: [...]` without `Edit`/`Write` declares read-only; it does not enforce it, because `Bash` carries the whole write surface. Observed in TruePace: this agent ran `git checkout -- website/public/styles.css` mid-audit and destroyed an implementer's uncommitted work, then reported the destruction as its own finding. Nothing was lost only because the work was re-applied by hand — the second collision in one session that isolation would have prevented. Worktree isolation contains the blast radius; the front door blocks the command class. Ship both; neither substitutes for the other. For Phase 3 step 7 (per-chunk advisory), dispatch the same `independent-auditor` with `diff_sha_range: <chunk_parent_sha>..<chunk_sha>` and `reason: "chunk-advisory"`. **Cross-vendor (QM v0.13.0)**: when the profile sets `cross_vendor_required` and a peer host is reachable (rally channel / `codex exec`), fan out a second-vendor reviewer in parallel and reconcile by severity+evidence; if no peer host can execute, record `cross_vendor: untested` — never claim it ran (per host-agent-is-the-LLM, this is the host's peer, not a vendored API call).
|
|
19
21
|
|
|
20
22
|
**Auditor dispatch ladder & parent-dispatch contract (GAP-1 — the LLM auditor is never silently skipped).** Dispatching `independent-auditor` via `Agent(subagent_type=...)` requires the Agent tool. A *nested* orchestrator — one dispatched as a subagent (`Agent(subagent_type="build-loop:build-orchestrator")`, Mode B) or running per-commit mode — does **not** have the Agent tool, because the harness blocks sub-subagents. The historical failure (2026-06-06 IBR retro, 4+ runs): the nested orchestrator silently substituted inline self-reasoning and reported it as "independent-auditor ran inline", rubber-stamping a HIGH cookie-leak + 2 MEDIUM findings a real dispatch later caught. To make that impossible, walk this ladder and record `auditor_status` honestly:
|
|
21
23
|
|
|
22
24
|
1. **Agent tool present** (top-level / Mode A) → dispatch `independent-auditor` at build scope as above → `auditor_status: ran:dispatched-agent`.
|
|
23
25
|
2. **No Agent tool, peer host reachable** → run the auditor as a **peer process** over the same channel the cross-vendor reviewer uses (rally channel handoff / `codex exec <prompt>` — reachable because the orchestrator retains Bash even when nested). Reconcile the peer's JSON envelope into `.build-loop/judge-decisions.json` with `judge_id: "independent-auditor"` (a real, cross-host verdict that satisfies the `write_run_entry --scope build` gate honestly) → `auditor_status: ran:peer-host(<host>)`. Prefer this over the not-run signal whenever a peer host can execute.
|
|
24
|
-
3. **Neither reachable** → `auditor_status: not-run:parent-must-dispatch` (or `cross-vendor-deferred` when a peer host exists but cannot execute this pass). Then, **all of**: (a) do NOT write any `judge_id` containing `independent-auditor` for inline self-reasoning — *inline self-audit is not the independent auditor*, and a mislabeled record would defeat the gate; (b) do NOT report a `scope=build` code-touching run as a review-complete `pass` — use `outcome: partial`; (c) surface `auditor_status: not-run:parent-must-dispatch` in the orchestrator's return envelope.
|
|
26
|
+
3. **Neither reachable** → `auditor_status: not-run:parent-must-dispatch` (or `cross-vendor-deferred` when a peer host exists but cannot execute this pass). Then, **all of**: (a) do NOT write any `judge_id` containing `independent-auditor` for inline self-reasoning — *inline self-audit is not the independent auditor*, and a mislabeled record would defeat the gate; (b) do NOT report a `scope=build` code-touching run as a review-complete `pass` — use `outcome: partial`; (c) surface `auditor_status: not-run:parent-must-dispatch` in the orchestrator's return envelope; **(d) WRITE THE OWED-VERIFICATION MANIFEST** — `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/owed_verification.py write --workdir "$PWD" --run-id "<run_id>" --diff-range "<pre_build_sha>..HEAD" --owe independent-auditor [--owe plan-critic] [--owe security-reviewer] --json`. This writes `.build-loop/owed-verification.json` (owed list + the exact `Agent(...)` dispatch command per verifier) and flips `state.json.review_incomplete = true`. Step (d) is what makes the parent-dispatch contract a MECHANISM instead of a note the parent might forget: the manifest survives in `.build-loop/` and `owed_verification.py check` is a gate the parent's Report step reads.
|
|
27
|
+
|
|
28
|
+
**Parent-dispatch contract (machine-checkable).** A run or commit whose envelope carries `auditor_status: not-run:parent-must-dispatch` (or `cross-vendor-deferred`) — equivalently, one for which `owed_verification.py check` reports `status: incomplete` — is **NOT review-complete**. The dispatching parent — the top-level session that *does* have the Agent tool (the `/build-loop:run` skill body, or the human-driving session) — MUST, on receiving such an envelope: (1) `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/owed_verification.py check --workdir "$PWD" --json` to read the owed list + per-verifier dispatch commands; (2) for each owed verifier, dispatch it (`Agent(subagent_type="build-loop:independent-auditor")` on the run's diff range `<pre_build_sha>..HEAD`, plus `plan-critic` / `security-reviewer` when owed) and append its verdict to `.build-loop/judge-decisions.json`; (3) `owed_verification.py clear --verifier <name>` (or `--all`) for each — the last clear removes the manifest and flips `review_incomplete` back to `false`; (4) re-run `write_run_entry --scope build` so the review-completeness gate passes, and only then finalize Report. Two structural backstops now bind: the manifest (`owed_verification.py check` exit 1 on any owed verifier) AND the existing `write_run_entry --scope build` `review_completeness_error` → exit 3 on a `pass`+`scope=build`+files-touched run lacking a real auditor verdict. Neither can be satisfied by an honest nested orchestrator, which is what forces the parent to finish the audit instead of shipping un-audited code. Helper + tests: `scripts/owed_verification.py` / `scripts/test_owed_verification.py`.
|
|
29
|
+
**Hostile-input closure gate — when a commit closes a security/safety finding (Lever 3, 2026-08-07).** A guard's test must contain the finding's literal hostile input, and a planted mutant disabling the guard must turn it red. Both are executable, both must pass before the finding is `closed`:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
python3 ${CLAUDE_PLUGIN_ROOT}/scripts/hostile_input_gate.py check \
|
|
33
|
+
--hostile-input "<the finding's literal hostile_input>" --test-file <test path> --json
|
|
34
|
+
python3 ${CLAUDE_PLUGIN_ROOT}/scripts/hostile_input_gate.py mutate \
|
|
35
|
+
--guard-file <path> --guard-symbol <fn> --test-cmd "<test command>" --json
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Exit 1 on `check` = `hostile_input_absent` (the test does not contain the attack) or `hostile_input_weak_match_only` (it contains only a path-segment match). Exit 1 on `mutate` = `mutant_survived`: the tests stay green with the guard disabled, so they never exercised it. Exit 2 on `mutate` = `baseline_red`, `mutant_run_timeout`, or `isolation_setup_failed` — a run that could not be observed is not a pass. Any of these means the finding is not closed regardless of how green the suite is; record the real state rather than the verdict.
|
|
39
|
+
|
|
40
|
+
`matched_via` names the tier that matched (`literal` / `normalized` / `distinctive_token`) and only the first two close a finding — the weak tier is gated because the original incident's own three-branch test would have scored as covered on a `Application Support` segment match. `--accept-weak-match` is the explicit, off-by-default override. `mutate` plants the mutant in a `git checkout-index` materialization of the index, never in the live checkout (`isolated: true`), so a killed run cannot strand a disabled guard on disk where a concurrent `git add` would stage it.
|
|
41
|
+
|
|
42
|
+
`security-reviewer` findings now carry a mandatory `hostile_input` field — the literal argv/path/payload, not a description of the class — which is exactly the string this gate consumes. Observed: a guard written to refuse writing to a user's live store shipped with a test asserting three adjacent things (in-repo target refused, default-with-flag-absent refused, outside path returns absolute), all of which already passed. It never called the function with the live store as an explicit argument — the attack the finding named. The guard required its flag only on the branch where the path was omitted, so naming the path walked past it, and the shipped code wrote 49 entries into the real store. A test written by reading the implementation enumerates the branches that exist; a test written from the threat asks what the attacker types.
|
|
25
43
|
|
|
26
|
-
**Parent-dispatch contract.** A run or commit whose envelope carries `auditor_status: not-run:parent-must-dispatch` (or `cross-vendor-deferred`) is **NOT review-complete**. The dispatching parent — the top-level session that *does* have the Agent tool (the `/build-loop:run` skill body, or the human-driving session) — MUST, on receiving such an envelope: (1) dispatch `Agent(subagent_type="build-loop:independent-auditor")` on the run's diff range (`<pre_build_sha>..HEAD`); (2) append its verdict to `.build-loop/judge-decisions.json`; (3) re-run `write_run_entry --scope build` so the review-completeness gate passes, and only then finalize Report. The existing gate (`scripts/write_run_entry`, `review_completeness_error` → exit 3 on a `pass` + `scope=build` + files-touched run lacking a real auditor verdict) is the structural backstop: it cannot be satisfied by an honest nested orchestrator, which is what forces the parent to finish the audit instead of shipping un-audited code.
|
|
27
44
|
2. **Input**: the rubric from `.build-loop/goal.md` + the implementer's diff (`git diff HEAD~1` or the changed-file set).
|
|
28
45
|
3. **Output**: JSON envelope with `verdict` ∈ {yay, nay, suggest_correction, look_again} + normalized `findings[]` (`severity: critical|high|medium|low`). See `agents/independent-auditor.md` for the full schema.
|
|
29
46
|
4. **Routing** (QM v0.13.0 normalized severities; legacy `major→high`, `minor→medium`, `info→low`):
|
|
@@ -58,6 +75,8 @@ Catch scope drift, patch-over-root-cause, missed edge cases, and rubric violatio
|
|
|
58
75
|
|
|
59
76
|
Test every criterion from Assess with evidence.
|
|
60
77
|
|
|
78
|
+
**Keep validation bounded.** Default graders, smokes, and functional checks to quick runs (seconds–minutes) — most are fast. Escalate to a long-running test only when a radical or unexpected result genuinely needs more time to characterize, and note that in the Review-G report rather than silently running long. A bounded live check that catches what a mocked/green suite hides (e.g. a real-osascript smoke over a mocked unit test) outranks a long run that adds no signal.
|
|
79
|
+
|
|
61
80
|
**UI validation — build-loop-owned route** (`uiTarget != null`): dispatch `ui-validator` first, then run the static design-rule scanner and UI input/output contract check. Build-loop does not auto-route to IBR for validation. If the user explicitly requested IBR, treat that as a manual auxiliary validator and keep its findings out of the default gate order.
|
|
62
81
|
|
|
63
82
|
**UI validation fallback**: paste `fallbacks.md#web-ui` into the validation subagent prompt when `ui-validator` cannot render the route. The fallback contains 10 specific grep checks (Gestalt violations, touch targets, missing handlers, missing aria-labels, status-pill anti-patterns, off-token colors, non-8pt spacing, console leftovers, mock data) plus a file-check matrix for landmarks, focus styles, and viewport tags. Findings get `⚠️ static-analysis only — browser/simulator evidence unavailable` in the Review-G report. This is the standalone UI validation path — degraded vs rendered validation, but not silent.
|
|
@@ -78,6 +97,19 @@ design-rule scan → must-fix=0 pass/fail (uiTarget != null only)
|
|
|
78
97
|
ui io contract → pass/fail (uiTarget != null only)
|
|
79
98
|
```
|
|
80
99
|
|
|
100
|
+
**Perturbation spot-check (advisory, WARN-only — outcome-based graders on a risk-surface change)**: an outcome-only grader (a test/assertion whose whole signal is pass/fail) can be Goodharted — a gamed or overfit implementation passes the check without satisfying the rule, and a plain pass/fail oracle cannot see it (arXiv:2606.09863 false-success; RLVR obfuscated-enumeration arXiv:2604.15149). When a grader above is **outcome-based** (test/assertion pass/fail, not a structural/lint check) AND `triggers.riskSurfaceChange` is set, re-run that grader once under an isomorphic perturbation and record whether the pass/fail flips:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/perturbation_spotcheck.py" \
|
|
104
|
+
--check-cmd "<the grader command, with {input} where the changed source path goes>" \
|
|
105
|
+
--input "<changed source file under this outcome gate>" \
|
|
106
|
+
--mode rename # rename identifiers; use --mode reorder for order-independent inputs
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The check exits 0 by contract (WARN-only — **it never blocks the build or routes to Iterate**; omit `--strict`). A legitimate outcome check is invariant under an isomorphic perturbation, so a **flip** (`WARN: pass flipped under …`) is an advisory signal the oracle may be gamed/overfit — record it in the Review-G `## Notes from judges` as `perturbation_spotcheck: WARN (<perturbation> flipped) — inspect the oracle` and let the operator judge; a clean run records `perturbation_spotcheck: clean`. Skip entirely when no outcome-based grader ran, or when `triggers.riskSurfaceChange` is unset.
|
|
110
|
+
|
|
111
|
+
**Safety-boundary guard test — mutation-verify (any change touching a never-X / safety-boundary guard)**: when the diff adds or changes a guard that enforces a safety invariant — a "never modify X" / "never delete Y" / "reject a path outside Z" boundary (e.g. an `isSidecarPath` write-fence, a path allowlist, a destructive-op gate) — the guard's test MUST import and exercise the SHIPPED guard, never a copy of its logic pasted into the test. A test that asserts against its own duplicate of the guard passes even when the shipped guard is broken to `return true` (observed: an Obsidian plugin's sole never-modify-`writing/` guard had a test that re-implemented the guard, so it stayed 20/0 green when the real guard was mutated to always-allow — a test that cannot fail blocks nothing). Then mutation-verify it: flip the shipped guard to the unsafe verdict, re-run only that test, confirm it now FAILS, restore. A guard test that stays green against a broken guard is a fake test — treat it as a Validate failure (route to Iterate: import the real guard, then re-mutation-verify). **How** (one line): flip the guard's return in place → re-run its test → expect red → `git checkout -- <guard-file>`. Memory: `feedback_verify_test_validity_by_mutation`. No new script/agent — the rule + memory are the mechanism; a deterministic mutation-runner is a possible follow-up, not built here.
|
|
112
|
+
|
|
81
113
|
**Design-rule scan** (when `uiTarget != null`):
|
|
82
114
|
```
|
|
83
115
|
node "${CLAUDE_PLUGIN_ROOT}/skills/build-loop/scanners/audit-design-rules.mjs" --root=<project> --platform=<swiftui|react|web> --json
|
|
@@ -148,7 +180,7 @@ Per-criterion `gate_verdict`:
|
|
|
148
180
|
- `WEAK_SIGNAL` → note reference in the Iterate plan, investigate normally
|
|
149
181
|
- `NO_MATCH` → standard Iterate fallthrough; store at sub-step G Report for future learning
|
|
150
182
|
|
|
151
|
-
The memory gate is always on. Build
|
|
183
|
+
The memory gate is always on. Build Loop bundles the debugger core and reads and writes the same project-local `.claude/memory/` store through `bin/build-loop-debugger.js`; no standalone package or MCP server is required. The strict direct-apply triple-gate spec lives in `skills/debugging-memory/references/search.md`.
|
|
152
184
|
|
|
153
185
|
**Output**: per-criterion pass/fail with evidence. Any `fail` → Iterate. All `pass` → sub-step C.
|
|
154
186
|
|
|
@@ -171,12 +203,14 @@ Metric-driven autonomous optimization using Karpathy's autoresearch pattern. Opt
|
|
|
171
203
|
Nothing false, fabricated, or placeholder reaches the user. Three gates, run in parallel. Load `phases/fact-check.md` for detailed guidance.
|
|
172
204
|
|
|
173
205
|
- **Gate 1 — Fact Checker**: Trace every rendered %, $, score, count, or assessment to its data source. Flag "always", "never", "100%", "guaranteed" — replace with accurate language unless genuinely absolute. Every rendered metric needs a traceable path: source → transformation → display.
|
|
206
|
+
- **Gate 1b — External-source adaptation** (fires on `triggers.externalSourceAdaptation`): load `Skill("build-loop:repository-intelligence")` and grade the diff against the SHA Phase 3 pinned. Two questions the other gates do not ask. **Concept or implementation?** The skill's contract is reuse of concepts and interfaces, not copied implementation; a diff reproducing an external file's structure line-for-line is a finding even when it compiles and passes tests. **License fit?** Check the source's license against this repo's — a permissive license removes an objection, it is not evidence the implementation fits. Also confirm no `inferred` concept from the Phase 3 scan became load-bearing without promotion to `source-confirmed`. WARN by default; BLOCK on an incompatible license, or on copied implementation whose license requires attribution this repo does not carry.
|
|
174
207
|
- **Gate 2 — Mock/Privacy Data Scanner**: Run via `mock-scanner`. Lightweight scan of production code paths and public release/package surfaces for residual mock/placeholder data and private data leaks — hardcoded fake data, placeholder text, faker/random in display paths, stubs replacing real implementations, live-looking API keys/secrets, absolute local paths, private vault/wiki/session paths, persona/profile exports, customer/user lists, resumes, calendars, private notes, transcripts, hostnames, Rally runtime logs, worktree bundles, and other personal or machine-specific data. Exclude test files, dev-only code, and clearly synthetic documentation examples.
|
|
175
|
-
- **Gate
|
|
208
|
+
- **Gate 2b — Memory/Resource Leak Scanner** (only when the diff touches long-lived runtime code — a daemon, service, server, registry, app-lifetime controller, or stream/parser path): run via `leak-scanner`. Lifecycle accounting: every acquire site (insert/register/spawn/open/subscribe/buffer) must have a release path that fires on the real input, including the uncooperative case. Core checks: unbounded collections fed by external input (memory AND the disk/inode/fd sprawl the same client-controlled key drives), terminal-only eviction predicates (the *terminal* set ≠ the *evictable* set — sweeps must age stale non-active entries), idempotency maps with no forget-point, registration without deregistration, retain/Arc cycles, spawn-without-reap (per-session helpers need session-end cleanup, a single-instance guard, or orphan self-exit), unclosed handles/sessions, and uncapped stream buffer accumulation (enumerate ALL entry forms and accumulating states — a cap on one introducer/sub-code is a false cap). **Scan the whole long-lived surface, not only changed lines** — the highest-value leaks are often pre-existing siblings of the changed code (a second unbounded map in the same registry), so the scanner sets `preexisting` per finding. Routing mirrors Gate 5: **new-content** blocking findings (introduced by this diff) require an `adversary_move` and route to **Iterate**; **pre-existing** blocking findings log to `.build-loop/issues/` with a break-what-if note (user decides scope — do not block the current build on a leak the diff did not introduce). For any eviction fix, honor the finding's `recovery_safe` flag: an eviction that is not recovery-safe (drops correctness state — sequence counters, cursors, dedup keys — with no rehydration path) must pair eviction with rehydration or bound a different way. Warnings go to Report.
|
|
209
|
+
- **Gate 3 — Architectural Violation Check**: invoke `Skill("build-loop:architecture-rules")` (no plugin gate — the native skill no-ops cleanly when `.navgator/architecture/index.json` is absent). Executes `navgator rules --json` and classifies blocking (`circular-dependency`, `layer-violation`, `database-isolation`, `frontend-direct-db` at error) vs warning (`hotspot`, `high-fan-out`, `orphan`, `shallow_module`). Flags recurrences against `.navgator/lessons/lessons.json`. For cross-layer changes, escalate to `Skill("build-loop:architecture-review")` for the full integrity review. **`shallow_module` findings** (from the `architecture-scout` `review-rules` envelope or the native `rules` engine — a thin pass-through with high fan-out and low fan-in) are surfaced in the Report `## Notes from judges` as advisory design guidance ("consider deepening `<component>` behind a narrower interface"); they are WARN-only and never route to Iterate.
|
|
176
210
|
- **Gate 4 — Plugin Cache Sync Check** (only when `pluginWork: true`): run `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/check_cache_sync.py --host claude --source <plugin-source-repo>` for Claude runtime surfaces. If the build changes Codex-visible surfaces (`.codex-plugin/`, `AGENTS.md`, `README.md`, `skills/`, or `commands/`), also run `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/check_cache_sync.py --host codex --source <plugin-source-repo>`. `[DIVERGED]`, `[MISSING IN CACHE]`, or stale installed Codex versions are **blocking** when they affect the host being used — runtime invocations will hit stale or missing files. Fix with `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/sync_plugin_cache.py --source <plugin-source-repo> --host <claude|codex|all>`, which syncs committed `HEAD` by default; use `--dirty --file <path>` only for explicit temporary runtime testing. Defer version bumps until the feature batch is declared complete (see Gate 6). Missing cache with no installed version skips silently (user has not installed the plugin, nothing to break).
|
|
177
211
|
- **Gate 5 — Design-Rule Scanner** (only when `uiTarget != null`): run `audit-design-rules.mjs` across full project (broader than Sub-step B's changed-files scope). Surfaces any pre-existing must-fix violations newly observable due to scanner rule additions. Pre-existing findings on first run are logged to `.build-loop/issues/` with break-what-if analysis (user decides scope). New-content findings are blocking. See `phases/ui-validation.md` for tuning.
|
|
178
212
|
- **Gate 5a — UI Input/Output Contract Scan** (only when `uiTarget != null`): walk the full rendered surface touched by the build and trace every input/output against `## UI Input/Output Contract`. Flag user-visible data without a component mapping, validation layer, state branch, or source trace. New-content gaps are blocking; pre-existing gaps are logged to `.build-loop/issues/` with user impact and recommended follow-up.
|
|
179
|
-
- **Gate 6 — Version-Bump Advisor** (only when `pluginWork: true`): run `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/version_advisor.py --workdir "$PWD"`. Default state is `hold` — emits a one-line note in Review-F: `"N commits accumulated since vX.Y.Z. Holding version. Create .build-loop/release-pending.md when the batch is ready."` Switches to `suggest` only when `.build-loop/release-pending.md` exists
|
|
213
|
+
- **Gate 6 — Version-Bump Advisor** (only when `pluginWork: true`): run `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/version_advisor.py --workdir "$PWD"`. Default state is `hold` — emits a one-line note in Review-F: `"N commits accumulated since vX.Y.Z. Holding version. Create .build-loop/release-pending.md when the batch is ready."` Switches to `suggest` only when `.build-loop/release-pending.md` exists. The marker may declare `bump: minor` or `bump: major`; absent or invalid declarations default to patch because one push is one release. Review-F surfaces `breaking_commits` for the release author's decision and asks for explicit user confirmation before any plugin.json edit. Never auto-bumps. Never blocks.
|
|
180
214
|
- **Gate 7 — UX Triage** (only when `uiTarget != null`): run `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/ux_triage.py --workdir "$PWD" --clear`. Static-scans for four dimensions — interactability, performance, data-accuracy beyond current scope, usability — across the full project (not just changed files). Each `blocker` or `major` finding becomes a queue entry in `.build-loop/ux-queue/<id>.md` with a complete fix plan, evidence, files-touched, and an `architecture_impact` flag. Minor findings stay in the Review-F report only. The agent layer augments static findings with `performance-assessor` and `fact-checker` agent dispatches against the same surface for dimensions the static scanner can't fully cover. Queue entries feed into Phase 5 Iterate (see "Iterate input contract" below). Never block the current build — UX rot fixes ride along, they don't gate.
|
|
181
215
|
- **Gate 8 — UI Coverage-Gap** (only when `uiTarget != null`): compare changed surfaces against existing project test files and the UI input/output contract. If a changed critical surface has no interaction/render coverage, add a queue entry to `.build-loop/ux-queue/` with `dimension: test-coverage` and a proposed repo-native test plan. Build-loop does not auto-draft `.ibr-test.json` files.
|
|
182
216
|
- **Gate 9 — README Currency** (every build; generic, not plugin-only): run `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/readme_currency_check.py --workdir "$PWD" --diff-range <pre_build_sha>..HEAD --json`. If the run changed a user-facing surface (a command, skill, agent, or CLI/`bin` entry per `readmeCurrency.surfaceGlobs`) but touched no README/`AGENTS.md` (`readmeCurrency.readmePaths`), it emits `verdict: warn` naming the undocumented surface. **WARN-only, never blocks** (advisory per the hook charter; exit 0 always) — surfaced in the Review-F report so the doc is updated before the batch ships. Skips cleanly when no surface changed, when disabled (`readmeCurrency.enabled: false`), or when no diff range resolves. Distinct from Gate 4 (which checks README↔plugin-cache *sync*, plugin repos only); this checks README *content currency* in any repo. Config + defaults: `.build-loop/config.json > readmeCurrency`; gate + tests: `scripts/readme_currency_check.py` / `scripts/test_readme_currency_check.py`.
|
|
@@ -267,6 +301,7 @@ Final report sections, in this order:
|
|
|
267
301
|
- `## Done` — every verified pass + every Auto-Resolve `auto` item, with one-line evidence each. **Lead outcome-first** (`output-style.md` §"Outcome framing"): the report's headline and substance lead with what the user can now do / what stops failing / what no longer needs a manual step, not the feature or mechanism that delivers it; mechanism, file paths, and design detail stay in the progressive-disclosure detail below the lead.
|
|
268
302
|
- `## Held` — items Auto-Resolve verdicted as `confirm`, with the `reason` field from `autonomy_gate.py` quoted verbatim. The user may run any held command manually if they want to. Build-loop does NOT prompt or auto-execute these.
|
|
269
303
|
- `## Blocked` — items Auto-Resolve verdicted as `block`, same shape as Held.
|
|
304
|
+
- `## Findings disposition` — MANDATORY every run (constitution `C-FINDINGS`). Table `| Finding | Source | State | Record |`, one row per finding surfaced from any source (Review A/B/D graders, lint, type-check, scanners, failing or skipped tests, deprecations, contract drift). `State` is exactly one of `fixed` / `waived` / `escalated`; `Record` is the commit sha, a `.build-loop/waivers/<ID>.md` (or decision) path, or a backlog / Operations Center id. Zero findings → header plus `_(no findings surfaced this run)_`; never omit the section, because omission and "nothing found" must not look alike. "Pre-existing" is provenance, not a state — an unchanged-by-this-commit warning still needs one of the three. Waivers are checked and written with `python3 scripts/waivers.py check|new`, always carry an expiry, and default to re-surfacing when their covered file next changes. Scope bounds what a run FIXES, never what it RECORDS: an out-of-scope finding takes the `escalated` row, never omission.
|
|
270
305
|
- `## Status markers` — ✅ Known / ⚠️ Untested / ❓ Unfixed (existing convention; keep this section).
|
|
271
306
|
|
|
272
307
|
Research citation gate: before emitting, read
|
|
@@ -320,7 +355,38 @@ If a category is empty (no Held items, no Blocked items), omit the section entir
|
|
|
320
355
|
|
|
321
356
|
Write scorecard to `.build-loop/evals/YYYY-MM-DD-<topic>-scorecard.md`.
|
|
322
357
|
|
|
323
|
-
**
|
|
358
|
+
**Groundwork implementation-map return (blocking when Phase 1 accepted a
|
|
359
|
+
request).** Write `.build-loop/groundwork-evidence.json` with exactly
|
|
360
|
+
`mappings`, `evidence`, and `deviations`. Map only request target IDs. Every
|
|
361
|
+
`implemented`/`verified` mapping names both existing repository-relative files
|
|
362
|
+
and real commits; every `verified` mapping references passing test/runtime evidence;
|
|
363
|
+
every passed evidence row names an existing repository-relative `artifactPath`
|
|
364
|
+
under `.build-loop/evidence/` whose bytes the adapter hashes. A passed row is
|
|
365
|
+
not trusted merely because the draft says `outcome: passed`: include one
|
|
366
|
+
`--verified-evidence-id` per evidence ID whose command Review-B actually ran
|
|
367
|
+
successfully. Then run:
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
request="${GROUNDWORK_BUILD_REQUEST:-$PWD/.designdoc/build-request.json}"
|
|
371
|
+
spec="${GROUNDWORK_SPEC:-$(dirname "$request")/spec.json}"
|
|
372
|
+
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/groundwork_exchange.py" emit-map \
|
|
373
|
+
--request "$request" --spec "$spec" \
|
|
374
|
+
--evidence "$PWD/.build-loop/groundwork-evidence.json" \
|
|
375
|
+
--workdir "$PWD" --output "$(dirname "$request")/implementation-map.json" \
|
|
376
|
+
--producer-version auto --created-at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
|
377
|
+
--verified-evidence-id "<id-from-Review-B>"
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
Any non-zero adapter exit routes to Iterate; contract and operational failures
|
|
381
|
+
return structured JSON with exit 2. Review-G cannot pass with stale bindings, unsafe
|
|
382
|
+
paths, missing commits/artifacts, unsupported targets, or a `verified` status
|
|
383
|
+
without passing evidence. Repeat `--verified-evidence-id` for each passed
|
|
384
|
+
receipt; never grant it to an unexecuted, stale, or user-supplied assertion.
|
|
385
|
+
Report the output digest and path. Build Loop never
|
|
386
|
+
writes Groundwork convergence or mutates `spec.json`; Groundwork independently
|
|
387
|
+
validates the map and calculates `groundwork.convergence/v1`.
|
|
388
|
+
|
|
389
|
+
**Debugger store + retrieval check**: for each resolved Review-B/Iterate failure, invoke `build-loop:debugging-memory` `{op:"store"}` with `{symptom, root_cause, fix, verification, tags, files_changed}`. Then search the symptom again and confirm the stored incident is discoverable from the same `.claude/memory/` root.
|
|
324
390
|
|
|
325
391
|
**Orphan scan**: invoke `Skill("build-loop:architecture-dead")` — runs `navgator dead`, diffs against the Phase 1 Assess baseline, surfaces ONLY new orphans introduced this build. No-ops cleanly when `.navgator/architecture/index.json` is absent.
|
|
326
392
|
|
|
@@ -334,8 +400,19 @@ python3 "${CLAUDE_PLUGIN_ROOT}/scripts/deployment_policy.py" \
|
|
|
334
400
|
|
|
335
401
|
Follow the returned `action`: `auto` may proceed after Review passes; `confirm` requires an explicit user confirmation in chat before running the command; `block` must not run and should be reported as a configured repo policy. Defaults favor speed for preview/TestFlight and safety for production/unknown.
|
|
336
402
|
|
|
337
|
-
**Auto-version-bump (LAST step before push/merge for plugin-bearing repos)**: when `plugin.json` (or `.claude-plugin/plugin.json`) exists at repo root AND `git diff --name-only origin/main..HEAD` includes any path outside `docs/`, `tests/`, `*.md`: bump the patch segment of `plugin.json:version`; mirror the new version into every locally-known `.claude-plugin/marketplace.json` (search
|
|
403
|
+
**Auto-version-bump (LAST step before push/merge for plugin-bearing repos)**: when `plugin.json` (or `.claude-plugin/plugin.json`) exists at repo root AND `git diff --name-only origin/main..HEAD` includes any path outside `docs/`, `tests/`, `*.md`: bump the patch segment of `plugin.json:version`; mirror the new version into every locally-known `.claude-plugin/marketplace.json` (search sibling checkouts under your dev root, if any, and `~/.claude/plugins/marketplaces/`) entry referencing this plugin — no sibling dev root or no matching entries is `(none found)`, not an error; commit `chore(version): bump <plugin-name> to <new-version>`. No minor/major bumps; no bumps for docs-only diffs.
|
|
338
404
|
|
|
339
405
|
**Post-deploy verification gate (after a deploy actually ran)**: once a deploy executed — i.e. the deployment policy gate returned `auto` and the deploy/push command ran, or the pushed branch auto-deploys via Vercel — invoke `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/verify_deploy.py --workdir "$PWD" --changed-route <route> [--changed-route <route> ...] --json`. The script detects a Vercel link (`.vercel/project.json` or `vercel.json`), resolves the latest production deployment, polls `vercel inspect` to a terminal state, then probes the prod root + each changed route. `pass` proceeds; `fail` routes to Iterate using the envelope's `findings` as the rubric; `skipped` (no Vercel link, CLI missing, not authed, or other transient infra) records `deploy_verify: skipped (<reason>)` in Review-F and proceeds. An auth-gated `401`/`403` on a protected route is **healthy** (function deployed and running) — only a `5xx`/build-error is a real failure. Never block the build on infra. See `agents/build-orchestrator.md` §"Review: Post-deploy verification gate" for the routing rules and `fallbacks.md#web-deploy-verify` for the inline degraded procedure.
|
|
340
406
|
|
|
341
407
|
**Append a run entry to `.build-loop/state.json.runs[]`** for Learn (Phase 6) to scan. The orchestrator agent owns the invocation — see `agents/build-orchestrator.md` §G for the canonical call (including `--judge-decisions-json` and `--budget-summary-json`). Schema and flags are owned by `scripts/write_run_entry/__main__.py --help`; do not hand-write JSON.
|
|
408
|
+
|
|
409
|
+
**Run-close assertion (MANDATORY every Phase 4G — run record and Learn receipt are verified, not assumed).** After `write_run_entry` and Phase 6 complete, assert both mutations landed:
|
|
410
|
+
|
|
411
|
+
```bash
|
|
412
|
+
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/run_close_lint.py" \
|
|
413
|
+
--workdir "$PWD" --run-id "<run_id>" --require-orchestrator --require-learn --json
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Exit 0 (`status: recorded`) → proceed. Exit 1 means the report waits: `missing`/`floor_only`/`no_state` describe run-record failures; `learn_missing` means the runner, receipt, state summary, or agent attestations are incomplete. Run the returned remediation, then re-run the lint.
|
|
417
|
+
|
|
418
|
+
Why this exists as a separate read rather than another clause inside the writer: the `runs[]` write already carried a "MUST fire on every Phase 4G regardless of dispatch path" rule and a `--scope build` review-completeness gate, and both are inside the write path, so both stay silent on **non-invocation** — the one failure mode observed on 2026-07-16, when six sequential dispatched orchestrators each returned a quality report and wrote no run record, retrospective, milestone, or feedback entry, starving Phase 6 Learn of a six-run day. A gate inside the script cannot fire when nobody runs the script, so the assertion reads durable state instead. The matching half is the dispatching parent's check at the completion boundary (`references/verify-dispatch.md` §6) — Review-G catches a write that failed, the parent catches an orchestrator that never reached Review-G. Contract locked by `scripts/test_run_close_lint.py`; lesson: `build-loop-memory/lessons/2026-07-17-lesson-dispatched-orchestrator-writes-no-run-records.md`.
|