@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
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
|
|
11
11
|
Entered when Review sub-step A, B, or D finds blocking issues OR `.build-loop/ux-queue/` is non-empty. Critic-only failures (strong-checkpoint from A without touching B) route to Execute instead — no iteration counter burn.
|
|
12
12
|
|
|
13
|
+
**Bounded admission at first entry.** Snapshot pre-existing, intent-aligned queue
|
|
14
|
+
work once with `python3 scripts/autonomy_supervisor.py --workdir "$PWD" snapshot
|
|
15
|
+
--goal "<intent>" --limit <configured-or-12>`. Schedule only paths in
|
|
16
|
+
`.build-loop/autonomy/queue-manifest.json`; later queue arrivals wait for the
|
|
17
|
+
next manifest. An issue discovered while executing the current work is handled
|
|
18
|
+
separately: run `classify-related` and execute it in this run when the verdict is
|
|
19
|
+
`execute` (intent-aligned, inside the repo, reversible, and deterministically
|
|
20
|
+
testable). `followup` writes a durable item. `decision` names why the owner is
|
|
21
|
+
needed, available choices, and owner/app/user/other impact.
|
|
22
|
+
|
|
13
23
|
**Iterate input contract (prioritized work list)**:
|
|
14
24
|
|
|
15
25
|
| Priority | Source | Notes |
|
|
@@ -23,25 +33,61 @@ Entered when Review sub-step A, B, or D finds blocking issues OR `.build-loop/ux
|
|
|
23
33
|
|
|
24
34
|
The "code is cheap, AI agents build fast" framing: the orchestrator does NOT defer based on patch size. It defers only when `architecture_impact: true` (new component, new data flow, navigation graph change, schema migration, auth provider swap). Everything else is fair game for the current loop.
|
|
25
35
|
|
|
36
|
+
## Premise re-validation gate (MANDATORY before scheduling any queue item)
|
|
37
|
+
|
|
38
|
+
A queue item is written at one moment and executed at another. By the time it surfaces, the bug may be fixed, the file moved, or the precondition false. Before scheduling any item drained from `.build-loop/queue/`, `.build-loop/issues/`, `.build-loop/ux-queue/`, or `.build-loop/followup/`:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
python3 "${CLAUDE_PLUGIN_ROOT:-.}/scripts/premise_revalidation.py" gate --item <path> --repo "$PWD" --json
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Exit 0 = `fresh`, schedule it. Exit 1 = do not schedule; route by `reason_code`:
|
|
45
|
+
|
|
46
|
+
| Verdict | Meaning | Route |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `fresh` | Within the window, or re-validated with evidence | Schedule |
|
|
49
|
+
| `stale_needs_revalidation` | Past the window (default 7d), never re-checked | Re-check the premise against the live repo, then `validate --note "<what you checked>"`; if it has resolved, close the item with that receipt |
|
|
50
|
+
| `premise_broken` | A cited path or commit the item depends on is genuinely gone | Close the item with the receipt; do not implement |
|
|
51
|
+
| `needs_human_recheck` | A cited path **relocated** (same basename elsewhere), or extraction was ambiguous | Re-read the item against the new path before acting |
|
|
52
|
+
|
|
53
|
+
Freshness falls back to `created` when `validated` is absent, so an item filed minutes ago is fresh by construction — the gate cannot deadlock a queue fed by the current run. Stamp freshness only through:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
python3 "${CLAUDE_PLUGIN_ROOT:-.}/scripts/premise_revalidation.py" validate --item <path> --note "<evidence>"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`--note` is required. A bare timestamp asserts freshness without evidence, which is the failure being fixed.
|
|
60
|
+
|
|
61
|
+
**Why `needs_human_recheck` is a separate verdict from `premise_broken`.** 2026-08-07: a sweep of 67 queue cards found 16 (24%) whose premise had already resolved — one claimed 65 commits were stranded by a push blocker that had cleared two days earlier. Several card specs even carried hand-written *"VALIDATE FIRST (mandatory) … if stale, write a receipt and STOP"* prose, which proves the need was known and unautomated. The sharper finding: **the careful human sweep was itself stale** — it reported a file as deleted when the file had been relocated, and a repo as 0 ahead when it was 6. A missing path is therefore never enough to declare a premise dead; the gate checks for a same-basename relocation first and asks for a human re-read instead of concluding. Staleness is also repo-dependent (one repo measured 4/4 stale, another 12 live to 1 stale), so the gate is per-item, never a blanket policy.
|
|
62
|
+
|
|
63
|
+
Mirrors the Operations Center design (`validated_at` + refusal at the same gate that already refuses an unrunnable card, commit `3fd0a23`) rather than reinventing it.
|
|
64
|
+
|
|
26
65
|
**Fan-out** (mode-dependent): After dequeue, partition entries by `files_touched` into independent groups (no overlapping files).
|
|
27
66
|
|
|
67
|
+
Before each fan-out and after a provider/worker error, run
|
|
68
|
+
`autonomy_supervisor.py backpressure --signals '<json>'`. Feed available 429
|
|
69
|
+
count, memory percentage, free disk, thermal state, error streak, cost use and
|
|
70
|
+
ceiling, current concurrency, and stable-window count. Obey `pause_new_work`,
|
|
71
|
+
`reduce_concurrency`, `steady`, or `recover_one`; finish in-flight chunks before
|
|
72
|
+
reducing admission. Missing signals retain current concurrency.
|
|
73
|
+
|
|
28
74
|
- **Top-level mode** (orchestrator invoked directly via the user's session): dispatch up to 4 `implementer` subagents in parallel via `Agent(subagent_type="build-loop:implementer", ...)` per the bundled `agents/implementer.md` (Sonnet 5, scoped tools=[Read, Write, Edit, Bash, Glob, Grep]). Hard cap from `~/.claude/CLAUDE.md` §Sub-Agents. Sequential groups process after the parallel batch.
|
|
29
75
|
- **Subagent mode** (orchestrator was itself spawned via `Agent(...)` so the no-sub-sub-agents rule applies): degrade to **inline-implementer mode** — iterate the queue serially, apply each fix following the implementer's protocol (scope to `files_touched`, refuse `architecture_impact: true`, verify locally before declaring fixed). No parallelism, same quality bar. The orchestrator surfaces the degradation in Review-F.
|
|
30
76
|
|
|
31
77
|
In both modes, each pass returns the same structured outcome (status + files_changed + verifications). Status routing covers all 9 implementer return values:
|
|
32
78
|
- `fixed` → mark done (delete the .md)
|
|
33
79
|
- `partial` → keep entry, re-pass next iteration
|
|
34
|
-
- `scope_breach` →
|
|
80
|
+
- `scope_breach` → re-plan automatically when the added files remain inside the authorized repo and resolve to the current intent; otherwise route through `classify-related`
|
|
35
81
|
- `deferred_architecture` → Review-F surfaces for explicit user confirmation
|
|
36
82
|
- `evidence_stale` → regenerate via `ux_triage.py --clear`, then re-pass
|
|
37
83
|
- `plan_malformed` → same as `evidence_stale` (regenerate); log id to `.build-loop/state.json.malformedPlans[]`
|
|
38
|
-
- `needs_dependency` →
|
|
39
|
-
- `failed` → re-pass with implementer's `notes` as `additional_context`; after 2 attempts escalate
|
|
84
|
+
- `needs_dependency` → classify the concrete dependency change with `classify_action.py`; SAFE/RISKY follows its normal branch route, while DECISION/PRODUCTION surfaces with impact
|
|
85
|
+
- `failed` → re-pass with implementer's `notes` as `additional_context`; after 2 attempts escalate per `model-tiering`; after 3 identical verdicts quarantine and continue
|
|
40
86
|
- `concurrent_modification_detected` → abort current parallel batch (orchestrator partition bug; never transient)
|
|
41
87
|
|
|
42
88
|
Results re-enter Sub-step B for re-validation. For Validate failures (no queue entry), construct an inline plan in the same shape and treat identically.
|
|
43
89
|
|
|
44
|
-
**UI re-validate hook (when uiTarget != null)**: After each implementer subagent reports back AND before re-entering Sub-step B Validate,
|
|
90
|
+
**UI re-validate hook (when uiTarget != null)**: After each implementer subagent reports back AND before re-entering Sub-step B Validate, invoke headless IBR for affected renderable surfaces when installed, following `../../../references/ibr-ui-verification-policy.md`. Run `ui-validator` in parallel for web, with native AX or simulator/browser evidence as the fallback. If no renderable surface can be resolved, record the gap and fall back to `audit-design-rules.mjs`.
|
|
45
91
|
|
|
46
92
|
**Infra self-heal before counting an attempt (C-HEAL / self_heal_safe_issues).** When an Iterate attempt's own tooling, hook, or Bash command FAILS (infra error — non-zero exit that is not a graded-criterion failure, e.g. a pre-commit hook crash, a lint runner that throws on a binary file, a script that errors on a missing env var): ROOT-CAUSE and FIX that infra error first. Classify via `scripts/classify_action.py`. SAFE → apply, verify (re-run the failed action), commit, then resume the Iterate attempt. RISKY/DECISION/PRODUCTION → isolate/surface per the normal routing table. An infra self-heal does NOT burn the iterate budget; only a graded-criterion failure (test/lint/validate failure against the rubric) burns a count. This prevents `--no-verify` bypasses and other workarounds from masking fixable infra errors.
|
|
47
93
|
|
|
@@ -53,17 +99,39 @@ Per attempt:
|
|
|
53
99
|
- **2 consecutive same-root-cause failures** → parallel multi-domain assessment via `build-loop:debugging-memory` `{op:"assess"}`. Pass `model: sonnet` to domain assessors explicitly (override `inherit` default to prevent 4× Opus fan-out from the Opus 4.7 orchestrator). The full procedure is documented in `skills/debug-loop/SKILL.md` §"If stuck — parallel multi-domain assessment".
|
|
54
100
|
- **3 consecutive same-criterion failures** → causal-tree investigation via `Skill("build-loop:debug-loop")`. Runs its own 7-phase cycle internally; returns with fix applied or hard-stop.
|
|
55
101
|
3. **Build the prioritized work list** from the table above (Validate failures + UX queue).
|
|
56
|
-
4. **Partition for parallel fan-out**: group by disjoint `files_touched`;
|
|
102
|
+
4. **Partition for parallel fan-out**: group by disjoint `files_touched`; use `autonomy_supervisor.py fanout` for the binding dynamic admission count. The absolute ceiling is 150, while independent work, shared capacity, provider errors, cost, memory, disk, load, latency, and measured thermal stability normally set a lower limit.
|
|
57
103
|
5. **Execute fixes**; for UI files, run the UI re-validate hook before continuing.
|
|
58
104
|
6. **Loop back to Review sub-step B** (Validate). Sub-step A (Critic) usually skipped on re-runs unless the fix touched new files. Sub-steps C-F run only on final pass.
|
|
105
|
+
- When the completed queue file has `source: autonomy-dashboard`, read its
|
|
106
|
+
`dashboard_gap_id` and record the validated completion before advancing:
|
|
107
|
+
`python3 scripts/autonomy_dashboard.py --workdir "$PWD" --complete
|
|
108
|
+
"<dashboard_gap_id>" --summary "<what changed>" --evidence
|
|
109
|
+
"commit:<sha>; tests:<result>; audit:<verdict>"`. This moves the file out
|
|
110
|
+
of the executable follow-up queue and makes the dashboard show `Applied`.
|
|
59
111
|
7. **Followup overflow**: when the iteration cap (5) is reached and queue entries remain, write them to `.build-loop/followup/<topic>.md` for a subsequent `/build-loop:run` invocation. Plan content is already complete — the followup build skips its own Plan phase for these entries.
|
|
60
112
|
- **`judgment-owed-<run-id>.md`** entries (written by `stop_closeout` when a stakes-gated inline run closed at the inline floor) mean: **dispatch the owed verification layer(s) named in the file for that run** (the Frontier auditor/advisor it skipped), then the file is cleared automatically on the next passing Stop. Do not treat it as a code work-item — it is a dispatch-the-judgment debt.
|
|
61
113
|
8. **Track**: attempt count, what failed, what was attempted, what changed, queue depth before/after each pass.
|
|
62
114
|
|
|
115
|
+
After every item outcome, enforce the per-item limit:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
python3 scripts/autonomy_supervisor.py --workdir "$PWD" verdict \
|
|
119
|
+
--item "<stable-item-id>" --verdict "<verdict>" --limit 5 --audit-at 3 \
|
|
120
|
+
--actor-id "<worker-id>" --actor-session "<worker-session-id>"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`action: independent_audit` dispatches a different worker/session. The orchestrator first
|
|
124
|
+
records the returned `verify` action in the current run's agent ledger with
|
|
125
|
+
`refs.item_id` and `refs.session_id`, then records its evidence with
|
|
126
|
+
`autonomy_supervisor.py audit --item <stable-item-id> --evidence <evidence>
|
|
127
|
+
--auditor-id <auditor-id> --auditor-session <auditor-session-id>`. Only then may the
|
|
128
|
+
fourth attempt start. `action: quarantine` moves the item to follow-up with all five
|
|
129
|
+
verdict receipts and continues the manifest. A resolved verdict resets the counter.
|
|
130
|
+
|
|
63
131
|
**Convergence detection**:
|
|
64
|
-
- Same criterion fails 2x with same root cause →
|
|
65
|
-
- Fix A breaks criterion B (oscillation) →
|
|
66
|
-
- 3+ criteria fail simultaneously after a fix → systemic issue,
|
|
132
|
+
- Same criterion fails 2x with the same root cause → invoke the causal-tree re-plan; the third identical unresolved verdict requires an independent audit, and the fifth quarantines the item
|
|
133
|
+
- Fix A breaks criterion B (oscillation) → revert the weaker reversible fix, re-plan once, then quarantine on recurrence
|
|
134
|
+
- 3+ criteria fail simultaneously after a fix → treat as one systemic issue, re-plan from the shared cause, and continue unaffected manifest items
|
|
67
135
|
|
|
68
136
|
**Stop condition (QM v0.13.0 — severity-aware, replaces the blunt 5-cap for critical/high)**. The 5-iteration cap still bounds the loop, but it **cannot finalize with an open `critical` or `high` finding** (the no-critical/high exit gate in Review-G, `review_finding_gate.py`, blocks the final pass). On reaching the cap:
|
|
69
137
|
- **Open `critical`/`high` remain** → do NOT silently ship as ❓ Unfixed. Escalate to the user with the blocking findings and their `closure_proof` gaps; the build does not pass until they close or the user explicitly waives. (If the same approach keeps failing, re-plan instead of burning more iterations.)
|
|
@@ -6,30 +6,21 @@
|
|
|
6
6
|
|
|
7
7
|
## Phase 6: Learn — Cross-Build Pattern Detection (mandatory; always runs and always reports)
|
|
8
8
|
|
|
9
|
+
**One executable path:** `python3 scripts/learn/__main__.py run --workdir "$PWD" --run-id <recorded-run-id> --source review-g --json`. It writes `.build-loop/learn/<run-id>.json`, updates `runs[].learn`, and returns durable `work_orders[]` for agent-only drafting/review. Dispatch those roles and attach results with the CLI's `attest` command. `status: complete` is the only completed Phase 6 state.
|
|
10
|
+
|
|
9
11
|
**Goal**: detect recurring patterns across recent runs, auto-draft experimental skills/agents to address them, surface them for keep/remove decisions. Closes the loop between "build N times" and "build N+1 is faster because we learned."
|
|
10
12
|
|
|
11
13
|
**Load the `build-loop:self-improve` skill for the full protocol.** (Skill keeps its existing name for backward compatibility; this phase was named "Self-Improvement Review" in v0.2.0 — renamed here to avoid collision with Phase 4 Review.)
|
|
12
14
|
|
|
13
|
-
**Mandatory contract (v0.
|
|
15
|
+
**Mandatory contract (v0.39.0+).** Every Phase 6 runs the deterministic detector and consolidation stages, persists their receipt, and emits its `learn_line` in Review-G. This path uses no LLM when nothing crosses threshold. Sonnet drafting and promotion review stay conditional and appear as explicit work orders. Also user-invokable via `/build-loop:self-improve` after recording a manual run id.
|
|
14
16
|
|
|
15
17
|
Quick flow:
|
|
16
18
|
|
|
17
|
-
1. **
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
4. **Signoff** — orchestrator (Opus 4.7) reviews each draft: APPROVE / REVISE (1 retry) / DISCARD.
|
|
23
|
-
5. **Sample review sweep** — for artifacts in `.build-loop/skills/experimental/` from prior runs: if `.build-loop/config.json.autoPromote` is true AND effective (non-confounded) sample ≥ 8 AND target met → eligible for promotion. **Promotion is no longer silent.** Each eligible candidate goes through (a) advisory review by `promotion-reviewer` (Opus, agent), (b) async user confirmation via PushNotification + TaskCreate fallback. The reviewer's variance verdict (approve / rethink / new_approach) becomes the body of the notification. Move from `experimental/` to `active/` happens only after the user confirms via `/build-loop:promote-experiment <name>`. Regressions and inconclusive-at-2N write proposals to `.build-loop/proposals/` for user confirmation — never auto-delete.
|
|
24
|
-
|
|
25
|
-
**Promotion-reviewer dispatch protocol** (per advisory-judge design, plan §12 / `agents/promotion-reviewer.md`):
|
|
26
|
-
- For each eligible candidate, dispatch `Agent(subagent_type="build-loop:promotion-reviewer", ...)` with brief fields: `artifact_path`, `experiment_log`, `sample_size`, `target_metric`, `triggering_run_id`, `recent_judge_decisions`.
|
|
27
|
-
- Append the returned verdict object to the run's `judge_decisions[]` via `python3 ${CLAUDE_PLUGIN_ROOT}/scripts/write_run_entry/__main__.py --judge-decisions-json <verdict.json>` (combined with other Phase 4 verdicts if any).
|
|
28
|
-
- Compose the user-facing notification body from the verdict's `variances[]` and `meta_guidance`. Fire `PushNotification` if available; fall back to `TaskCreate` with subject `"[BUILD-LOOP] Promotion candidate <name>: <verdict> — review needed"`.
|
|
29
|
-
- Write a marker file at `.build-loop/proposals/<name>.pending.md` with the verdict + how-to-confirm so the user can resume context later (TTL 14 days; lapsed candidates auto-archive to `.build-loop/proposals/<name>.lapsed.md`).
|
|
30
|
-
- **Do not move the artifact.** The user-invoked `/build-loop:promote-experiment <name>` command performs the move after reading the pending verdict.
|
|
31
|
-
|
|
32
|
-
6. **Notify** — concise synthesis appended to Review sub-step G report, including: (a) removal command for each artifact moved or proposed, (b) for each pending promotion: the reviewer verdict + confirmation command.
|
|
19
|
+
1. **Run** — the executable runner reads four bounded sources: `runs[]`, retro enforce-candidates, learning objects, and tool traces. It consolidates memory, detects and deduplicates patterns, caps new work at two, and performs the sample sweep.
|
|
20
|
+
2. **Read** — no patterns means no agent dispatch. Agent-only work appears in `work_orders[]` with the exact role and payload.
|
|
21
|
+
3. **Dispatch** — call only returned roles. Architects draft experimental skills or agents. Implementers realize enforcement specifications. Promotion reviewers judge drafted or sample-eligible artifacts.
|
|
22
|
+
4. **Attest** — attach repository-relative artifacts and reviewer verdicts with the CLI. Pending or failed work keeps Phase 6 open.
|
|
23
|
+
5. **Close** — emit `learn_line`, enforce `run_close_lint.py --require-learn`, and leave promotion to explicit `/build-loop:promote-experiment` confirmation.
|
|
33
24
|
|
|
34
25
|
**Always-run + report gating (v0.30.0)**
|
|
35
26
|
|
|
@@ -52,6 +43,8 @@ Phase 6 has NO "skip entirely" condition. Three outcome states cover every run:
|
|
|
52
43
|
|
|
53
44
|
- Consumer default — learned drafts route to `~/.build-loop-extensions/pending/` via `scripts/extensions_route.py --name <ext-slug> --file <draft>`; they do not load until `scripts/extensions_approve.py` moves them into `plugin/`. (Maintainer routing: P2.)
|
|
54
45
|
|
|
46
|
+
**Retrospective finding capture — ownership (2026-08-29).** build-loop is the DEFAULT owner of the retrospective-finding-filing flow (`scripts/retrospective/file_findings.py`; see `AGENTS.md` §"Retrospective finding capture" for the exact `plan`/`apply`/`lint` commands and filing ladder). The `ai-assistant` and `ambient agent` projects may also invoke or guide this same flow, but only through those same `file_findings.py` commands — never a parallel reimplementation. This pointer lives in build-loop's own docs only: `ai-assistant` and `ambient agent` are NOT edited by this change.
|
|
47
|
+
|
|
55
48
|
**What this phase will NOT do**:
|
|
56
49
|
- Modify the build-loop plugin repo
|
|
57
50
|
- Promote artifacts cross-project without explicit `/build-loop:promote-experiment <name>`
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
<!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
|
|
2
|
+
|
|
3
|
+
# Privileged-request broker — naming, coalescing, and recording admin prompts
|
|
4
|
+
|
|
5
|
+
Load this when a build touches a command that asks macOS for an administrator
|
|
6
|
+
password, when a user reports unexplained password dialogs, or when changing
|
|
7
|
+
`scripts/privileged_commands.json`.
|
|
8
|
+
|
|
9
|
+
Scope: RUNTIME privileged requests across concurrent agent tasks. The separate
|
|
10
|
+
background-item identity work — giving persistent login items recognizable names
|
|
11
|
+
— is a different problem and is untouched here.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## The incident this exists for
|
|
16
|
+
|
|
17
|
+
**2026-08-20, 01:29:11 and 01:29:25 PDT.** A Codex task ran `sfltool dumpbtm`
|
|
18
|
+
twice. macOS showed two administrator-password dialogs naming only `sfltool` —
|
|
19
|
+
no app, no repository, no reason. Parent chain: ChatGPT/Codex → zsh → sfltool.
|
|
20
|
+
|
|
21
|
+
Evidence, from `~/.codex/sessions/2026/08/20/`:
|
|
22
|
+
|
|
23
|
+
| Session | UTC | Command |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| `01a01e31` | 08:04:07 | `sfltool dumpbtm` (bare, inside a 4-way `Promise.all`) |
|
|
26
|
+
| `01a01e46` | 08:29:11 | `sfltool dumpbtm 2>/dev/null \| rg -n -C 2 '…' \| sed -n '1,260p'` |
|
|
27
|
+
| `01a01e46` | 08:29:25 | `set -o pipefail`⏎`sfltool dumpbtm \| sed -n '1,120p'`⏎`rc=$?` |
|
|
28
|
+
| `01a01e4b` | 08:30:59 | probing where `sfltool` lives (no `dumpbtm`) |
|
|
29
|
+
|
|
30
|
+
The 08:29 pair share a session AND a `turn_id`. Both returned **empty output**
|
|
31
|
+
after 10.6 s and 30.6 s of wall clock — the time the dialog sat on screen.
|
|
32
|
+
|
|
33
|
+
### Three separable faults
|
|
34
|
+
|
|
35
|
+
**1 — Anonymity.** `sfltool dumpbtm` requires root and is **undocumented**:
|
|
36
|
+
`sfltool(1)` describes only `sfltool archive`. macOS names the leaf binary in the
|
|
37
|
+
dialog and nothing else, so the user could not tell which of several concurrent
|
|
38
|
+
agent tasks was asking, or why.
|
|
39
|
+
|
|
40
|
+
**2 — A failure shaped like a result.** A refused privileged read returns empty
|
|
41
|
+
stdout, which is indistinguishable from "the grep matched nothing". The agent
|
|
42
|
+
could not tell denial from no-results, so it retried 14 seconds later with a
|
|
43
|
+
different wrapper (`set -o pipefail`, `rc=$?`) purely to get diagnostics. **The
|
|
44
|
+
retry was rational.** The second dialog was caused by the first one's outcome
|
|
45
|
+
being unreadable, not by carelessness.
|
|
46
|
+
|
|
47
|
+
**3 — No shared broker.** Three sessions reached for the same host fact inside
|
|
48
|
+
27 minutes. Nothing coalesced them, named them, or recorded that a prompt
|
|
49
|
+
occurred.
|
|
50
|
+
|
|
51
|
+
### Baseline, measured
|
|
52
|
+
|
|
53
|
+
`python3 scripts/privileged_audit.py report` over 4,169 transcript files:
|
|
54
|
+
|
|
55
|
+
| metric | before | projected |
|
|
56
|
+
|---|---:|---:|
|
|
57
|
+
| privileged invocations | 13 | 13 |
|
|
58
|
+
| OS prompts | 10 | 7 |
|
|
59
|
+
| coalesced | 0 | 3 |
|
|
60
|
+
| retries | 1 | 0 |
|
|
61
|
+
| unattributed | 13 | 0 |
|
|
62
|
+
| distinct requests | 6 | 6 |
|
|
63
|
+
|
|
64
|
+
`projected` replays the same observed trace through the coalescing rules. It is a
|
|
65
|
+
counterfactual on real input, not a measurement; the measured column fills in from
|
|
66
|
+
the broker's own ledger as traffic routes through it.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## What was built
|
|
71
|
+
|
|
72
|
+
| Piece | File | Job |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| Registry | `scripts/privileged_commands.json` | Which commands are privileged, their scope, mutability, TTL. Data, not code. |
|
|
75
|
+
| Coordinator | `scripts/privileged_broker.py` | Attribution, single-flight, TTL cache, state machine, hash-chained ledger. |
|
|
76
|
+
| Forensics | `scripts/privileged_audit.py` | Read-only. Reconstructs the baseline from transcripts; before/after counts. |
|
|
77
|
+
| Enforcement | `scripts/hooks/pre_bash_privileged.py` | PreToolUse:Bash gate. Redirects a raw privileged command to the broker. |
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Using it
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# What in this command needs root?
|
|
85
|
+
python3 scripts/privileged_broker.py classify --command "sfltool dumpbtm | head" --json
|
|
86
|
+
|
|
87
|
+
# Run it through the coordinator. --purpose is MANDATORY.
|
|
88
|
+
python3 scripts/privileged_broker.py request \
|
|
89
|
+
--purpose "enumerate background-task items to name unlabeled login items" \
|
|
90
|
+
--task-id "$RUN_ID" --repo "$PWD" --initiating-app "Claude Code" \
|
|
91
|
+
--argv sfltool dumpbtm
|
|
92
|
+
|
|
93
|
+
# What is in flight, what is cached, is the ledger intact?
|
|
94
|
+
python3 scripts/privileged_broker.py status --json
|
|
95
|
+
python3 scripts/privileged_broker.py verify-ledger --json
|
|
96
|
+
|
|
97
|
+
# Cancelled a dialog and now want to allow it? Drop the cached answer.
|
|
98
|
+
# This can only ever CAUSE a prompt, never skip one. An in-flight key is left alone.
|
|
99
|
+
python3 scripts/privileged_broker.py forget --key <key-or-prefix> --json
|
|
100
|
+
|
|
101
|
+
# Before/after counts.
|
|
102
|
+
python3 scripts/privileged_audit.py report --window 300
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Exit codes for `request`: `0` completed · `1` denied/cancelled/timeout/failed ·
|
|
106
|
+
`2` refused by the broker (bad request, password-capture shape, attempt cap).
|
|
107
|
+
|
|
108
|
+
### What the user sees before the dialog
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
┌ ADMIN PASSWORD REQUEST ─────────────────────────────────────
|
|
112
|
+
│ macOS is about to ask for your admin password for: sfltool
|
|
113
|
+
│ Who Codex · task d71397a3 · thread 01a01e46
|
|
114
|
+
│ Where build-loop (worktree run-864834) · branch main
|
|
115
|
+
│ What /usr/bin/sfltool dumpbtm
|
|
116
|
+
│ Why enumerate background-task items to name unlabeled login items
|
|
117
|
+
│ Scope btm:read · read-only · trust=local-admin
|
|
118
|
+
│ Shared yes — identical read-only requests reuse this for 900s, 2 task(s) waiting
|
|
119
|
+
│ When 2026-08-20T08:29:11Z · request 4f2a…
|
|
120
|
+
└─────────────────────────────────────────────────────────────
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## The rules
|
|
126
|
+
|
|
127
|
+
### Coalescing is narrow
|
|
128
|
+
|
|
129
|
+
Two requests share one authorization only when **all** of these are identical:
|
|
130
|
+
resolved `argv`, `scope`, `trust_domain`, `mutating`, uid, and registry entry.
|
|
131
|
+
Anything different is a different key and inherits nothing.
|
|
132
|
+
|
|
133
|
+
The identity is the **argv**, not the shell string. That is what makes it work on
|
|
134
|
+
the real incident: `sfltool dumpbtm 2>/dev/null | rg …` and `set -o pipefail`⏎
|
|
135
|
+
`sfltool dumpbtm | sed …` are different strings and the same request.
|
|
136
|
+
|
|
137
|
+
### Mutating never coalesces
|
|
138
|
+
|
|
139
|
+
A mutating request gets a private key directory, never reads the cache, never
|
|
140
|
+
writes one. One request, one prompt, no inheritance — in either direction.
|
|
141
|
+
|
|
142
|
+
### A negative is remembered; a negative is never upgraded
|
|
143
|
+
|
|
144
|
+
Denial, cancellation, and timeout are cached for `negative_ttl_seconds`
|
|
145
|
+
(default 300 s, 600 s for `sfltool dumpbtm`). During that window an identical
|
|
146
|
+
request is refused **from cache, without a dialog**. This is the control that
|
|
147
|
+
kills the observed retry. A cached terminal state replays verbatim; no branch
|
|
148
|
+
turns a `denied` into a `completed`.
|
|
149
|
+
|
|
150
|
+
The negative cache must not become a trap, so `forget --key` drops a cached
|
|
151
|
+
answer on demand. It removes an answer; the next request has to earn a new one.
|
|
152
|
+
|
|
153
|
+
### A cap is a rate limit, never a lockout
|
|
154
|
+
|
|
155
|
+
When a result ages out and nobody owns the key, the TTL window rolls: the cached
|
|
156
|
+
result and the prompt-attempt counter are cleared **together**. They have to move
|
|
157
|
+
as a unit — a counter that outlived its window would leave a key that once hit
|
|
158
|
+
the cap permanently `denied_exhausted`.
|
|
159
|
+
|
|
160
|
+
### The password is never touched
|
|
161
|
+
|
|
162
|
+
macOS performs the authentication. The broker decides who triggers it and shares
|
|
163
|
+
the resulting *output*. It refuses `sudo -S`, `--stdin`, `-A`, `--askpass`, a set
|
|
164
|
+
`SUDO_ASKPASS`, and any `--password=` argument, and never gives the child a piped
|
|
165
|
+
stdin. Nothing password-shaped is ever written to the store.
|
|
166
|
+
|
|
167
|
+
### A crashed owner cannot strand or storm
|
|
168
|
+
|
|
169
|
+
The owner heartbeats while the command runs. A waiter whose owner has a stale
|
|
170
|
+
heartbeat **and** a dead pid takes the lease over — once. `max_prompt_attempts`
|
|
171
|
+
(default 2) bounds how many dialogs one key may open in a TTL window; past it the
|
|
172
|
+
key goes terminal as `denied_exhausted` and every waiter gets that answer.
|
|
173
|
+
|
|
174
|
+
### Ambient observes; Ambient never decides
|
|
175
|
+
|
|
176
|
+
Durable visibility is `ledger.jsonl` — append-only and hash-chained, so a deleted
|
|
177
|
+
or edited record is detectable (`verify-ledger`). Live visibility is an optional
|
|
178
|
+
`ambient.notify_command` that receives each event on stdin. **The return value is
|
|
179
|
+
discarded and never inspected**, so no Ambient state can approve, deny, terminate,
|
|
180
|
+
or widen a request. A hostile sink is a covered test case.
|
|
181
|
+
|
|
182
|
+
To surface the event in RossLabs Ambient Agent, run its local daemon and configure
|
|
183
|
+
the broker with its `ambientctl` binary and state directory. The receiver accepts
|
|
184
|
+
only the redacted event on standard input; it records the purpose, requesting app,
|
|
185
|
+
risk class, and broker event id in Ambient activity. It never receives command
|
|
186
|
+
arguments, command output, or a password.
|
|
187
|
+
|
|
188
|
+
```json
|
|
189
|
+
{
|
|
190
|
+
"ambient": {
|
|
191
|
+
"mode": "live",
|
|
192
|
+
"notify_command": ["/absolute/path/to/ambientctl", "--state-dir", "/absolute/path/to/ambient-state", "systemAccessRequest"],
|
|
193
|
+
"notify_timeout_seconds": 3
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Unavailability is never approval
|
|
199
|
+
|
|
200
|
+
| Risk class | Coordinator unavailable | Ambient unavailable |
|
|
201
|
+
|---|---|---|
|
|
202
|
+
| read-only | proceed **uncoalesced**, attribution still printed, gap receipt written | proceed; gap receipt |
|
|
203
|
+
| mutating | **refuse** — never run a privileged mutation with no record | proceed; gap receipt |
|
|
204
|
+
| unknown | proceed uncoalesced, never coalesce; gap receipt | proceed; gap receipt |
|
|
205
|
+
|
|
206
|
+
Every receipt carries `unattributed_possible: true`. An empty ledger means *no
|
|
207
|
+
brokered traffic*, never *no privileged request*. `privileged_audit.py` counts
|
|
208
|
+
gaps as `unattributed` for exactly this reason.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Adding a command
|
|
213
|
+
|
|
214
|
+
Edit `scripts/privileged_commands.json`. Never special-case a command in the
|
|
215
|
+
broker.
|
|
216
|
+
|
|
217
|
+
```json
|
|
218
|
+
{
|
|
219
|
+
"id": "sfltool-dumpbtm",
|
|
220
|
+
"executable": "sfltool",
|
|
221
|
+
"argv_prefix": ["dumpbtm"],
|
|
222
|
+
"scope": "btm:read",
|
|
223
|
+
"mutating": false,
|
|
224
|
+
"cacheable": true,
|
|
225
|
+
"ttl_seconds": 900,
|
|
226
|
+
"negative_ttl_seconds": 600,
|
|
227
|
+
"confidence": "observed",
|
|
228
|
+
"notes": "…"
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Longest matching `argv_prefix` wins, so `csrutil status` (`"privileged": false`)
|
|
233
|
+
beats the `csrutil` catch-all. Set `"prompts": false` for a privileged command
|
|
234
|
+
that cannot open a dialog (`sudo -n`) — it is still attributed and recorded, just
|
|
235
|
+
never counted as a prompt. `confidence` is one of `observed` (seen prompting here,
|
|
236
|
+
evidence on file), `documented` (vendor/man page says root), `inferred`
|
|
237
|
+
(behaviour follows from the command class; unverified here).
|
|
238
|
+
|
|
239
|
+
When in doubt, leave `mutating: true`. A read wrongly marked mutating costs one
|
|
240
|
+
extra dialog; a mutation wrongly marked read-only inherits an approval it should
|
|
241
|
+
never have had.
|
|
242
|
+
|
|
243
|
+
## Known limits
|
|
244
|
+
|
|
245
|
+
- `prompt_opened` is a **proxy**: the broker counts the times it invoked a
|
|
246
|
+
privileged command, because it cannot observe SecurityAgent directly.
|
|
247
|
+
- `sudo` keeps its own sudoers timestamp cache, independent of this broker.
|
|
248
|
+
Consecutive `sudo` calls inside that window may show fewer real dialogs than
|
|
249
|
+
the baseline counts. The SecurityAgent commands have no such cache.
|
|
250
|
+
- The PreToolUse gate covers **Claude Code Bash calls**. Codex sessions are
|
|
251
|
+
covered by the `AGENTS.md` protocol, which is instruction-level, not enforced.
|
|
252
|
+
- `ambient.mode` defaults to `ledger-only`; live push stays unconfigured until a
|
|
253
|
+
`notify_command` is set, and that state is reported once as a coverage gap
|
|
254
|
+
rather than silently.
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
<!-- SPDX-FileCopyrightText: 2025-2026 Tyrone Ross, Jr <46267523+tyroneross@users.noreply.github.com> | SPDX-License-Identifier: Apache-2.0 -->
|
|
2
|
+
|
|
3
|
+
# Resource-Aware Execution
|
|
4
|
+
|
|
5
|
+
This is the canonical token, CPU, execution-profile, and context-conservation
|
|
6
|
+
contract. It is internal. The user still has one Build Loop entry point and no
|
|
7
|
+
resource-mode choices to manage.
|
|
8
|
+
|
|
9
|
+
## Automatic execution profile
|
|
10
|
+
|
|
11
|
+
Run `scripts/review_trigger.py` in Assess and again after Plan has concrete file
|
|
12
|
+
and line estimates. Persist the last envelope at
|
|
13
|
+
`state.json.execution.resourceProfile`.
|
|
14
|
+
|
|
15
|
+
| Profile | Trigger | Required path |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| `skip` | Small single-file/config change with no risk signal | Execute directly; deterministic validation only; do not start the full loop |
|
|
18
|
+
| `standard` | Multi-file, non-trivial, or 20+ line work with no high-risk signal | One independent auditor, deterministic validation, report, cheap Learn outcome; fact-check/security/simplify only when their signal exists |
|
|
19
|
+
| `high` | Auth, security, network, persistence, architecture, runtime, model/tool, dependency, large-diff, or ambiguous-risk signal | Full Review and cross-vendor review when reachable |
|
|
20
|
+
|
|
21
|
+
Profiles never bypass production, destructive-delete, secret, security, owed-
|
|
22
|
+
verification, or user-impact gates. A later high-risk signal promotes the run to
|
|
23
|
+
`high`; profiles never demote during a run.
|
|
24
|
+
|
|
25
|
+
## Resource-aware fan-out
|
|
26
|
+
|
|
27
|
+
Resolve the concrete model first. Then run:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/parallelism.py" \
|
|
31
|
+
--workdir "$PWD" --model "$MODEL" --provider "$PROVIDER" \
|
|
32
|
+
--segment "$SEGMENT" --tier "$TIER" \
|
|
33
|
+
--execution-location "$LOCATION" --output-size "$OUTPUT_SIZE" \
|
|
34
|
+
--agent implementer \
|
|
35
|
+
--independent-items "$READY_CHUNKS" --shared-capacity "$SHARED_CAPACITY" \
|
|
36
|
+
--active-elsewhere "$ACTIVE_ELSEWHERE" --describe --json
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Persist the envelope at `state.json.execution.fanout`. `effective_max` is
|
|
40
|
+
capacity, not a dispatch target. Pass it to `autonomy_supervisor.py fanout`;
|
|
41
|
+
the supervisor applies provider/host/cost/failure backpressure and chooses the
|
|
42
|
+
next wave. Dispatch only across a MECE partition. The absolute safety ceiling
|
|
43
|
+
is 150, while every lower live cap remains binding.
|
|
44
|
+
|
|
45
|
+
The role supplies an advisory effort when `--effort` is omitted. Today
|
|
46
|
+
`agentic_execution/T3` prefers `high`, so Codex execution resolves to Terra-high
|
|
47
|
+
and Claude execution resolves to Sonnet-high. Passing `--effort` remains an
|
|
48
|
+
explicit override.
|
|
49
|
+
|
|
50
|
+
## Accuracy-first token efficiency
|
|
51
|
+
|
|
52
|
+
Minimize tokens only among approaches expected to meet the same acceptance
|
|
53
|
+
criteria. Use this order:
|
|
54
|
+
|
|
55
|
+
1. Run deterministic scripts for repeatable checks, transforms, inventories,
|
|
56
|
+
and schema validation.
|
|
57
|
+
2. Use keyword or semantic retrieval to narrow source context before any model
|
|
58
|
+
reads it.
|
|
59
|
+
3. Route bounded scanning and classification to Pattern-tier or local models
|
|
60
|
+
when a deterministic verifier can judge the output.
|
|
61
|
+
4. Read the relevant implementation and tests before proposing complex code.
|
|
62
|
+
Early source grounding is cheaper than rework and repeated troubleshooting.
|
|
63
|
+
5. Use measured ledger rows to tune prompts, effort, and fan-out after quality
|
|
64
|
+
passes. Never count an unmatched or lower-quality run as a token win.
|
|
65
|
+
|
|
66
|
+
### Adaptive backpressure
|
|
67
|
+
|
|
68
|
+
- Start with a bounded ramp of at most four workers.
|
|
69
|
+
- Reduce admissions after repeated 429s, worker errors, memory pressure,
|
|
70
|
+
serious thermal state, low disk, or 80% cost use.
|
|
71
|
+
- Pause new work at critical thermal/memory/disk pressure or the cost ceiling.
|
|
72
|
+
- Recover one worker only after two stable telemetry windows.
|
|
73
|
+
- External cooling changes measured thermal stability; it does not bypass CPU,
|
|
74
|
+
token, cost, ownership, or provider limits.
|
|
75
|
+
|
|
76
|
+
Every tool call and result reconciles into
|
|
77
|
+
`.build-loop/telemetry/tool-traces.jsonl` as an OTel-shaped, bounded, redacted
|
|
78
|
+
span. The supervisor consumes error, retry, 429, and latency summaries; Phase 6
|
|
79
|
+
consumes the same signals for recursive learning.
|
|
80
|
+
|
|
81
|
+
### Synthetic load safety
|
|
82
|
+
|
|
83
|
+
Never launch an unbounded background CPU loop. Run load-sensitive checks through
|
|
84
|
+
`build-loop-load-probe`, which caps admission, names every worker, gives each
|
|
85
|
+
worker an internal hard deadline, and verifies cleanup:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
build-loop-load-probe --workers 4 --duration-seconds 30 -- npm test -- --runInBand
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The lifecycle receipt contains only a fixed product/purpose, opaque run id, PID
|
|
92
|
+
birth identity, process group, timestamps, and cleanup result. It must never
|
|
93
|
+
contain prompts, URLs, secrets, repository paths, or the wrapped command line.
|
|
94
|
+
Host-wide cleanup may signal a probe only when its owned receipt, PID birth
|
|
95
|
+
identity, process-group identity, marker, and expired deadline all match.
|
|
96
|
+
Unknown or ambiguous processes remain advisory.
|
|
97
|
+
|
|
98
|
+
### Cloud inference: token-led
|
|
99
|
+
|
|
100
|
+
1. Use the median measured raw tokens for the same model and agent from the
|
|
101
|
+
cost ledger when available.
|
|
102
|
+
2. Otherwise use the model/output/effort T-shirt estimate.
|
|
103
|
+
3. Divide the wave token budget by per-worker demand.
|
|
104
|
+
4. Apply configuration, CPU headroom, and hard-ceiling caps as secondary limits.
|
|
105
|
+
|
|
106
|
+
Default heuristic demand before output/effort multipliers:
|
|
107
|
+
|
|
108
|
+
| Model size | Typical role | Tokens/worker |
|
|
109
|
+
|---|---|---:|
|
|
110
|
+
| small | Pattern/utility | 8,000 |
|
|
111
|
+
| medium | Code/workhorse | 16,000 |
|
|
112
|
+
| large | Thinking | 24,000 |
|
|
113
|
+
| xlarge | Frontier | 32,000 |
|
|
114
|
+
|
|
115
|
+
Output multipliers are small `0.5`, medium `1.0`, large `1.75`. Effort
|
|
116
|
+
multipliers are low `0.75`, medium `1.0`, high `1.25`, xhigh `1.75`, max
|
|
117
|
+
`2.25`, ultra `3.0`. These values are routing heuristics, not pricing claims.
|
|
118
|
+
Measured data replaces them automatically.
|
|
119
|
+
|
|
120
|
+
### Local inference: CPU-led
|
|
121
|
+
|
|
122
|
+
Local workers reserve CPU according to model size: small `1`, medium `2`, large
|
|
123
|
+
`4`, xlarge `8` cores per worker. The resolver keeps two cores for the lead and
|
|
124
|
+
OS. Token limits apply to local inference only when the caller supplies one;
|
|
125
|
+
local token throughput does not silently override CPU safety.
|
|
126
|
+
|
|
127
|
+
### Unknown location
|
|
128
|
+
|
|
129
|
+
Pass the provider/location when known. `auto` recognizes Ollama, MLX, LM Studio,
|
|
130
|
+
llama.cpp, and explicit local adapters. Other models default to cloud so an
|
|
131
|
+
unknown provider receives the conservative token-led path.
|
|
132
|
+
|
|
133
|
+
## Token telemetry
|
|
134
|
+
|
|
135
|
+
`cost_ledger_hook.py` always records dispatch identity, run, phase, execution
|
|
136
|
+
location, model/output T-shirt sizes, and a heuristic token estimate. Provider
|
|
137
|
+
adapters enrich the same task id through `write_cost_ledger_row.py` with:
|
|
138
|
+
|
|
139
|
+
- `input_tokens`
|
|
140
|
+
- `output_tokens`
|
|
141
|
+
- `cache_read_input_tokens`
|
|
142
|
+
- `cache_creation_input_tokens`
|
|
143
|
+
- `phase`, `fanout_limit`, and `fanout_primary_constraint`
|
|
144
|
+
|
|
145
|
+
Keep measured buckets separate from `tokens_estimate`. Benchmark conclusions
|
|
146
|
+
use measured rows only.
|
|
147
|
+
|
|
148
|
+
## Bounded context
|
|
149
|
+
|
|
150
|
+
- Capture each assembled brief once under `.build-loop/briefs/<run>/<chunk>.md`.
|
|
151
|
+
- Pass goal, ownership, interface, acceptance criteria, falsifier, and file
|
|
152
|
+
pointers. Do not paste full shared documents into every worker.
|
|
153
|
+
- Preserve stable prefixes for provider caching.
|
|
154
|
+
- Use the resolved model's `prompting_profile`; compressed/standard profiles
|
|
155
|
+
remove repeated examples and rationale while keeping safety and acceptance
|
|
156
|
+
contracts.
|
|
157
|
+
- Prefer one context for sequential/cross-cutting work. Fan-out must earn its
|
|
158
|
+
repeated brief cost through genuinely independent chunks.
|
|
159
|
+
|
|
160
|
+
## Proposal maintenance
|
|
161
|
+
|
|
162
|
+
Before Phase 6 pattern detection, run the reversible consumer once:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/drain_self_review_proposals.py" \
|
|
166
|
+
--workdir "$PWD" --archive --stamp "$RUN_ID" --json
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
This archives superseded, stale, and non-actionable proposals before any model
|
|
170
|
+
reads the queue. It never applies findings and never deletes evidence.
|
|
171
|
+
|
|
172
|
+
## Benchmark
|
|
173
|
+
|
|
174
|
+
Use `evals/token-efficiency/tasks.jsonl` as the starter task set. Record results
|
|
175
|
+
for identical task id, repository snapshot, and model, then compare with:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
python3 scripts/token_efficiency_benchmark.py --results results.jsonl \
|
|
179
|
+
--baseline current --candidate resource-aware --json
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The harness excludes estimates and unmatched tasks from the A/B token claim.
|
|
183
|
+
Quality must remain non-inferior before a token reduction counts as a win.
|
|
@@ -8,7 +8,7 @@ A run is **self-recursive** when the build-loop working tree IS the loaded runti
|
|
|
8
8
|
Recommended: pass the working tree directly to Claude Code at session start.
|
|
9
9
|
|
|
10
10
|
```sh
|
|
11
|
-
claude --plugin-dir
|
|
11
|
+
claude --plugin-dir <path-to-your-local-checkout>
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
`--plugin-dir` takes session precedence over any cached marketplace copy, and Claude Code sets `CLAUDE_PLUGIN_ROOT` to that directory. The detector reads it. No symlink, no `~/.claude/` mutation.
|
|
@@ -16,7 +16,7 @@ claude --plugin-dir ~/dev/git-folder/build-loop
|
|
|
16
16
|
Convenience alias (optional, in `~/.zshrc` or `~/.bashrc`):
|
|
17
17
|
|
|
18
18
|
```sh
|
|
19
|
-
alias claude-bl='claude --plugin-dir
|
|
19
|
+
alias claude-bl='claude --plugin-dir <path-to-your-local-checkout>'
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
Use the alias when you intend to dogfood build-loop changes; use plain `claude` for normal work that should run against the released cache version.
|