@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
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
<!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
|
|
2
|
-
|
|
3
|
-
# Phase 2: Plan (full protocol)
|
|
4
|
-
|
|
5
|
-
> Loaded from `skills/build-loop/SKILL.md` summary. Contains the full Plan phase: task breakdown, dependency graph, mockup gate, and plan acceptance.
|
|
6
|
-
|
|
7
|
-
## Phase 2: Plan — Steps & Optimization
|
|
8
|
-
|
|
9
|
-
**Goal**: Break work into executable steps, then optimize the plan before execution.
|
|
10
|
-
|
|
11
|
-
0. **Consume the Phase 1 spec-router record (author selection)**: READ `state.json.intent.spec_router` (written by Phase 1 Assess step 11 per `references/capability-routing.md` §"Spec/Plan author router (intent-driven, ordered)"). Do NOT independently re-decide which author skill to call — **branch on `action` first**, then on `skill`:
|
|
12
|
-
- `action: "noop"` → **terminal**: author NOTHING from the router. Skip the author/writing-plans invocation entirely and proceed to step 1's optimization work without drafting a spec. Do not fall through to `writing-plans`.
|
|
13
|
-
- `action: "recommend"` → surface-only: name the recommended `skill` in the report so the lead knows what to run if it chooses, but do NOT auto-invoke it. Then proceed. (Distinct from `call`, which auto-invokes, and `noop`, which skips silently.)
|
|
14
|
-
- `action: "call"`, `skill: "build-loop:spec-writing"` → invoke `Skill("build-loop:spec-writing")` to draft the plan (the `no-plan` case: `.build-loop/plan.md` absent/empty).
|
|
15
|
-
- `action: "call"`, `skill: "build-loop:writing-plans"` → the plan exists and is valid; go straight to step 1 (`writing-plans` turns it into the task/dependency graph). Skip spec-writing. `writing-plans` is the external superpowers skill, not vendored here; if absent, write a structured plan inline (see `references/capability-routing.md` §"Core loop skills/assets" fallback).
|
|
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
|
-
- **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
|
-
|
|
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, and routing-risk fields), runs `check_checklist.py` + `plan-critic`, writes the plan to `docs/plans/<feature-slug>.md`, and commits it before any implementation branches are cut. Only continue to step 1 once a plan path exists.
|
|
20
|
-
|
|
21
|
-
1. **Invoke `writing-plans` skill** for detailed task breakdown
|
|
22
|
-
2. **Identify parallel-safe tasks** vs sequential dependencies — build a dependency graph
|
|
23
|
-
- If the graph has 2+ independent / parallel-safe chunks, write `parallel_batch:` naming the chunks that will dispatch together.
|
|
24
|
-
- If the graph appears parallelizable but execution must serialize, write `parallel_skipped_reason:` with the specific dependency, tool limit, or coordination constraint.
|
|
25
|
-
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
|
-
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
|
-
- **Clean-sheet best approach**: the use-case-first answer if no prior implementation debt or historical decisions constrained the design.
|
|
28
|
-
- **Current-constraints approach**: the best practical answer given the repo's existing code, dependencies, tools, debt, migration risk, and delivery horizon.
|
|
29
|
-
- **Bridge/backcast**: the smallest credible migration path from current state toward the clean-sheet target.
|
|
30
|
-
- **Recommendation**: what to execute now and why. If choosing the constrained path, name the constraint that justifies not taking the clean-sheet path now.
|
|
31
|
-
|
|
32
|
-
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
|
-
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
|
-
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).
|
|
35
|
-
|
|
36
|
-
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
|
-
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.
|
|
38
|
-
6. **Codex delegation gate**: If running in Codex, record whether the user explicitly authorized subagents/parallel delegation. If not, keep all execution local even when the graph contains parallel-safe groups.
|
|
39
|
-
7. **Research Context gate**: read `.build-loop/state.json.researchGate`. If
|
|
40
|
-
`research_required: true`, add `## Research Context` to the plan with the
|
|
41
|
-
returned `depth`, `packet_path`, source policy, and
|
|
42
|
-
`blocks_final_claims` value. If `packet_path` is non-null, state whether
|
|
43
|
-
the packet already exists, will be created before Execute, or is unavailable
|
|
44
|
-
with rationale. For current/external/API claims, verify current docs before
|
|
45
|
-
coding and do not carry uncited claims into the final report.
|
|
46
|
-
8. **UI input/output contract gate**: If `uiTarget != null`, load `references/ui-io-contract.md` and add a `## UI Input/Output Contract` section to the plan before mockups or implementation. The section must cover every affected screen/component and name: user inputs, system outputs, data taxonomy, CRUD/domain operation, component mapping, state matrix, modality fallback, validation/security, and traceability. If a planned UI component has no named input/output, remove it or mark it decorative with rationale; decorative controls are usually a scope error.
|
|
47
|
-
8a. **Calm Precision core-consideration gate**: If `uiTarget != null`, the design direction must treat Calm Precision as a core decision gate before selecting structure, style mode, motion, or interaction behavior. The resulting `.build-loop/app-contract/ui.md` must include `## Calm Precision Core Considerations` with relevant principles, perceptual foundations, implementation effects, and explicit exceptions.
|
|
48
|
-
8b. **Recent design structures gate**: If `uiTarget != null`, load `references/recent-design-structures.md` before dispatching `design-contract-specialist`. The specialist, not the planner, selects the structure. The plan should pass the file path and any relevant mockup/screenshot/design artifacts; it should not force a named structure unless the user explicitly requested one.
|
|
49
|
-
9. **Mockup-first gate for major UI work**: If the plan introduces a *new page/screen* or makes a *major redesign* (changes navigation graph, primary user flow, or replaces ≥40% of an existing screen), pause Plan and invoke `mockup-gallery:mockup-session-new` to draft black-and-white mockups before any UI is written. Wait for user feedback via `mockup-gallery:mockup-feedback`; carry the selected mockup into Execute as a reference. Skip for cosmetic tweaks, copy edits, or single-component swaps. This is the documented exception to build-loop's "actions/functions only, no UI surfaces" plugin-bridging policy — mockup drafting is itself the action.
|
|
50
|
-
|
|
51
|
-
**Optimization checklist** (review the plan for these before proceeding):
|
|
52
|
-
- Can more tasks run in parallel? Unnecessary sequential bottlenecks?
|
|
53
|
-
- Can subagent context be smaller? Shared reads that should be done once?
|
|
54
|
-
- Missing dependencies, interface mismatches, env assumptions?
|
|
55
|
-
- Changes that could conflict with each other (oscillation risk)?
|
|
56
|
-
- Is the recommendation accidentally anchored to current tech debt when a cleaner use-case-first answer exists?
|
|
57
|
-
- If the plan chooses the current-constraints approach, is the bridge/backcast explicit enough to prevent the compromise from becoming permanent architecture by default?
|
|
58
|
-
- Define coordination checkpoints where subagents must sync
|
|
59
|
-
- UI/API/data choices that add options, mocks, or complexity without user value?
|
|
60
|
-
- UI plans missing input/output coverage, state coverage, modality fallbacks, validation/security layers, or schema/API traceability?
|
|
61
|
-
- MECE gaps or overlaps: unowned responsibilities, shared file ownership, or mixed grouping dimensions?
|
|
62
|
-
- Boundaries that are too tight, too broad, or missing a stable interface?
|
|
63
|
-
- If the plan chooses a simpler/integrated path over modularity, is there a documented `MODULARITY EXCEPTION`?
|
|
64
|
-
|
|
65
|
-
**Plan acceptance gate** — required before "Output: Plan file":
|
|
66
|
-
|
|
67
|
-
**Readback discipline**: build-loop runs `plan-verify` and `plan-critic` automatically and prefixes every plan presentation with a one-line gaps-readback. The user should never have to ask "anything missing?" — the answer is always shown first.
|
|
68
|
-
|
|
69
|
-
Readback format (one line, mandatory, before the plan body):
|
|
70
|
-
- `✓ Plan gaps-checked (plan-verify + plan-critic): none` — when both passes are clean.
|
|
71
|
-
- `⚠ Plan gaps: <N> — <comma-separated list of findings>` — when findings exist, with each item marked `resolved` or `surfaced` (resolved = fixed in this plan revision; surfaced = carried as open for user awareness).
|
|
72
|
-
|
|
73
|
-
8. **Run `plan-verify`** (deterministic, grep-checkable rules; now includes `no-stop-language` rule):
|
|
74
|
-
```bash
|
|
75
|
-
python3 ${CLAUDE_PLUGIN_ROOT}/scripts/plan_verify.py <plan.md> --repo "$PWD" --json
|
|
76
|
-
```
|
|
77
|
-
- Exit 0 → proceed to step 9.
|
|
78
|
-
- Exit 1 → revise the plan to address each BLOCKER, or document an explicit override in `.build-loop/state.json.planVerifyOverride[]` with rationale before proceeding.
|
|
79
|
-
- Exit 2 → treat as verifier outage; log and proceed with `plan-critic` alone plus a state.json warning.
|
|
80
|
-
- `parallel-decision-record` is a BLOCKER: plans that name independent / parallel-safe multi-chunk work must include `parallel_batch:` or `parallel_skipped_reason:`.
|
|
81
|
-
- Full rule list and contract: `${CLAUDE_PLUGIN_ROOT}/skills/plan-verify/SKILL.md`.
|
|
82
|
-
9. **Dispatch `plan-critic` agent** (non-deterministic checks): pass the plan + the JSON from step 8 so the critic doesn't re-derive deterministic findings. Critic surfaces alternatives-considered, MECE scope, marker adequacy, headline drift. The critic's emitted severity caps at WARN. **Gating is stakes-conditional (decided by the orchestrator, not the critic):** on high-stakes plans (`synthesisDensity > 5`, `triggers.riskSurfaceChange`, `stakes >= medium`, or `dispatch_tier: frontier`) those WARNs are **blocking** — Phase 2 does not finish until each is revised or explicitly overridden; otherwise they are **advisory** (today's behavior). The gate advances on objective signals only, never self-reported confidence. See `references/advisor-dispatch-ladder.md`.
|
|
83
|
-
10. **Emit gaps-readback** using the combined output of steps 8–9. Populate the one-line readback prefix before presenting the plan. Both passes must complete before the plan is shown to the user — never present a plan without the readback line.
|
|
84
|
-
11. **Dispatch `scope-auditor` agent** (Plan→Execute boundary): pass the plan + extracted commit table (with `modifies_api` per commit). The auditor is Opus + read-only; it traces every caller-site of every modified-API symbol via project-wide grep, classifies callers as in-scope / out-of-scope, and emits a `## Caller Audit (Scope Auditor)` JSON section appended to the plan. Verdict `scope_gap_found` requires plan revision (absorb missing callers into the right commit's owned-files) before Phase 3, OR explicit acceptance in `state.json.scopeGapAccepted[]` with rationale. Skip ONLY when the plan has zero `modifies_api` entries (doc-only commits). Prevents the fan-out scope-blindness defect class — see `agents/scope-auditor.md`.
|
|
85
|
-
|
|
86
|
-
**Output**: Plan file with dependency graph, integration points, optimization notes, plan-verify JSON, plan-critic findings, gaps-readback line, and scope-auditor caller audit.
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
<!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
|
|
2
|
-
|
|
3
|
-
# Phase 3: Execute (full protocol)
|
|
4
|
-
|
|
5
|
-
> Loaded from `skills/build-loop/SKILL.md` summary. Contains the full Execute phase: parallel subagent dispatch, single-writer git contract, and C5 halt-and-ask backstop.
|
|
6
|
-
|
|
7
|
-
## Phase 3: Execute — Build With Agents
|
|
8
|
-
|
|
9
|
-
**Goal**: Implement the plan using parallel subagents where possible.
|
|
10
|
-
|
|
11
|
-
1. **Use `subagent-driven-development`** — dispatch subagents per task
|
|
12
|
-
2. **Model assignment**: Default implementer `model: sonnet`, `effort: high` (`xhigh` on hard/code-heavy chunks — Sonnet 5's coding gains land at high/xhigh, claude-api T1). Consult `Skill("build-loop:model-tiering")` for task-specific defaults and escalation triggers
|
|
13
|
-
3. **Parallel agents** where dependency graph allows. build-loop dispatches up to `effective_max` parallel subagents, where `effective_max = scripts/parallelism.py effective_max_implementers(workdir)` — machine-aware (default 8; `min(config.parallelism.maxImplementers, cpu_count−2, hard ceiling 12)`). Decompose the plan into as many independent MECE chunks as the dependency graph allows so the wider fan-out is filled; dispatch in batches via `plan_batches()` when chunk count exceeds `effective_max`.
|
|
14
|
-
|
|
15
|
-
**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
|
-
**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
|
-
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
|
-
**`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
|
-
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
|
-
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".
|
|
23
|
-
5. **Codex execution adapter**: If running in Codex, load `references/codex-subagents.md` before any spawn decision. Spawn `explorer` or `worker` subagents only when the Codex permission gate passed; otherwise execute locally. When spawning a worker, use `templates/codex-worker-prompt.md`, prefer explicit prompt packets over full context forks, and require the worker return changed files, validation, unresolved risks, and integration notes.
|
|
24
|
-
6. **UI work (when `uiTarget != null`)**: Every UI subagent prompt MUST be prepended with the verbatim contents of `templates/ui-subagent-prompt.md` (loaded as raw text, not as a link). The template injects:
|
|
25
|
-
- Mandate to load `calm-precision`, read `.build-loop/app-contract/ui.md` when present, and use external platform/design skills only when explicitly requested by the orchestrator
|
|
26
|
-
- Mandate to apply the plan's `## UI Input/Output Contract` from `references/ui-io-contract.md`
|
|
27
|
-
- Mockup-vs-rule conflict policy: rule wins; subagent must report `RULE BEATS MOCKUP:` decisions
|
|
28
|
-
- Inline anti-pattern checklist (status pills, ungated animations, theme-token bypass, Dynamic Type, accessibility labels, touch targets, VoiceOver consistency, no fake buttons)
|
|
29
|
-
- Required env hooks (e.g. `@Environment(\.accessibilityReduceMotion)` on SwiftUI animations)
|
|
30
|
-
- Self-verification: run scanner before returning, zero must-fix on changed files
|
|
31
|
-
|
|
32
|
-
Subagents cannot rely on parent context — knowledge that doesn't enter the prompt doesn't reach the code. The template entering the prompt is non-negotiable. Plus also load `calm-precision` skill at the orchestrator level for cross-cutting decisions. Apply "beauty in the basics": every visible element needs a purpose, working behavior, clear hierarchy, useful states, accurate data, and an explicit input/output contract.
|
|
33
|
-
7. **Surface pre-existing issues**: Don't silently ignore problems discovered during implementation. If an issue affects users and is local to the current build, plan and fix it automatically. If it is too large/risky, log to `.build-loop/issues/` with user impact and proposed fix.
|
|
34
|
-
7a. **Simplify as you go**: remove dead code AND prefer the clearest, equal-or-better-performing logic/architecture — never just deletion; preserve behavior + correctness.
|
|
35
|
-
7b. **Visual-evidence gate (BL-1)** — REQUIRED at chunk-close when `uiTarget != null` AND the chunk's `files_changed` includes any UI file (`Views/`, `*.swift`, `*.tsx`, `*.jsx`, `*.vue`, `*.svelte`, `components/*`, `pages/*`, `app/*.ts(x)`). After the implementer returns and before the commit step, build an envelope `{ uiTarget, files_changed, verification, evidence_paths }` from the return packet and run:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
node "${CLAUDE_PLUGIN_ROOT}/skills/build-loop/scanners/require-visual-evidence.mjs" \
|
|
39
|
-
--envelope-file "$PWD/.build-loop/visual-evidence-<chunk>.json"
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Exit-code routing:
|
|
43
|
-
- `0` (pass) → proceed to commit step
|
|
44
|
-
- `1` (warn) → re-prompt the implementer for a screenshot / AX-tree dump / scan result; do NOT commit yet
|
|
45
|
-
- `2` (reject) → **BLOCK the commit**; route the chunk back to Phase 5 Iterate with `status: fail` and the gate's `reason` as the rubric. Symbol/string-only evidence (`nm`, `strings`, `git grep`, "compiles cleanly", "identifier present") is NOT a substitute for visual/AX verification. Required: render the running app (pid-anchored) and capture a screenshot, AX-tree dump, or scan result.
|
|
46
|
-
- `3` (malformed) → log a one-line warn and proceed (infra defect, not a build defect — capture in `.build-loop/feedback.md`)
|
|
47
|
-
|
|
48
|
-
This gate exists because "visual-verify REQUIRED" was historical prose that a bad dispatch brief could override (session-findings 2026-06-04: brief blessed `nm`/`strings` → chunks shipped with non-rendering UI). The gate replaces prose with an enforced exit-code check.
|
|
49
|
-
8. **Coordination checkpoints**: At defined sync points, verify agent outputs align before continuing
|
|
@@ -1,341 +0,0 @@
|
|
|
1
|
-
<!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
|
|
2
|
-
|
|
3
|
-
# Phase 4: Review (full protocol)
|
|
4
|
-
|
|
5
|
-
> Loaded from `skills/build-loop/SKILL.md` summary. Contains the seven sub-steps A–G including Sub-step F Auto-Resolve with all 4 routing arms (auto/warn/confirm/block).
|
|
6
|
-
|
|
7
|
-
## Phase 4: Review — Critic, Validate, Fact-Check, Simplify, Auto-Resolve, Report
|
|
8
|
-
|
|
9
|
-
**Goal**: evaluate the built output against the rubric and decide pass / fail / iterate. Everything that used to live in phases 4.5, 4.7, 5, 7, 8, and 8.5 happens here as ordered sub-steps. One phase heading, seven sub-steps, single exit point.
|
|
10
|
-
|
|
11
|
-
Review runs every time we need an evaluation (initial post-Execute, and again after each Iterate pass). The report sub-step (G) writes final artifacts only on the LAST pass — intermediate Reviews skip it.
|
|
12
|
-
|
|
13
|
-
### Sub-step A: Critic (adversarial read-only)
|
|
14
|
-
|
|
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
|
-
|
|
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. 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
|
-
|
|
20
|
-
**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
|
-
|
|
22
|
-
1. **Agent tool present** (top-level / Mode A) → dispatch `independent-auditor` at build scope as above → `auditor_status: ran:dispatched-agent`.
|
|
23
|
-
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.
|
|
25
|
-
|
|
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
|
-
2. **Input**: the rubric from `.build-loop/goal.md` + the implementer's diff (`git diff HEAD~1` or the changed-file set).
|
|
28
|
-
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
|
-
4. **Routing** (QM v0.13.0 normalized severities; legacy `major→high`, `minor→medium`, `info→low`):
|
|
30
|
-
- `verdict: yay` → proceed to sub-step B (Validate)
|
|
31
|
-
- `verdict: nay` (paired with a `critical`/`high` finding) → route back to **Execute** for fixes (strong-checkpoint; no iteration counter burn yet on critic-only failures). If the diff reveals the *plan* is wrong, re-plan instead — orchestrator's call.
|
|
32
|
-
- `verdict: suggest_correction` with `auto_fixable: true` AND `severity in {medium, low}` → Auto-Resolve queue (Sub-step F)
|
|
33
|
-
- `verdict: look_again` → operator gathers the named `missing_artifacts` and re-runs the auditor
|
|
34
|
-
- `severity: medium|low` findings → record in `.build-loop/issues/` and proceed; `critical|high` never proceed silently (they block the final pass — see Sub-step G no-critical/high exit gate)
|
|
35
|
-
5. **Escalation**: if the same chunk fails critic twice, escalate the implementer to Opus per `model-tiering` skill §Escalation Triggers.
|
|
36
|
-
6. **Skip** on re-reviews after Iterate (critic already saw the diff at first pass) unless Iterate touched different files. Skip entirely for trivial chunks (single-file typo, config value).
|
|
37
|
-
7. **Push-hold marker (set on blocking verdict, clear on resolution)** — close the "autonomous push of un-reviewed work" defect at the git layer, not the app layer. When the auditor returns `verdict: nay` OR `verdict: suggest_correction` OR `verdict: look_again` AND those findings are NOT yet resolved, immediately set the push-hold marker so a parallel autonomous push (self-review `apply_push`, `codex-autonomy-poller`, any path that doesn't consult `deployment_policy.py`) gets blocked by `hooks/git/pre-push`:
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
python3 ${CLAUDE_PLUGIN_ROOT}/scripts/push_hold.py --set \
|
|
41
|
-
--source review-a \
|
|
42
|
-
--reason "<verdict> from independent-auditor (run <run_id>)" \
|
|
43
|
-
--auditor-verdict "<verdict>" \
|
|
44
|
-
--finding-ids "<comma-separated finding ids>" \
|
|
45
|
-
--run-id "<run_id>" --json
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
The marker is auto-detected as a hold by the pre-push hook even when the orchestrator crashes mid-run — that's the whole reason it lives at the git layer. On re-audit pass (verdict `yay`, OR every prior `critical`/`high` finding now has `resolved: true` in `state.json.runs[-1].judge_decisions[]`), CLEAR the marker:
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
python3 ${CLAUDE_PLUGIN_ROOT}/scripts/push_hold.py --release \
|
|
52
|
-
--reason "auditor findings resolved (run <run_id>)" --json
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
The state.json signal is a backstop: if the marker was somehow lost, `push_hold.evaluate_push` will still detect an unresolved blocking verdict in `runs[-1].judge_decisions[]` and block. The explicit marker takes precedence; both are honored. Bypass exists at `BUILDLOOP_PUSH_HOLD_BYPASS=1` (logged to `.build-loop/audit-log.md`) for genuine emergencies — never in autonomous mode without an explicit operator decision. The pre-push hook is installed via `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/install_git_hooks.py --install` (idempotent; mirror of the existing `audit_before_commit.py` install pattern).
|
|
56
|
-
|
|
57
|
-
### Sub-step B: Validate (graders + memory-first gate)
|
|
58
|
-
|
|
59
|
-
Test every criterion from Assess with evidence.
|
|
60
|
-
|
|
61
|
-
**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
|
-
|
|
63
|
-
**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.
|
|
64
|
-
|
|
65
|
-
**UI input/output contract validation** (`uiTarget != null`): read the plan's `## UI Input/Output Contract` section and compare it to changed UI files before visual validation. Confirm every user input and system output in the changed surface has a data taxonomy, operation/domain verb, component mapping, state coverage, modality fallback when relevant, validation/security layer, and schema/API/design-system trace. Missing coverage is a Validate failure unless the change is copy-only and the contract explicitly says no data surface changed.
|
|
66
|
-
|
|
67
|
-
**Calm Precision core-consideration validation** (`uiTarget != null`): check `.build-loop/app-contract/ui.md` or the implementer return envelope for the relevant Calm Precision principles, foundations, and implementation effects. Missing consideration is a Validate failure for non-trivial UI work, because Calm Precision is a design gate, not a passive reference.
|
|
68
|
-
|
|
69
|
-
**Code-based graders first** (fast, deterministic):
|
|
70
|
-
```
|
|
71
|
-
test suite → pass/fail
|
|
72
|
-
lint / type check → pass/fail
|
|
73
|
-
build → pass/fail
|
|
74
|
-
accessibility → threshold pass/fail (if web)
|
|
75
|
-
schema validation → pass/fail
|
|
76
|
-
custom assertions → pass/fail
|
|
77
|
-
design-rule scan → must-fix=0 pass/fail (uiTarget != null only)
|
|
78
|
-
ui io contract → pass/fail (uiTarget != null only)
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
**Design-rule scan** (when `uiTarget != null`):
|
|
82
|
-
```
|
|
83
|
-
node "${CLAUDE_PLUGIN_ROOT}/skills/build-loop/scanners/audit-design-rules.mjs" --root=<project> --platform=<swiftui|react|web> --json
|
|
84
|
-
```
|
|
85
|
-
Exit 0 = clean. Exit 1 = warnings only (continue, log). Exit 2 = must-fix found (fail; route to Iterate).
|
|
86
|
-
|
|
87
|
-
This is the static-analysis gate that catches what mockup-parity misses — colored status pills, ungated `.repeatForever`, raw `UIColor` outside Theme, literal `cornerRadius`, body-copy `.font(.system(size:))`, icon-only `Image(systemName:)` without accessibility labels. Maintained in `scanners/audit-design-rules.mjs`, dependency-free Node 18+, per-platform packs.
|
|
88
|
-
|
|
89
|
-
**Visual validation** (REQUIRED when `uiTarget != null`): the static scanner cannot catch rendering bugs — an upside-down arc, an invisible track stroke, a row clipped behind a floating tab bar, a chip that wraps. After the scanner passes, render the actual screen via the platform's preferred tool:
|
|
90
|
-
- iOS / macOS / watchOS: `xcrun simctl io booted screenshot` after installing and launching the build, or the built-in native AX driver for macOS interaction checks
|
|
91
|
-
- Web: browser/screenshot tooling against the dev server URL
|
|
92
|
-
- Fallback: static scanner + explicit missing-visual-evidence note
|
|
93
|
-
|
|
94
|
-
**The audit is mandatory; the verdict is advisory.** The screenshot/browser artifact path MUST be written to `state.json.runs[].artifacts.uiAudit[]` and surfaced in the Phase 4 Report `## Notes from judges` section. **Findings are WARN-only — never block the build** (same posture as `synthesis-critic`). The user retains final visual judgment; build-loop's job is to guarantee the artifact lands in the operator's view before any TestFlight/preview/production push. Subjective UI judgments (intended chrome change vs scope creep, deliberate layout shift vs regression) cannot be mechanically distinguished from intended changes — a fail-closed audit would halt every legitimate UI change with false-positive layout-shift noise. Per [[pattern_buildloop_coordination_default]]. **Scope-creep signal:** if the diff vs prior baseline shows substantial pixel delta on routes the plan did NOT name as touched, surface in `## Notes from judges` as `scope_creep_signal` with the route list — advisory only; build does NOT pause and does NOT route to `## Held`.
|
|
95
|
-
|
|
96
|
-
For returning-user states (post-onboarding screens, dashboards with data), use the DebugSeeder pattern (see `templates/ui-subagent-prompt.md` §DebugSeeder) so visual states can be verified in seconds without manual data entry. Build 55 of a real shipped app passed scanner exit 0 but rendered an upside-down semicircle gauge with stray tick marks because no one rendered the actual screen — visual validation is non-negotiable for UI work.
|
|
97
|
-
|
|
98
|
-
**Live HTTP/SSE smoke** (REQUIRED when `triggers.runtimeServer == true` AND the diff touches `runtimeServerInfo.server_module` OR `runtimeServerInfo.embedded_ui_module`): pytest with mocked SDKs is necessary but not sufficient for projects that ship a live server — it does not iterate real DOM trees, does not open SSE connections, and does not render embedded HTML. Implements decision `_unscoped/0003`. The 5-step procedure:
|
|
99
|
-
|
|
100
|
-
1. Restart the server in background. Read `state.json.runtimeServerInfo.start_command` if present, else fall back to `uv run <package> --serve --port <default_port>` derived from `pyproject.toml`'s package name and `runtimeServerInfo.default_port`. Redirect stdout/stderr to `/tmp/buildloop-serve.log` for forensic surface in Review-F.
|
|
101
|
-
2. Wait up to 15s for `/api/status` (or `/`) to return HTTP 200 — poll once per second.
|
|
102
|
-
3. Run a 5-second curl POST against the SSE route:
|
|
103
|
-
```
|
|
104
|
-
curl -sN -X POST http://localhost:<port><sse_route> \
|
|
105
|
-
-H 'Content-Type: application/json' -d '<minimal-prompt>' --max-time 5 \
|
|
106
|
-
| grep -oE '"type":\s*"[^"]+"' | sort -u
|
|
107
|
-
```
|
|
108
|
-
4. Read the UI's event-handler switch at the locations from `runtimeServerInfo.event_handler_locations[]` and extract every handled event type (regex on `d\.type === '([^']+)'` and `d\.type == "([^"]+)"`). Skip this step when `embedded_ui_module: null` (API-only services have no embedded UI to compare).
|
|
109
|
-
5. **Fail the build** when an observed event type from step 3 has no matching handler arm from step 4 — this is the silent-server, ignored-client class of bug. Surface as a Validate failure → routes to Iterate.
|
|
110
|
-
|
|
111
|
-
If any infrastructure step fails (server won't start, curl errors, can't parse handler) → log evidence to `.build-loop/issues/live-smoke-<date>.md` and surface as `⚠️ untested live-flow` in Review-F. Do NOT fail the build on infrastructure issues — only on the specific server/client contract violation. Heavier integration tests (Playwright/Selenium) are still the right answer for full correctness; this gate is the cheapest check that catches what pytest-with-mocks cannot.
|
|
112
|
-
|
|
113
|
-
**LLM-as-judge graders second** (for nuanced criteria):
|
|
114
|
-
- Each criterion → its own focused judge prompt
|
|
115
|
-
- Binary pass/fail output only
|
|
116
|
-
- No multi-dimension scoring in a single prompt
|
|
117
|
-
|
|
118
|
-
**Evidence collection**:
|
|
119
|
-
- Every pass/fail must have evidence: command output, screenshot, or judge reasoning
|
|
120
|
-
- Use `verification-before-completion` for evidence-based claims
|
|
121
|
-
- No criterion marked "pass" without proof
|
|
122
|
-
|
|
123
|
-
**Acceptance-probe re-run gate (deterministic gate #1 — runs first, before any criterion can be marked passed)**: re-execute every `acceptance_probe` captured in Phase 1 Assess against the post-fix tree:
|
|
124
|
-
```
|
|
125
|
-
python3 ${CLAUDE_PLUGIN_ROOT}/scripts/acceptance_probe.py rerun --goal .build-loop/goal.md --workdir "$PWD" --json
|
|
126
|
-
```
|
|
127
|
-
Per-criterion `gate_verdict`:
|
|
128
|
-
- `passed` — the probe ran and its output **no longer matches the captured baseline-failure**. The criterion's data-layer evidence is necessary but NOT sufficient; this re-run is the boundary observation that makes "passed" real. Proceed to the criterion's other graders.
|
|
129
|
-
- `blocked` — the probe **still returns its baseline-failure state**. A blocked criterion **CANNOT be marked `passed`, and CANNOT be deferred inline** (no "out of scope" prose drop — that exact scope-drop is the evidenced failure this gate closes, sample-app 2026-06-13). It routes to Iterate like any Validate failure. If the run nonetheless needs to defer it, the deferral is a **DECISION-class surface**: pass the criterion's `decision_command` through the existing autonomy gate —
|
|
130
|
-
```
|
|
131
|
-
python3 ${CLAUDE_PLUGIN_ROOT}/scripts/autonomy_gate.py --workdir "$PWD" \
|
|
132
|
-
--action "defer acceptance criterion <id>" --command "<decision_command>" --json
|
|
133
|
-
```
|
|
134
|
-
with `.build-loop/config.json` `autonomy.confirmFor` carrying `"defer acceptance criterion *"`, so the verdict is `confirm` and the item lands in Sub-step G's `## Held` (explicit operator confirmation), never an inline prose defer. This reuses the Sub-step F Auto-Resolve wiring — no parallel surface.
|
|
135
|
-
- `unverifiable` — the criterion carried no probe (flagged at Assess). The re-run has nothing to execute; the criterion falls through to its LLM-judge/other graders as today. Surface `⚠️ <id> unverifiable — no acceptance_probe` in Review-G.
|
|
136
|
-
- `error` — the probe could not run (timeout / OS error). Surfaced, not silently passed; treat like an infrastructure-failure note and re-attempt or route to Iterate.
|
|
137
|
-
|
|
138
|
-
`rerun` exit 0 = no criterion blocked; exit 1 = at least one blocked. Skip cleanly when goal.md has no `acceptance_probe` block (legacy/opt-in run; `no_probes`). Boundary discipline: the probe's declared `boundary` (`data|api|render|console|visual`) is the boundary the re-run observes — a `console`/`render` criterion is re-checked at that boundary, not via a cheaper `data` proxy. Full contract: `scripts/acceptance_probe.py` module docstring; Phase 1 capture in `phase-1-assess.md` §"Acceptance-probe contract".
|
|
139
|
-
|
|
140
|
-
**Runtime smoke gate (post-tests, pre-LLM-judges)**: after code-based graders pass, invoke `python3 scripts/runtime_smoke.py --changed-files <list> --workdir "$PWD" --json` whenever any changed file matches a runtime-smoke trigger. The script auto-detects a dev-server adapter from the project's manifest (Next.js today; FastAPI, Express, and SSE-consumer adapters are documented future slots). `pass` proceeds; `fail` routes to Iterate using the smoke envelope's `findings` as the rubric; `skipped` (no trigger matched or no adapter for this stack) records `runtime_smoke: skipped (<reason>)` in Review-F and proceeds — library-only repos never fail this gate. See `references/runtime-smoke-triggers.md` for the full trigger-pattern table and adapter roadmap, and `agents/build-orchestrator.md` §"Review-B: Runtime smoke gate" for the routing rules.
|
|
141
|
-
|
|
142
|
-
**Pytest-collection gate (full-suite-load check, every run)**: after code-based graders pass and before LLM judges, invoke `python3 scripts/pytest_collect_gate.py --workdir "$PWD" --json` on Python-bearing repos. The gate runs `pytest scripts/ tests/ --collect-only` with `PYTHONPATH` stripped (matching the spec's `env -u PYTHONPATH` discipline). Collection-only is the bar — it does NOT require the full suite to execute green (db/live tests legitimately skip via their markers); it only verifies that every test module *loads*. `pass` (exit 0, no findings) proceeds; `fail` (exit 1, one or more import/syntax errors) routes to Iterate using `findings[]` as the rubric — each finding carries `{file, line, error_class, message}` pointing at the broken module so the next iteration fixes the import rather than papering over the test; `exit 2` (runner error — pytest not found or a usage error with no parseable output) carries `status="fail"` with `error_class="RunnerError"` and `stderr_tail` — treat it exactly as `fail` and route to Iterate; `skipped` (no `pyproject.toml`/`pytest.ini`/`setup.cfg` and no test paths — library-only repo) records `pytest_collect: skipped (<reason>)` in Review-F and proceeds. **Non-standard layouts**: when `pyproject.toml` is present but the default `scripts/`/`tests/` paths are absent, the gate skips with a loud reason naming the gap — pass `--paths <dir> [...]` so a Python-bearing repo with tests elsewhere is not silently bypassed. **Why this gate exists** (every issue is a systems issue): build-loop's run gate historically scoped to changed-area tests, so a broken import that quietly removed an entire test module from coverage would not fail the build — exactly how 8750d2a's psycopg breakage and the EXECUTION_SCHEMA_VERSION miss hid for multiple runs. The collection gate closes that gap with one cheap check; the gate file is `scripts/pytest_collect_gate.py`, its regression tests are `scripts/test_pytest_collect_gate.py`.
|
|
143
|
-
|
|
144
|
-
**Memory-first gate (on any failing criterion)**: before routing failures to Iterate, the orchestrator runs the gate (read_logs → synthesize symptom → invoke `Skill("build-loop:debugging-memory")` → act on verdict). See `agents/build-orchestrator.md` §Phase 4 sub-step B for the orchestrator's exact when-to-fire and gate-recording policy. **Memory is a hypothesis, not a patch — every verdict routes to Iterate as an adapted plan by default**:
|
|
145
|
-
|
|
146
|
-
- `KNOWN_FIX` → adapt prior incident as the Iterate fix plan. Direct-apply only when all three gates hold: file match + version match + second validation signal (stack frame, error class, or log entry). Otherwise behave as LIKELY_MATCH.
|
|
147
|
-
- `LIKELY_MATCH` → adapt prior incident as the Iterate fix plan
|
|
148
|
-
- `WEAK_SIGNAL` → note reference in the Iterate plan, investigate normally
|
|
149
|
-
- `NO_MATCH` → standard Iterate fallthrough; store at sub-step G Report for future learning
|
|
150
|
-
|
|
151
|
-
The memory gate is always on. Build-loop bundles native debugging-memory skills and file-backed search/store, with standalone Coding Debugger available only as an optional cross-project memory plugin when explicitly installed. If structured memory is unavailable, the orchestrator falls through to the local-grep fallback. The strict direct-apply triple-gate spec lives in `skills/debugging-memory/SKILL.md` §"Direct-apply gate (strict)".
|
|
152
|
-
|
|
153
|
-
**Output**: per-criterion pass/fail with evidence. Any `fail` → Iterate. All `pass` → sub-step C.
|
|
154
|
-
|
|
155
|
-
### Sub-step C: Optimize (opt-in, only with a mechanical metric)
|
|
156
|
-
|
|
157
|
-
Metric-driven autonomous optimization using Karpathy's autoresearch pattern. Opt-in — runs only when a mechanical metric exists AND the user hasn't disabled it.
|
|
158
|
-
|
|
159
|
-
**Load the `build-loop:optimize` skill for the full protocol.**
|
|
160
|
-
|
|
161
|
-
1. **Discover targets**: Run `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/optimize_loop.py --detect --workdir "$PWD"`.
|
|
162
|
-
2. **`simplify` is always available** when code changed: reduces line count in files changed by Execute. Metric = total lines, direction = lower, guard = build passes.
|
|
163
|
-
3. **Other targets** appear when the repo has the right tooling (build script → optimize-build, test runner → optimize-tests, bundler → optimize-bundle).
|
|
164
|
-
4. **Budget**: 3-5 iterations (polish, not deep optimization).
|
|
165
|
-
5. **Post-loop**: dispatch `overfitting-reviewer`. Archive to `.build-loop/optimize/experiments/`.
|
|
166
|
-
|
|
167
|
-
**Skip** when: no mechanical metric, build was trivial (<20 lines), or user opts out. Optimization results feed back into Validate as additional evidence.
|
|
168
|
-
|
|
169
|
-
### Sub-step D: Fact-Check & Mock/Privacy Scan
|
|
170
|
-
|
|
171
|
-
Nothing false, fabricated, or placeholder reaches the user. Three gates, run in parallel. Load `phases/fact-check.md` for detailed guidance.
|
|
172
|
-
|
|
173
|
-
- **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.
|
|
174
|
-
- **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 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`). Flags recurrences against `.navgator/lessons/lessons.json`. For cross-layer changes, escalate to `Skill("build-loop:architecture-review")` for the full integrity review.
|
|
176
|
-
- **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
|
-
- **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
|
-
- **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; in `suggest` mode, Review-F proposes `vA.B.C` (semver inferred from Conventional Commits) and asks for explicit user confirmation before any plugin.json edit. Never auto-bumps. Never blocks. The marker file is the user's release signal; build-loop only ever advises.
|
|
180
|
-
- **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
|
-
- **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
|
-
- **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`.
|
|
183
|
-
|
|
184
|
-
Blocking issues (Gates 1-4) -> route to Iterate; do not halt the run. For Gate 2 privacy findings, the orchestrator invokes the appropriate implementer, auditor, or specialist agent to remediate, then re-runs validation. Prefer `.gitignore` plus untracking for runtime/generated files, archive or private-store relocation over deletion for useful evidence, and redaction/scrubbing over removing useful public documentation. Queue entries (Gates 7-8) -> flow into Phase 5's prioritized work list. Warnings -> include in Report (sub-step G). Auto-bumping is forbidden.
|
|
185
|
-
|
|
186
|
-
### Sub-step E: Simplify (trim the diff)
|
|
187
|
-
|
|
188
|
-
Simplify = remove dead code AND restructure over-complex logic/architecture into clearer, equal-or-better-performing forms; preserve behavior + correctness. Both categories run as the default pass on every build.
|
|
189
|
-
|
|
190
|
-
Run `/simplify` (or load the `simplify` skill directly) against the changed files. The running build-loop subagent reasons over the diff directly and language-agnostically — no external tool required. Focus:
|
|
191
|
-
|
|
192
|
-
**Dead code (remove):**
|
|
193
|
-
- Inline single-use helpers extracted "just in case"
|
|
194
|
-
- Dead branches, commented-out code, unused imports
|
|
195
|
-
- Collapse try/except that catches a thing that can't happen
|
|
196
|
-
- Remove validation for invariants the type system or upstream already guarantees
|
|
197
|
-
- Reduce abstractions that have exactly one call site
|
|
198
|
-
|
|
199
|
-
**Over-complex logic/architecture (restructure — clear wins only):**
|
|
200
|
-
- Deep nesting that flattens without behavioral change (early-return, extracted predicate)
|
|
201
|
-
- Duplicated logic that a single well-named extraction eliminates (DRY)
|
|
202
|
-
- Accidental-quadratic or redundant multi-pass loops where a single-pass equivalent is obvious
|
|
203
|
-
- Needless indirection layers that obscure the data flow without protecting a boundary
|
|
204
|
-
|
|
205
|
-
For changed Python files, `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/complexity_detector.py --changed-files <changed .py files> --json` is a precise accelerator — its ranked hotspot envelope (`high_complexity`, `deep_nesting`, `accidental_quadratic`, `redundant_multipass`, `needless_indirection`) focuses attention on `severity: "high"` candidates. It is diff-scoped, zero-dependency, and non-fatal on unparseable/missing paths. Use it when it applies; reason directly over the diff for all other languages.
|
|
206
|
-
|
|
207
|
-
**Apply vs. advise.** APPLY a restructure only if all hold: (a) it is a clear win (not a lateral rewrite); (b) the existing test subset for the touched files still passes — reuse the Sub-step B Validate machinery on E's changed paths only, not the full gate; (c) public signatures and observable behavior are unchanged. If ambiguous, uncertain-architectural, or fails (b)/(c) → do not apply; emit as an advisory finding via the existing independent-auditor surface (Phase 4 Report `## Notes from judges`). No perf gate, no benchmark, no cost-proxy — equal-or-better performance is an unmeasured bonus, never asserted or gated.
|
|
208
|
-
|
|
209
|
-
Applied edits flow through the existing single-writer Phase 3 commit contract — part of the build's diff, not a side-channel.
|
|
210
|
-
|
|
211
|
-
Preserve: public API surface, test coverage, observability (logging/tracing), documented behavior, and modular boundaries that protect user value, scalability, accuracy, security, testability, or stable interfaces. If an integrated simplification is better, document `MODULARITY EXCEPTION: <reason>`. For **plugin work**: also re-run `plugin-dev/scripts/hook-linter.sh` against any touched `hooks.json` and `grep` the manifest for `../` or bare paths.
|
|
212
|
-
|
|
213
|
-
**Self-recursive builds:** when `selfRecursive.enabled == true` (the build is editing build-loop itself), Sub-step E also consumes `self_review.py`'s `self_simplification[]` findings as an additional hotspot source. Any simplification applied to build-loop's own code from this list MUST pass `python3 scripts/self_mod_verify.py --scope full --auto-revert --json` (`verdict: pass`) before it is committed. A `verdict: fail` auto-reverts the change; it does not route to Iterate — move it to `.build-loop/proposals/needs-human/` instead.
|
|
214
|
-
|
|
215
|
-
**Report.** Log one line: `[Simplify] N hotspots, M applied, K advised`; record applied/advised counts in the Sub-step G report. An applied rewrite that later fails a re-validate routes like any Sub-step B failure (Phase 5 Iterate, existing 5x cap).
|
|
216
|
-
|
|
217
|
-
#### Sub-step E telemetry
|
|
218
|
-
|
|
219
|
-
**Sub-step E telemetry (mandatory, every Review pass, all builds).** After E completes for this Review pass, the orchestrator MUST append one row to `state.json["reviewE"]` via:
|
|
220
|
-
|
|
221
|
-
```python
|
|
222
|
-
update_execution_state(state_path, 'review_e_pass',
|
|
223
|
-
files_scanned=[<files E actually inspected this pass>],
|
|
224
|
-
is_final=<True iff this is the final Review pass>)
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
This is **measurement infrastructure, not a factor** — it is present and identical on every build regardless of any cadence policy. It records *what E did this pass*; it must NOT change *what E does*. `pass_idx` auto-derives from the existing row count (0-based). When a cadence policy scopes E to only iterate-changed files on Review re-entry, the recorded `files_scanned` naturally shrinks on non-first passes — that difference is the signal a deterministic scorer reads. Telemetry write failure is logged, never blocks the build.
|
|
228
|
-
|
|
229
|
-
### Sub-step F: Auto-Resolve (drain non-destructive open items)
|
|
230
|
-
|
|
231
|
-
Drain the candidate auto-resolve queue before writing the final scorecard. Items in the queue come from four sources:
|
|
232
|
-
|
|
233
|
-
- **Sub-step A Critic** — findings with normalized `severity in {medium, low}` AND `suggestion` naming a single `file:line` (canonical independent-auditor finding fields per `agents/independent-auditor.md`; QM v0.13.0 — legacy `minor→medium`, `info→low`)
|
|
234
|
-
- **Sub-step D Fact-Check & Mock Scan** — non-blocking gate findings (e.g. `Plugin Cache Sync` divergence, `Version-Bump Advisor` notes when `release-pending.md` is absent, single-file documentation drift)
|
|
235
|
-
- **Quality / performance findings this run** (C-HEAL / self_heal_safe_issues) — any quality or performance issue surfaced by this run's self-review, fact-check, simplify, or efficiency scan whose fix classifies SAFE. Auto-fix them in-pass; do NOT defer to followup, do NOT surface. RISKY/DECISION findings from this same path still route to `## Held` / report as usual.
|
|
236
|
-
- **Operator queue** — items previously deferred via the `## Held` section of a prior build's report
|
|
237
|
-
|
|
238
|
-
For each item:
|
|
239
|
-
|
|
240
|
-
1. Build a short `<label>` and the corresponding shell `<command>` describing the action.
|
|
241
|
-
2. Invoke `python3 scripts/autonomy_gate.py --workdir "$PWD" --action "<label>" --command "<command>" --json` (single source of truth — see `references/autonomy-config.md`).
|
|
242
|
-
3. Route on the verdict:
|
|
243
|
-
- `auto` (exit 0) → execute the action via the appropriate implementer/script and record the result in `## Done` for Report.
|
|
244
|
-
- `warn` (exit 0) → execute the action (does not block), record in `## Done` with `[warn] <reason>` prefix, and emit a one-line entry to `state.json.runs[].autonomyEvents[]` for match-rate tracking. See `references/autonomy-config.md` §"Warn-before-block workflow" for the autonomyEvents shape.
|
|
245
|
-
- `confirm` (exit 1) → record in `## Held` with the `reason` field from the gate's envelope verbatim. Do NOT prompt the operator inline.
|
|
246
|
-
- `block` (exit 2) → record in `## Blocked` with the same reason field.
|
|
247
|
-
|
|
248
|
-
Cap auto-execute attempts per item at the existing Iterate ceiling (5x). After the cap, demote to `## Held` with reason `"auto-resolve cap reached after N attempts"`.
|
|
249
|
-
|
|
250
|
-
**What does NOT belong in Auto-Resolve:**
|
|
251
|
-
- Strong-checkpoint findings from Sub-step A — a `nay` routes back to Execute (no iteration counter burn).
|
|
252
|
-
- Sub-step B Validate failures — those route to Phase 5 Iterate.
|
|
253
|
-
- Anything matching deployment_policy.py heuristics — autonomy_gate delegates to deployment_policy automatically; the verdict still flows through `auto | confirm | block`, but the source-of-truth is deployment_policy for those items.
|
|
254
|
-
|
|
255
|
-
The auto-resolve queue is rebuilt from scratch per Phase 4 invocation. Items not drained on a given pass don't carry forward unless explicitly re-surfaced by Sub-steps A/D on the next pass.
|
|
256
|
-
|
|
257
|
-
### Sub-step G: Report (only on final Review pass)
|
|
258
|
-
|
|
259
|
-
Runs only when all prior sub-steps pass OR when iteration cap is hit. Writes final artifacts and closes the build.
|
|
260
|
-
|
|
261
|
-
**No-critical/high exit gate (QM v0.13.0 Piece 3, BLOCKING).** Before this final pass may report `pass`, collect every reviewer findings JSON produced this run (independent-auditor + security-reviewer) and run `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/review_finding_gate.py --findings-json <each.json> --json`. It normalizes legacy (`major→high`, `minor→medium`, `info→low`; security `CRITICAL|HIGH|MEDIUM|LOW` case-insensitively; ambiguous→`high`) and returns `{pass, blocking_count, ...}`, exit 1 when any `critical`/`high` finding is open (not `closed` + `closure_proof`). **Exit 1 → the final pass is blocked; route the blocking findings to Phase 5 Iterate** (the fixed 5-iteration cap cannot finalize with an open critical/high). Exit 0 → proceed. Medium/low never block here — they route through the ux-queue/followup with explicit disposition; they are never silently skipped.
|
|
262
|
-
|
|
263
|
-
**Judgment-dispatch gate (BLOCKING on stakes-gated runs).** The advisor/auditor ladders RECORD which rung fired but nothing ENFORCED it, so an inline run (skill-as-methodology, no orchestrator dispatch) silently sat at the inline-Opus floor and the Frontier judgment never happened (observed: agent-rally-point v0.1.2 ran 16 commits with 0 Fable dispatches until the user asked why). Before this final pass may report `pass`, run `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/judgment_gate.py --workdir "$PWD" --run-id <this run> --agent-tool-available <true|false> --json`. Pass `--run-id` so stakes/statuses/ledger are scoped to THIS run only (never a stale top-level trigger or a prior run's ledger row — the gate reads stakes from the run record); omit it to default to the latest `runs[]` entry. Pass `--agent-tool-available false` only for a nested orchestrator / no-Agent-tool context. Stakes-conditional (mirrors the ladders): no stakes trigger → `pass`; stakes fired + `auditor_status`/`advisor_status` shows a real Frontier/peer dispatch → `pass`; stakes fired + the inline floor (`fallback:inline-opus` / `not-run:parent-must-dispatch` / unrecorded) with the Agent tool reachable → **exit 1, `fail`**. **Exit 1 → the run is NOT review-complete: dispatch the independent-auditor (and, for a stakes-gated Phase 2, the advisor) to Frontier, then re-run.** Also fails on an `agent-ledger.jsonl` `verify`/`author` action recorded at a non-frontier tier. This closes the inline-substitution hole — the same class as the inline self-audit masquerading as the independent auditor.
|
|
264
|
-
|
|
265
|
-
Final report sections, in this order:
|
|
266
|
-
|
|
267
|
-
- `## 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
|
-
- `## 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
|
-
- `## Blocked` — items Auto-Resolve verdicted as `block`, same shape as Held.
|
|
270
|
-
- `## Status markers` — ✅ Known / ⚠️ Untested / ❓ Unfixed (existing convention; keep this section).
|
|
271
|
-
|
|
272
|
-
Research citation gate: before emitting, read
|
|
273
|
-
`.build-loop/state.json.researchGate`. When `blocks_final_claims: true`, every
|
|
274
|
-
current/external/API/package claim in the report must cite the research packet
|
|
275
|
-
or explicitly say the evidence was unavailable and the claim is unverified. If
|
|
276
|
-
`packet_path` is non-null, add a compact `research_packet:` evidence item to
|
|
277
|
-
`## Done` or `## Status markers`.
|
|
278
|
-
|
|
279
|
-
Reference-capture report field (mirrors the researchGate citation contract):
|
|
280
|
-
every run reports one `references captured:` line in `## Done` or `## Status
|
|
281
|
-
markers` — `references captured: N (<files>)` when one or more external fetches
|
|
282
|
-
informed a decision and were captured via the canonical writer, `none — no
|
|
283
|
-
external fetch informed a decision` when no web/doc fetch fed a decision, or
|
|
284
|
-
`skipped: <rationale>` when a fetch informed a decision but capture was
|
|
285
|
-
intentionally not run. This makes the default-on capture trigger
|
|
286
|
-
(`references/research-trigger-policy.md` §"Reference Capture") accountable in the
|
|
287
|
-
run report instead of advisory-only.
|
|
288
|
-
|
|
289
|
-
Before emitting the final report, write the draft to a temp file and run BOTH linters (orthogonal — structural vs style):
|
|
290
|
-
|
|
291
|
-
```bash
|
|
292
|
-
python3 scripts/build_report_lint.py <draft.md> --json # structural: parallel_batch, merge_plan, evidence triplets
|
|
293
|
-
python3 scripts/report_lint.py <draft.md> --json # style: headline shape, validation line, jargon, contrastive pivot, length
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
Structural lint (`build_report_lint.py`):
|
|
297
|
-
|
|
298
|
-
- Exit 0 → emit the report.
|
|
299
|
-
- Exit 1 → revise the report before emitting it. The linter blocks vague verified/known claims, missing `parallel_batch` / `parallel_skipped_reason`, and missing `merge_plan` fields.
|
|
300
|
-
- Exit 2 → lint outage. Record `[warn] build-report-lint skipped (<reason>)` in `## Done` and continue.
|
|
301
|
-
|
|
302
|
-
Style lint (`report_lint.py`) — WARN with self-heal, never a hard halt. The user has asked for enforced concise, no-jargon user-facing output (`skills/build-loop/references/output-style.md` is the contract):
|
|
303
|
-
|
|
304
|
-
- `summary.total == 0` → emit the report.
|
|
305
|
-
- `summary.total > 0` → auto-revise the draft ONCE to clear the findings (translate jargon to plain language per the contract's blocklist, rewrite a missing headline as a one-sentence statement of what changed, add a validation line naming the exact command/method that verified the work, remove contrastive-pivot constructions), then re-run the lint. If a second pass still has findings, emit the report with a `[warn] report-lint findings remain after one revise pass` line in `## Done` and continue. Never block on style.
|
|
306
|
-
- Outcome framing AND precision-and-brevity are part of this same self-heal pass (the lint does NOT grade either — both are judgment, not pattern): if the headline or first substance line leads with the feature/mechanism rather than the user outcome, rewrite it outcome-first per `output-style.md` §"Outcome framing"; and apply `output-style.md` §"Precision and Brevity — sentence architecture" (actor+strong-verb+outcome spine, concrete nouns/verbs, data over adjectives/adverbs, direct cause→effect with `because`/`suggesting`, no invented numbers) to the prose while rewriting. No extra pass and no new lint — fold both into the one revise pass above; a fuzzy "shorter words / causal pattern" check would over-block and is deliberately not added.
|
|
307
|
-
- Script error / file not found → record `[warn] report-lint skipped (<reason>)` in `## Done` and continue.
|
|
308
|
-
|
|
309
|
-
The two lints are orthogonal: structural rules live in `build_report_lint.py`, style/jargon rules live in `report_lint.py`. Neither replaces the other. The lints target ONLY the final user-facing report markdown; internal envelopes between agents stay structured/jargon-ok.
|
|
310
|
-
|
|
311
|
-
Evidence contract: each verified/known claim carries its evidence in the compact form `✅ <claim> [<method> → <artifact>]` (e.g. `✅ auth works [pytest → ci.log]`); `@<observer>` only when the observer isn't this run's orchestrator. One line per claim — no restated context or process narration. Multi-chunk or parallel reports must include `merge_plan:` with `clean_against`, `conflicts_with`, and `suggested_order`.
|
|
312
|
-
|
|
313
|
-
**Forbidden in the report**:
|
|
314
|
-
- Recommendation-list headers (e.g. headers that invite operator selection of which items to execute)
|
|
315
|
-
- "Next Action" sentences that read like questions
|
|
316
|
-
- Any bullet phrased as `Want me to X?` or `Should I Y?`
|
|
317
|
-
- Any list that presents items as choices for the operator to pick from
|
|
318
|
-
|
|
319
|
-
If a category is empty (no Held items, no Blocked items), omit the section entirely — no header, no `_(none)_` placeholder. A reader infers "none" from absence.
|
|
320
|
-
|
|
321
|
-
Write scorecard to `.build-loop/evals/YYYY-MM-DD-<topic>-scorecard.md`.
|
|
322
|
-
|
|
323
|
-
**Debugger store + outcome**: for each resolved Review-B/Iterate failure, write a native `.build-loop/issues/<incident>.md` incident note with `{symptom, root_cause, fix, tags, files}`. If `availablePlugins.codingDebugger` is true and the run explicitly requested cross-project memory, mirror the same outcome to standalone Coding Debugger. Both sides of the memory feedback loop — local store and outcome status — are required for learning.
|
|
324
|
-
|
|
325
|
-
**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
|
-
|
|
327
|
-
**Deployment policy gate** (before any push/deploy): run:
|
|
328
|
-
|
|
329
|
-
```bash
|
|
330
|
-
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/deployment_policy.py" \
|
|
331
|
-
--workdir "$PWD" \
|
|
332
|
-
--command "$CANDIDATE_DEPLOY_COMMAND"
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
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
|
-
|
|
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 `~/dev/git-folder/`, `~/.claude/plugins/marketplaces/`) entry referencing this plugin; commit `chore(version): bump <plugin-name> to <new-version>`. No minor/major bumps; no bumps for docs-only diffs.
|
|
338
|
-
|
|
339
|
-
**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
|
-
|
|
341
|
-
**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.
|