mandrel 2.59.0 → 2.61.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/README.md +21 -19
- package/.agents/agents/acceptance-critic.md +24 -43
- package/.agents/agents/story-worker.md +20 -21
- package/.agents/docs/agentrc-reference.json +5 -84
- package/.agents/docs/configuration.md +48 -132
- package/.agents/docs/workflows.md +2 -2
- package/.agents/instructions.md +5 -8
- package/.agents/rules/ci-remediation.md +41 -8
- package/.agents/rules/gherkin-standards.md +4 -0
- package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
- package/.agents/schemas/agentrc.schema.json +16 -496
- package/.agents/schemas/story-deliver-terminal.schema.json +13 -3
- package/.agents/schemas/validation-evidence.schema.json +2 -1
- package/.agents/scripts/README.md +23 -13
- package/.agents/scripts/acceptance-eval.js +35 -169
- package/.agents/scripts/agents-bootstrap-github.js +27 -129
- package/.agents/scripts/apply-quality-bootstrap.js +4 -40
- package/.agents/scripts/audit-baselines.js +6 -27
- package/.agents/scripts/audit-labels-bootstrap.js +5 -29
- package/.agents/scripts/audit-to-stories.js +91 -361
- package/.agents/scripts/boot-sweep.js +19 -72
- package/.agents/scripts/bootstrap.js +74 -395
- package/.agents/scripts/ceremony-derive.js +10 -41
- package/.agents/scripts/check-arch-cycles.js +14 -64
- package/.agents/scripts/check-baselines.js +8 -48
- package/.agents/scripts/check-context-budget.js +105 -311
- package/.agents/scripts/check-cyclomatic.js +12 -44
- package/.agents/scripts/check-dead-exports.js +13 -64
- package/.agents/scripts/check-doc-links.js +38 -186
- package/.agents/scripts/check-gherkin-corpus.js +24 -127
- package/.agents/scripts/check-test-temp-hygiene.js +28 -169
- package/.agents/scripts/coverage-capture.js +34 -98
- package/.agents/scripts/deliver-light.js +25 -171
- package/.agents/scripts/deliver-recover.js +6 -42
- package/.agents/scripts/deliver-run.js +534 -0
- package/.agents/scripts/diagnose-friction.js +24 -116
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +23 -85
- package/.agents/scripts/file-ci-gap.js +57 -49
- package/.agents/scripts/generate-config-docs.js +30 -170
- package/.agents/scripts/generate-lens-checklists.js +8 -52
- package/.agents/scripts/generate-skills-index.js +14 -112
- package/.agents/scripts/generate-workflows-doc.js +10 -70
- package/.agents/scripts/git-cleanup.js +2 -34
- package/.agents/scripts/lib/Graph.js +24 -81
- package/.agents/scripts/lib/ITicketingProvider.js +47 -143
- package/.agents/scripts/lib/Logger.js +14 -76
- package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
- package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
- package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
- package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
- package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
- package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
- package/.agents/scripts/lib/audit-baselines/read.js +3 -16
- package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
- package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
- package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
- package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
- package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
- package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
- package/.agents/scripts/lib/audit-suite/findings.js +12 -52
- package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
- package/.agents/scripts/lib/audit-suite/index.js +1 -15
- package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
- package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
- package/.agents/scripts/lib/audit-suite/runner.js +13 -43
- package/.agents/scripts/lib/audit-suite/selector.js +49 -349
- package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
- package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
- package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
- package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
- package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
- package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
- package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
- package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
- package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
- package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
- package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
- package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
- package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
- package/.agents/scripts/lib/baseline-loader.js +12 -51
- package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
- package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
- package/.agents/scripts/lib/baselines/components.js +10 -61
- package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
- package/.agents/scripts/lib/baselines/crap-preview-incremental.js +7 -19
- package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
- package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
- package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
- package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
- package/.agents/scripts/lib/baselines/envelope.js +13 -129
- package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
- package/.agents/scripts/lib/baselines/git-base.js +23 -142
- package/.agents/scripts/lib/baselines/kernel.js +11 -111
- package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
- package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
- package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
- package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
- package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
- package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
- package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
- package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
- package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
- package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
- package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
- package/.agents/scripts/lib/baselines/path-canon.js +19 -128
- package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
- package/.agents/scripts/lib/baselines/reader.js +14 -107
- package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
- package/.agents/scripts/lib/baselines/scope.js +11 -135
- package/.agents/scripts/lib/baselines/writer.js +16 -149
- package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
- package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
- package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
- package/.agents/scripts/lib/bdd-step-index.js +26 -100
- package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
- package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
- package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
- package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
- package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
- package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
- package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
- package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
- package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
- package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
- package/.agents/scripts/lib/bootstrap/summary.js +1 -8
- package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
- package/.agents/scripts/lib/branch-name-guard.js +4 -23
- package/.agents/scripts/lib/changed-files.js +39 -121
- package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
- package/.agents/scripts/lib/checks/index.js +18 -101
- package/.agents/scripts/lib/checks/loop-health.js +11 -53
- package/.agents/scripts/lib/checks/state.js +16 -91
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
- package/.agents/scripts/lib/child-exec.js +39 -108
- package/.agents/scripts/lib/cli/standard-args.js +9 -116
- package/.agents/scripts/lib/cli-args.js +31 -146
- package/.agents/scripts/lib/cli-usage.js +5 -27
- package/.agents/scripts/lib/cli-utils.js +2 -12
- package/.agents/scripts/lib/close-validation/commands.js +13 -76
- package/.agents/scripts/lib/close-validation/gates.js +92 -331
- package/.agents/scripts/lib/close-validation/process.js +121 -151
- package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
- package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
- package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
- package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
- package/.agents/scripts/lib/close-validation/runner.js +53 -110
- package/.agents/scripts/lib/command-header.js +6 -28
- package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
- package/.agents/scripts/lib/config/baselines.js +3 -14
- package/.agents/scripts/lib/config/ci.js +8 -38
- package/.agents/scripts/lib/config/commands.js +1 -15
- package/.agents/scripts/lib/config/defaults.js +4 -33
- package/.agents/scripts/lib/config/delivery-routing.js +6 -34
- package/.agents/scripts/lib/config/explain.js +10 -83
- package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +3 -31
- package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
- package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
- package/.agents/scripts/lib/config/gates/index.js +2 -17
- package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
- package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
- package/.agents/scripts/lib/config/gates/shared.js +4 -64
- package/.agents/scripts/lib/config/github.js +4 -22
- package/.agents/scripts/lib/config/limits.js +4 -57
- package/.agents/scripts/lib/config/paths.js +2 -21
- package/.agents/scripts/lib/config/qa.js +4 -38
- package/.agents/scripts/lib/config/quality.js +76 -432
- package/.agents/scripts/lib/config/runners.js +12 -56
- package/.agents/scripts/lib/config/runtime.js +13 -57
- package/.agents/scripts/lib/config/shared.js +2 -16
- package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
- package/.agents/scripts/lib/config/temp-paths.js +40 -280
- package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
- package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
- package/.agents/scripts/lib/config-resolver.js +11 -52
- package/.agents/scripts/lib/config-schema-shared.js +1 -4
- package/.agents/scripts/lib/config-settings-schema-delivery.js +16 -291
- package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
- package/.agents/scripts/lib/config-settings-schema.js +37 -274
- package/.agents/scripts/lib/coverage-baseline.js +20 -110
- package/.agents/scripts/lib/coverage-capture-fullscope.js +18 -35
- package/.agents/scripts/lib/coverage-capture-incremental.js +15 -45
- package/.agents/scripts/lib/coverage-capture-usage.js +8 -25
- package/.agents/scripts/lib/coverage-capture.js +99 -224
- package/.agents/scripts/lib/coverage-utils.js +14 -79
- package/.agents/scripts/lib/cpu-pool.js +17 -123
- package/.agents/scripts/lib/crap-baseline-join.js +16 -88
- package/.agents/scripts/lib/crap-coordinates.js +6 -25
- package/.agents/scripts/lib/crap-engine.js +40 -153
- package/.agents/scripts/lib/crap-method-identity.js +16 -78
- package/.agents/scripts/lib/crap-utils.js +31 -155
- package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
- package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
- package/.agents/scripts/lib/dead-exports-knip.js +18 -56
- package/.agents/scripts/lib/dead-exports-mode.js +5 -24
- package/.agents/scripts/lib/degraded-mode.js +3 -26
- package/.agents/scripts/lib/dependency-parser.js +8 -40
- package/.agents/scripts/lib/dependency-version.js +13 -35
- package/.agents/scripts/lib/detect-package-manager.js +6 -36
- package/.agents/scripts/lib/doc-tiers.js +22 -124
- package/.agents/scripts/lib/duplicate-search.js +8 -72
- package/.agents/scripts/lib/env-loader.js +5 -27
- package/.agents/scripts/lib/error-redactor.js +6 -31
- package/.agents/scripts/lib/errors/index.js +2 -22
- package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
- package/.agents/scripts/lib/escomplex-kernel.js +21 -123
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +94 -419
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -149
- package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
- package/.agents/scripts/lib/findings/classify-finding.js +14 -69
- package/.agents/scripts/lib/findings/promote-finding.js +14 -112
- package/.agents/scripts/lib/findings/provenance-field.js +11 -52
- package/.agents/scripts/lib/findings/route-finding.js +37 -255
- package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
- package/.agents/scripts/lib/findings/severity.js +18 -104
- package/.agents/scripts/lib/format-generated-json.js +12 -44
- package/.agents/scripts/lib/full-suite-lock.js +160 -429
- package/.agents/scripts/lib/full-suite-queue.js +213 -0
- package/.agents/scripts/lib/gates/baseline-store.js +5 -9
- package/.agents/scripts/lib/gates/friction.js +1 -3
- package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
- package/.agents/scripts/lib/gh-exec.js +123 -191
- package/.agents/scripts/lib/git/cached-fetch.js +9 -52
- package/.agents/scripts/lib/git/sync-from-base.js +15 -107
- package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
- package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
- package/.agents/scripts/lib/git-utils.js +37 -161
- package/.agents/scripts/lib/github/framework-repo.js +8 -71
- package/.agents/scripts/lib/github-url.js +2 -17
- package/.agents/scripts/lib/import-graph.js +11 -38
- package/.agents/scripts/lib/install-cmd-parser.js +4 -13
- package/.agents/scripts/lib/json-utils.js +3 -18
- package/.agents/scripts/lib/label-constants.js +16 -111
- package/.agents/scripts/lib/label-taxonomy.js +4 -30
- package/.agents/scripts/lib/maintainability-engine.js +12 -80
- package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
- package/.agents/scripts/lib/maintainability-utils.js +16 -92
- package/.agents/scripts/lib/mandrel-catalog.js +12 -70
- package/.agents/scripts/lib/notifications/notifier.js +13 -38
- package/.agents/scripts/lib/npm-scripts.js +4 -23
- package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
- package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
- package/.agents/scripts/lib/observability/signal-validator.js +5 -37
- package/.agents/scripts/lib/observability/signals-writer.js +11 -121
- package/.agents/scripts/lib/observability/source-classifier.js +22 -203
- package/.agents/scripts/lib/observability/terse-result.js +14 -47
- package/.agents/scripts/lib/onboard/init-tail.js +13 -74
- package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
- package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
- package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +28 -156
- package/.agents/scripts/lib/orchestration/change-set.js +7 -36
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
- package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
- package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
- package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
- package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
- package/.agents/scripts/lib/orchestration/check-state.js +92 -0
- package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +121 -157
- package/.agents/scripts/lib/orchestration/code-review.js +24 -128
- package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
- package/.agents/scripts/lib/orchestration/complexity-gate.js +118 -462
- package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
- package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
- package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
- package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
- package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
- package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
- package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
- package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
- package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
- package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
- package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
- package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
- package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
- package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
- package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
- package/.agents/scripts/lib/orchestration/light-suitability.js +37 -307
- package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
- package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
- package/.agents/scripts/lib/orchestration/plan-context.js +55 -318
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
- package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
- package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
- package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
- package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
- package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +16 -78
- package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
- package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
- package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
- package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +71 -289
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +96 -362
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +9 -39
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +60 -186
- package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
- package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
- package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
- package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
- package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
- package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
- package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
- package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
- package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
- package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
- package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
- package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
- package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
- package/.agents/scripts/lib/orchestration/review-depth.js +12 -91
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
- package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
- package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
- package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
- package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
- package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
- package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
- package/.agents/scripts/lib/orchestration/run-epilogue.js +245 -326
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +55 -159
- package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
- package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
- package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +20 -82
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +136 -486
- package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
- package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +96 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +180 -273
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
- package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
- package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
- package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
- package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -200
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +167 -252
- package/.agents/scripts/lib/orchestration/story-init-envelope.js +52 -0
- package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
- package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
- package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -135
- package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
- package/.agents/scripts/lib/orchestration/ticket-validator.js +63 -344
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -261
- package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
- package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
- package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
- package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
- package/.agents/scripts/lib/path-security.js +3 -6
- package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
- package/.agents/scripts/lib/preflight-runner.js +13 -69
- package/.agents/scripts/lib/process-group.js +143 -0
- package/.agents/scripts/lib/project-root.js +2 -8
- package/.agents/scripts/lib/provider-factory.js +2 -25
- package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
- package/.agents/scripts/lib/qa/qa-session.js +15 -69
- package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
- package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
- package/.agents/scripts/lib/reserved-test-ids.js +9 -47
- package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
- package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
- package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
- package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
- package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
- package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
- package/.agents/scripts/lib/signals/detectors/common.js +12 -38
- package/.agents/scripts/lib/signals/index.js +2 -19
- package/.agents/scripts/lib/signals/schema.js +14 -109
- package/.agents/scripts/lib/signals/write.js +2 -11
- package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
- package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
- package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
- package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
- package/.agents/scripts/lib/single-story-sweep.js +14 -97
- package/.agents/scripts/lib/skills/parse-skill.js +13 -59
- package/.agents/scripts/lib/skills/skills-index.js +8 -29
- package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
- package/.agents/scripts/lib/source-extensions.js +11 -42
- package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
- package/.agents/scripts/lib/stdio-flush.js +9 -36
- package/.agents/scripts/lib/story-adjacency.js +8 -40
- package/.agents/scripts/lib/story-body/body-format-lints.js +51 -66
- package/.agents/scripts/lib/story-body/footer-block.js +11 -44
- package/.agents/scripts/lib/story-body/story-body.js +123 -344
- package/.agents/scripts/lib/temp-retention.js +42 -143
- package/.agents/scripts/lib/templates/decomposer-prompts.js +18 -80
- package/.agents/scripts/lib/test-env.js +12 -65
- package/.agents/scripts/lib/test-run-credit.js +10 -65
- package/.agents/scripts/lib/test-runner-contract.js +19 -74
- package/.agents/scripts/lib/test-temp.js +38 -184
- package/.agents/scripts/lib/test-tiers.js +12 -96
- package/.agents/scripts/lib/ticket-body-sections.js +21 -96
- package/.agents/scripts/lib/transpile.js +15 -74
- package/.agents/scripts/lib/util/concurrent-map.js +6 -25
- package/.agents/scripts/lib/util/parse-id-list.js +8 -34
- package/.agents/scripts/lib/util/poll-loop.js +8 -28
- package/.agents/scripts/lib/util/with-timeout.js +2 -11
- package/.agents/scripts/lib/validation-evidence.js +21 -96
- package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
- package/.agents/scripts/lib/wave-runner/live-probe.js +67 -209
- package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
- package/.agents/scripts/lib/workers/crap-worker.js +11 -64
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
- package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
- package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
- package/.agents/scripts/lib/workflow-closure.js +22 -105
- package/.agents/scripts/lib/workspace-provisioner.js +16 -54
- package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
- package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
- package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
- package/.agents/scripts/lib/worktree-manager.js +15 -40
- package/.agents/scripts/lint-issue-body.js +12 -68
- package/.agents/scripts/mandrel-update-preflight.js +10 -70
- package/.agents/scripts/merge-baseline.js +30 -105
- package/.agents/scripts/nav-registry-diff.js +22 -108
- package/.agents/scripts/notify.js +12 -69
- package/.agents/scripts/plan-context.js +97 -92
- package/.agents/scripts/plan-critics.js +12 -66
- package/.agents/scripts/plan-persist.js +71 -137
- package/.agents/scripts/plan-run-epilogue.js +20 -43
- package/.agents/scripts/pr-watch-with-update.js +79 -263
- package/.agents/scripts/providers/github/auth.js +3 -8
- package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
- package/.agents/scripts/providers/github/board-add.js +5 -21
- package/.agents/scripts/providers/github/branch-protection.js +11 -43
- package/.agents/scripts/providers/github/cache.js +2 -14
- package/.agents/scripts/providers/github/comments.js +7 -40
- package/.agents/scripts/providers/github/compose.js +3 -19
- package/.agents/scripts/providers/github/errors.js +22 -125
- package/.agents/scripts/providers/github/issues.js +31 -123
- package/.agents/scripts/providers/github/labels.js +24 -124
- package/.agents/scripts/providers/github/mappers.js +5 -27
- package/.agents/scripts/providers/github/merge-methods.js +3 -22
- package/.agents/scripts/providers/github/project-board.js +2 -17
- package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
- package/.agents/scripts/providers/github/request-helpers.js +5 -32
- package/.agents/scripts/providers/github/search-budget.js +9 -39
- package/.agents/scripts/providers/github/search-query.js +5 -26
- package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
- package/.agents/scripts/providers/github/sub-issues.js +7 -36
- package/.agents/scripts/providers/github/tickets.js +32 -134
- package/.agents/scripts/providers/github.js +18 -59
- package/.agents/scripts/prune-plan-run-labels.js +12 -46
- package/.agents/scripts/quality-preview.js +35 -220
- package/.agents/scripts/resolve-doc-tiers.js +3 -26
- package/.agents/scripts/resolve-stories.js +16 -67
- package/.agents/scripts/resync-status-column.js +6 -25
- package/.agents/scripts/run-tests.js +29 -104
- package/.agents/scripts/single-story-close.js +23 -135
- package/.agents/scripts/single-story-confirm-merge.js +32 -139
- package/.agents/scripts/single-story-init.js +47 -259
- package/.agents/scripts/stories-wave-tick.js +179 -415
- package/.agents/scripts/sync-agentrc.js +3 -21
- package/.agents/scripts/sync-claude-agents.js +9 -55
- package/.agents/scripts/sync-claude-commands.js +20 -110
- package/.agents/scripts/test-wrapper.js +6 -43
- package/.agents/scripts/update-coverage-baseline.js +5 -22
- package/.agents/scripts/update-crap-baseline.js +7 -30
- package/.agents/scripts/update-duplication-baseline.js +16 -92
- package/.agents/scripts/update-maintainability-baseline.js +8 -62
- package/.agents/scripts/update-ticket-state.js +1 -7
- package/.agents/scripts/validate-skills.js +6 -26
- package/.agents/skills/core/gates-and-baselines/reference.md +0 -1
- package/.agents/skills/skills.index.json +2 -2
- package/.agents/skills/stack/qa/playwright/SKILL.md +26 -0
- package/.agents/templates/agent-protocol.md +2 -2
- package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
- package/.agents/workflows/audit-accessibility.md +4 -7
- package/.agents/workflows/audit-adrs.md +3 -6
- package/.agents/workflows/audit-architecture.md +3 -11
- package/.agents/workflows/audit-baselines.md +6 -9
- package/.agents/workflows/audit-clean-code.md +8 -12
- package/.agents/workflows/audit-data-model.md +3 -7
- package/.agents/workflows/audit-dependencies.md +4 -7
- package/.agents/workflows/audit-devops.md +4 -8
- package/.agents/workflows/audit-documentation.md +1 -4
- package/.agents/workflows/audit-mobile.md +4 -7
- package/.agents/workflows/audit-navigability.md +3 -6
- package/.agents/workflows/audit-performance.md +2 -4
- package/.agents/workflows/audit-privacy.md +4 -7
- package/.agents/workflows/audit-quality.md +4 -7
- package/.agents/workflows/audit-security.md +4 -7
- package/.agents/workflows/audit-seo.md +4 -7
- package/.agents/workflows/audit-sre.md +4 -7
- package/.agents/workflows/audit-to-stories.md +17 -30
- package/.agents/workflows/audit-ux-ui.md +4 -7
- package/.agents/workflows/helpers/acceptance-self-eval.md +84 -157
- package/.agents/workflows/helpers/audit-lens-core.md +1 -1
- package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
- package/.agents/workflows/helpers/code-review.md +4 -2
- package/.agents/workflows/helpers/deliver-digest.md +37 -28
- package/.agents/workflows/helpers/deliver-light.md +92 -101
- package/.agents/workflows/helpers/deliver-reference.md +162 -220
- package/.agents/workflows/helpers/deliver-story-reference.md +197 -607
- package/.agents/workflows/helpers/deliver-story.md +17 -18
- package/.agents/workflows/helpers/plan-reference.md +125 -167
- package/.agents/workflows/helpers/qa-core.md +12 -0
- package/.agents/workflows/mandrel-deliver.md +47 -31
- package/.agents/workflows/mandrel-plan.md +22 -21
- package/.agents/workflows/mandrel-update.md +36 -21
- package/.agents/workflows/memory-consolidate.md +1 -1
- package/.agents/workflows/qa-assist.md +27 -71
- package/.agents/workflows/qa-explore.md +19 -59
- package/.agents/workflows/qa-run.md +11 -33
- package/README.md +1 -1
- package/bin/mandrel.js +5 -46
- package/bin/postinstall.js +18 -107
- package/docs/CHANGELOG.md +60 -0
- package/lib/cli/doctor.js +11 -71
- package/lib/cli/init.js +26 -165
- package/lib/cli/migrate.js +5 -64
- package/lib/cli/registry.js +84 -467
- package/lib/cli/sync-agents.js +4 -64
- package/lib/cli/sync-commands.js +11 -64
- package/lib/cli/sync.js +34 -213
- package/lib/cli/uninstall.js +40 -219
- package/lib/cli/update.js +326 -523
- package/lib/cli/version-check.js +8 -72
- package/lib/cli/version-helpers.js +14 -87
- package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
- package/lib/migrations/index.js +17 -92
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
- package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
- package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
- package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
- package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
- package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
- package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
- package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +21 -0
- package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
- package/package.json +17 -14
- package/.agents/docs/SDLC.md +0 -590
- package/.agents/docs/quality-gates.md +0 -1179
- package/.agents/rules/known-tooling-behavior.md +0 -150
- package/.agents/rules/orchestration-error-handling.md +0 -61
- package/.agents/rules/test-seams.md +0 -59
- package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
- package/.agents/schemas/baselines/lint.schema.json +0 -47
- package/.agents/schemas/model-attribution.schema.json +0 -53
- package/.agents/scripts/check-action-pinning.js +0 -260
- package/.agents/scripts/check-audit-attribution.js +0 -302
- package/.agents/scripts/check-baseline-drift.js +0 -211
- package/.agents/scripts/check-baseline-scope.js +0 -362
- package/.agents/scripts/check-generated-validator.js +0 -202
- package/.agents/scripts/check-knip-entries.js +0 -159
- package/.agents/scripts/check-lifecycle-lint.js +0 -294
- package/.agents/scripts/check-pinned-override-notes.js +0 -102
- package/.agents/scripts/check-schema-references.js +0 -366
- package/.agents/scripts/check-test-portability.js +0 -512
- package/.agents/scripts/check-workflow-citations.js +0 -332
- package/.agents/scripts/check-workflow-cli-lint.js +0 -299
- package/.agents/scripts/check-workflow-timeouts.js +0 -291
- package/.agents/scripts/install-matrix-assert.js +0 -326
- package/.agents/scripts/lib/audit-advisories.js +0 -195
- package/.agents/scripts/lib/audit-attribution.js +0 -134
- package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
- package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
- package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
- package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
- package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
- package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
- package/.agents/scripts/lib/c8-cli-path.js +0 -21
- package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
- package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
- package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
- package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
- package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
- package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
- package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
- package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
- package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
- package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
- package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
- package/.agents/scripts/lib/fs-walk.js +0 -52
- package/.agents/scripts/lib/knip-config-resolver.js +0 -181
- package/.agents/scripts/lib/knip-entry-sync.js +0 -452
- package/.agents/scripts/lib/orchestration/model-attribution.js +0 -418
- package/.agents/scripts/lib/orchestration/story-plan-state.js +0 -33
- package/.agents/scripts/lib/orchestration/structured-comment-parser.js +0 -67
- package/.agents/scripts/lib/pinned-override-notes.js +0 -88
- package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
- package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
- package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
- package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
- package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
- package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
- package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
- package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
- package/.agents/scripts/lib/test-isolate/runner.js +0 -483
- package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
- package/.agents/scripts/lib/test-profile/render-report.js +0 -45
- package/.agents/scripts/lint-label-vocabulary.js +0 -214
- package/.agents/scripts/post-structured-comment.js +0 -127
- package/.agents/scripts/provision-git-hooks.js +0 -85
- package/.agents/scripts/prune-baseline-orphans.js +0 -181
- package/.agents/scripts/run-coverage.js +0 -197
- package/.agents/scripts/run-lint.js +0 -133
- package/.agents/scripts/run-test-profile.js +0 -129
- package/.agents/scripts/run-verify.js +0 -118
- package/.agents/scripts/test-isolate.js +0 -55
- package/.agents/scripts/update-dead-exports-baseline.js +0 -321
|
@@ -1,80 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI: ratchet
|
|
3
|
-
*
|
|
2
|
+
* CLI: ratchet gate for documentation context bytes against
|
|
3
|
+
* `baselines/context-budget.json`. Measures `alwaysLoaded` (the `CLAUDE.md`
|
|
4
|
+
* `@`-import closure), `mandatoryRead` (`project.docsContextFiles`) and
|
|
5
|
+
* `workflow` (entry points + `mandatoryReads:` closure).
|
|
4
6
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* Only `alwaysLoaded` gates — every session and subagent spawn pays it. Exit 1
|
|
8
|
+
* when it grows past `totalBytes + toleranceBytes` or a recorded row names a
|
|
9
|
+
* path it no longer contains; every other drift, and all shrinkage, is
|
|
10
|
+
* reported with exit 0 (the close writes a lower total back). An empty tier or
|
|
11
|
+
* a missing baseline is a no-op. Tolerance lives only in the baseline JSON.
|
|
10
12
|
*
|
|
11
|
-
*
|
|
12
|
-
* session and every subagent spawn (instructions.md § 4).
|
|
13
|
-
* - `mandatoryRead` — the resolved `project.docsContextFiles` set.
|
|
14
|
-
* - `workflow` — the workflow **mandatory closure** (Story #4752): every
|
|
15
|
-
* `.agents/workflows/**` entry point plus the transitive
|
|
16
|
-
* closure of its `mandatoryReads:` frontmatter edges. The
|
|
17
|
-
* companion **reachable** closure (per entry point) is
|
|
18
|
-
* recorded under the top-level `workflowClosure` key as a
|
|
19
|
-
* drift signal and never gates — growth there is a
|
|
20
|
-
* reading-cost signal, not a contract violation.
|
|
21
|
-
*
|
|
22
|
-
* It additionally enforces a **per-file** ceiling on the role-scoped agent-boot
|
|
23
|
-
* tier (`.agents/agents/*.md`, #4478): no single boot context may exceed
|
|
24
|
-
* `agentBoot.ceilingBytes` (default 8192). This is a per-agent cap, not a sum
|
|
25
|
-
* ratchet — each role def is a standalone system prompt a converted spawn boots
|
|
26
|
-
* on, and adding another role def is legitimate.
|
|
27
|
-
*
|
|
28
|
-
* The recorded `agentBoot` rows are additionally held **in sync with the tree**
|
|
29
|
-
* (Story #4830), because those rows are what an author sizes an edit against.
|
|
30
|
-
* The two drift directions are deliberately asymmetric:
|
|
31
|
-
*
|
|
32
|
-
* - **permissive** (the row understates the file, or no row exists) — the row
|
|
33
|
-
* promises headroom that does not exist, the gate stays green, and the
|
|
34
|
-
* shortfall only lands as a ceiling failure once the edit is written. This
|
|
35
|
-
* fails the gate.
|
|
36
|
-
* - **restrictive** (the row overstates the file) — an author under-spends
|
|
37
|
-
* and the ceiling is never surprised, so it is self-correcting. Reported as
|
|
38
|
-
* a `-` line; exit stays 0.
|
|
39
|
-
*
|
|
40
|
-
* Each row also records its `headroomBytes` under the ceiling, so the budget an
|
|
41
|
-
* author reads is stated rather than re-derived.
|
|
42
|
-
*
|
|
43
|
-
* A read-tier that resolves **empty** is skipped silently (the `docsContextFiles`
|
|
44
|
-
* half skips when unconfigured / its files are absent), so a repo with no
|
|
45
|
-
* `CLAUDE.md` and no context docs is a clean no-op.
|
|
46
|
-
*
|
|
47
|
-
* Ratchet semantics (mirroring the sibling ratchets):
|
|
48
|
-
* - A gated tier grows beyond `baseline.tiers.<tier>.totalBytes +
|
|
49
|
-
* baseline.toleranceBytes` → exit 1, naming the tier and its delta.
|
|
50
|
-
* - A gated tier shrinks below its baseline total → **exit 0**, reported as
|
|
51
|
-
* an informational `-` line (Story #5313). This deliberately reverses
|
|
52
|
-
* Story #4872's "shrink fails" rule: that rule made every trim a red gate
|
|
53
|
-
* whose only remedy was a hand-run `--update`, so the gain was paid for
|
|
54
|
-
* twice. The concern it answered — a stale total silently absorbing the
|
|
55
|
-
* next growth — is now met by the close's write-back seam
|
|
56
|
-
* (`story-close/context-budget-writeback.js`), which rewrites the lower
|
|
57
|
-
* total into `baselines/context-budget.json` on the Story branch so the
|
|
58
|
-
* gain locks in without a failing gate. Shrinkage stays zero-tolerance
|
|
59
|
-
* in the *report* (every byte under the total is listed) so a sub-
|
|
60
|
-
* tolerance gain is never discarded by the write-back either.
|
|
61
|
-
* - A recorded row naming a path the measured tier no longer contains →
|
|
62
|
-
* exit 1. The row describes a file that has been deleted or de-listed, so
|
|
63
|
-
* the bytes it contributes to the recorded total are fiction.
|
|
64
|
-
* - Within tolerance / clean → exit 0.
|
|
65
|
-
* - Baseline file absent → warn + exit 0 (no-op; nothing to ratchet against).
|
|
66
|
-
*
|
|
67
|
-
* Tolerance lives in the baseline JSON (`toleranceBytes`) — there is **no**
|
|
68
|
-
* `.agentrc.json` config key; this is a framework-internal dogfooding ratchet,
|
|
69
|
-
* like arch-cycles.
|
|
70
|
-
*
|
|
71
|
-
* Flags:
|
|
72
|
-
* --baseline <path> override the budget path (default
|
|
73
|
-
* `baselines/context-budget.json`, resolved from cwd).
|
|
74
|
-
* --root <path> resolve tiers against an explicit repo root (default cwd).
|
|
75
|
-
* --update reseed the baseline from the current measurement (keeps
|
|
76
|
-
* the existing `toleranceBytes`, or defaults it) and exit 0.
|
|
77
|
-
* --json write the structured envelope to stdout.
|
|
13
|
+
* Flags: --baseline <path>, --root <path>, --update (keeps tolerance), --json.
|
|
78
14
|
*/
|
|
79
15
|
|
|
80
16
|
import fs from 'node:fs';
|
|
@@ -85,143 +21,24 @@ import { resolveConfig } from './lib/config-resolver.js';
|
|
|
85
21
|
import { resolveDocTiers, tierTotalBytes } from './lib/doc-tiers.js';
|
|
86
22
|
|
|
87
23
|
/**
|
|
88
|
-
*
|
|
89
|
-
* and `workflowOnDemand` are resolved by the tier map for the lens, but the
|
|
90
|
-
* byte budget intentionally gates only the tiers a session is *forced* to read.
|
|
24
|
+
* Measured tiers, in report order — only those a session is forced to read.
|
|
91
25
|
* @type {Array<'alwaysLoaded' | 'mandatoryRead' | 'workflow'>}
|
|
92
26
|
*/
|
|
93
|
-
export const
|
|
27
|
+
export const MEASURED_TIERS = ['alwaysLoaded', 'mandatoryRead', 'workflow'];
|
|
94
28
|
|
|
95
29
|
/**
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
* @type {number}
|
|
30
|
+
* Tiers whose drift fails the command; the rest are report-only.
|
|
31
|
+
* @type {Array<'alwaysLoaded'>}
|
|
99
32
|
*/
|
|
100
|
-
export const
|
|
33
|
+
export const ENFORCED_TIERS = ['alwaysLoaded'];
|
|
101
34
|
|
|
102
35
|
/**
|
|
103
|
-
*
|
|
104
|
-
* the read-tiers (gated by a total-byte ratchet), each `.agents/agents/*.md`
|
|
105
|
-
* boot context is a **standalone** system prompt a converted spawn boots on, so
|
|
106
|
-
* the meaningful budget is per-agent, not the sum: no single role def may
|
|
107
|
-
* exceed this ceiling. Adding another role def is legitimate — a per-file gate
|
|
108
|
-
* (rather than a sum ratchet) does not false-positive on that.
|
|
36
|
+
* Seeded by `--update` when the baseline carries none.
|
|
109
37
|
* @type {number}
|
|
110
38
|
*/
|
|
111
|
-
export const
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Return the agent-boot files that exceed the per-file ceiling.
|
|
115
|
-
*
|
|
116
|
-
* @param {{ tiers: Record<string, Array<{ path: string, bytes: number }>> }} tierMap
|
|
117
|
-
* @param {number} ceiling
|
|
118
|
-
* @returns {Array<{ path: string, bytes: number, ceiling: number }>}
|
|
119
|
-
*/
|
|
120
|
-
export function agentBootOverflow(tierMap, ceiling = AGENT_BOOT_CEILING_BYTES) {
|
|
121
|
-
const files = tierMap?.tiers?.agentBoot ?? [];
|
|
122
|
-
return files
|
|
123
|
-
.filter((f) => Number.isFinite(f?.bytes) && f.bytes > ceiling)
|
|
124
|
-
.map((f) => ({ path: f.path, bytes: f.bytes, ceiling }));
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Classify one agent-boot file against its recorded baseline row (#4830).
|
|
129
|
-
* Returns `null` when the row already agrees with the tree.
|
|
130
|
-
*
|
|
131
|
-
* `permissive` drift is the failure class this gate exists for: the row
|
|
132
|
-
* understates the file (or is missing entirely), so the headroom an author
|
|
133
|
-
* computes from it is larger than the headroom that exists, and the shortfall
|
|
134
|
-
* only surfaces as a ceiling failure *after* the edit is written.
|
|
135
|
-
* `restrictive` drift is the benign mirror — the row overstates the file, so an
|
|
136
|
-
* author under-spends and the ceiling gate is never surprised.
|
|
137
|
-
*
|
|
138
|
-
* @param {{ path: string, bytes: number }} file live file measurement
|
|
139
|
-
* @param {{ bytes?: number, headroomBytes?: number } | undefined} row recorded row
|
|
140
|
-
* @param {number} ceiling
|
|
141
|
-
* @returns {{ path: string, recorded: number|null, actual: number, delta: number,
|
|
142
|
-
* direction: 'permissive'|'restrictive', recordedHeadroom: number|null,
|
|
143
|
-
* headroomBytes: number } | null}
|
|
144
|
-
*/
|
|
145
|
-
function classifyBootRow(file, row, ceiling) {
|
|
146
|
-
const actual = file.bytes;
|
|
147
|
-
const headroomBytes = ceiling - actual;
|
|
148
|
-
const recorded = Number.isFinite(row?.bytes) ? row.bytes : null;
|
|
149
|
-
const recordedHeadroom = Number.isFinite(row?.headroomBytes)
|
|
150
|
-
? row.headroomBytes
|
|
151
|
-
: recorded === null
|
|
152
|
-
? null
|
|
153
|
-
: ceiling - recorded;
|
|
154
|
-
// A row is in sync only when both the byte count and the headroom it
|
|
155
|
-
// advertises match the tree — a stale headroom misleads on its own.
|
|
156
|
-
if (recorded === actual && recordedHeadroom === headroomBytes) return null;
|
|
157
|
-
const permissive =
|
|
158
|
-
recorded === null ||
|
|
159
|
-
recorded < actual ||
|
|
160
|
-
(recordedHeadroom !== null && recordedHeadroom > headroomBytes);
|
|
161
|
-
return {
|
|
162
|
-
path: file.path,
|
|
163
|
-
recorded,
|
|
164
|
-
actual,
|
|
165
|
-
delta: recorded === null ? actual : actual - recorded,
|
|
166
|
-
direction: permissive ? 'permissive' : 'restrictive',
|
|
167
|
-
recordedHeadroom,
|
|
168
|
-
headroomBytes,
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Compare every recorded `agentBoot` row against the tree it describes.
|
|
174
|
-
*
|
|
175
|
-
* @param {{ tiers: Record<string, Array<{ path: string, bytes: number }>> }} tierMap
|
|
176
|
-
* @param {{ agentBoot?: { ceilingBytes?: number, files?: Array<{ path: string, bytes: number, headroomBytes?: number }> } } | null} baseline
|
|
177
|
-
* @param {number} [ceiling]
|
|
178
|
-
* @returns {Array<ReturnType<typeof classifyBootRow>>} drift rows (empty = in sync)
|
|
179
|
-
*/
|
|
180
|
-
export function agentBootDrift(tierMap, baseline, ceiling) {
|
|
181
|
-
const recordedCeiling = Number.isFinite(baseline?.agentBoot?.ceilingBytes)
|
|
182
|
-
? baseline.agentBoot.ceilingBytes
|
|
183
|
-
: AGENT_BOOT_CEILING_BYTES;
|
|
184
|
-
const effective = Number.isFinite(ceiling) ? ceiling : recordedCeiling;
|
|
185
|
-
const rows = new Map(
|
|
186
|
-
(baseline?.agentBoot?.files ?? []).map((f) => [f.path, f]),
|
|
187
|
-
);
|
|
188
|
-
const drift = [];
|
|
189
|
-
for (const file of tierMap?.tiers?.agentBoot ?? []) {
|
|
190
|
-
if (!Number.isFinite(file?.bytes)) continue;
|
|
191
|
-
const row = classifyBootRow(file, rows.get(file.path), effective);
|
|
192
|
-
if (row) drift.push(row);
|
|
193
|
-
}
|
|
194
|
-
return drift;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Render the agent-boot drift lines. `+` lines are permissive drift (gate
|
|
199
|
-
* fail); `-` lines are restrictive drift (informational). Each line states the
|
|
200
|
-
* **real** remaining headroom, so the author sizing the next edit reads the
|
|
201
|
-
* true number rather than re-deriving it from a row that just proved stale.
|
|
202
|
-
*
|
|
203
|
-
* @param {Array<ReturnType<typeof classifyBootRow>>} drift
|
|
204
|
-
* @returns {string[]}
|
|
205
|
-
*/
|
|
206
|
-
export function renderBootDrift(drift) {
|
|
207
|
-
return drift.map((d) => {
|
|
208
|
-
const marker = d.direction === 'permissive' ? '+' : '-';
|
|
209
|
-
const recorded =
|
|
210
|
-
d.recorded === null
|
|
211
|
-
? 'has no recorded row'
|
|
212
|
-
: `records ${d.recorded} bytes but the file is ${d.actual}`;
|
|
213
|
-
const note =
|
|
214
|
-
d.direction === 'permissive'
|
|
215
|
-
? 'the row overstates the headroom an author would size an edit against'
|
|
216
|
-
: 'the row is conservative — refresh at leisure';
|
|
217
|
-
return `${marker} agentBoot drift: ${d.path} ${recorded} — ${note} (real headroom ${d.headroomBytes})`;
|
|
218
|
-
});
|
|
219
|
-
}
|
|
39
|
+
export const DEFAULT_TOLERANCE_BYTES = 2048;
|
|
220
40
|
|
|
221
41
|
/**
|
|
222
|
-
* Parse argv for `--baseline <path>`, `--root <path>`, `--update`, `--json`.
|
|
223
|
-
* Exported so unit tests can pin the parser.
|
|
224
|
-
*
|
|
225
42
|
* @param {string[]} argv
|
|
226
43
|
* @returns {{ baselinePath: string|null, rootPath: string|null, update: boolean, json: boolean }}
|
|
227
44
|
*/
|
|
@@ -254,8 +71,7 @@ export function parseArgv(argv = []) {
|
|
|
254
71
|
}
|
|
255
72
|
|
|
256
73
|
/**
|
|
257
|
-
*
|
|
258
|
-
* `null` when the file is missing or unparseable.
|
|
74
|
+
* `null` when missing or unparseable.
|
|
259
75
|
*
|
|
260
76
|
* @param {string} baselinePath
|
|
261
77
|
* @returns {{ toleranceBytes?: number, tiers?: Record<string, { totalBytes: number, files?: Array<{ path: string, bytes: number }> }> } | null}
|
|
@@ -272,29 +88,20 @@ export function loadBaseline(baselinePath) {
|
|
|
272
88
|
}
|
|
273
89
|
|
|
274
90
|
/**
|
|
275
|
-
* Build the committed-baseline envelope from a resolved tier map. Only the
|
|
276
|
-
* gated tiers are recorded (each as `{ totalBytes, files }`).
|
|
277
|
-
*
|
|
278
91
|
* @param {{ tiers: Record<string, Array<{ path: string, bytes: number }>> }} tierMap
|
|
279
92
|
* @param {number} toleranceBytes
|
|
280
93
|
* @returns {object}
|
|
281
94
|
*/
|
|
282
95
|
export function buildBaseline(tierMap, toleranceBytes) {
|
|
283
96
|
const tiers = {};
|
|
284
|
-
for (const name of
|
|
97
|
+
for (const name of MEASURED_TIERS) {
|
|
285
98
|
const files = tierMap.tiers[name] ?? [];
|
|
286
99
|
tiers[name] = { totalBytes: tierTotalBytes(files), files };
|
|
287
100
|
}
|
|
288
|
-
//
|
|
289
|
-
// gated by a per-file ceiling, not the total-byte ratchet the `tiers` entries
|
|
290
|
-
// use — keeping it out of `tiers` keeps the ratchet diff loop unambiguous.
|
|
291
|
-
// Each row carries the headroom it leaves under the ceiling, so an author
|
|
292
|
-
// sizing an edit reads the remaining budget straight off the row (#4830)
|
|
293
|
-
// instead of re-deriving it — and `agentBootDrift` keeps both numbers honest.
|
|
101
|
+
// Top-level, not under `tiers`: a per-file size record with no total to diff.
|
|
294
102
|
const agentBootFiles = (tierMap.tiers.agentBoot ?? []).map((f) => ({
|
|
295
103
|
path: f.path,
|
|
296
104
|
bytes: f.bytes,
|
|
297
|
-
headroomBytes: AGENT_BOOT_CEILING_BYTES - f.bytes,
|
|
298
105
|
}));
|
|
299
106
|
return {
|
|
300
107
|
$schema: 'https://mandrel.dev/baselines/context-budget.schema.json',
|
|
@@ -302,11 +109,9 @@ export function buildBaseline(tierMap, toleranceBytes) {
|
|
|
302
109
|
toleranceBytes,
|
|
303
110
|
tiers,
|
|
304
111
|
agentBoot: {
|
|
305
|
-
ceilingBytes: AGENT_BOOT_CEILING_BYTES,
|
|
306
112
|
files: agentBootFiles,
|
|
307
113
|
},
|
|
308
|
-
// Recorded, never gated
|
|
309
|
-
// entry point. It is a drift signal — the gate is `tiers.workflow`.
|
|
114
|
+
// Recorded, never gated.
|
|
310
115
|
workflowClosure: {
|
|
311
116
|
reachableTotalBytes: tierMap.workflowClosure?.reachableTotalBytes ?? 0,
|
|
312
117
|
entryPoints: tierMap.workflowClosure?.entryPoints ?? [],
|
|
@@ -315,11 +120,8 @@ export function buildBaseline(tierMap, toleranceBytes) {
|
|
|
315
120
|
}
|
|
316
121
|
|
|
317
122
|
/**
|
|
318
|
-
*
|
|
319
|
-
*
|
|
320
|
-
* resolved tier, and so does one that has been de-listed from the read set —
|
|
321
|
-
* either way the row's bytes are counted into a recorded total that no live
|
|
322
|
-
* file backs, so the row is drift and not a detail.
|
|
123
|
+
* Recorded rows naming a path the tier no longer contains (deleted or
|
|
124
|
+
* de-listed) — their bytes inflate the total against nothing.
|
|
323
125
|
*
|
|
324
126
|
* @param {string} tier
|
|
325
127
|
* @param {Array<{ path: string, bytes: number }>} files live tier measurement
|
|
@@ -341,11 +143,7 @@ function absentRows(tier, files, baseTier) {
|
|
|
341
143
|
}
|
|
342
144
|
|
|
343
145
|
/**
|
|
344
|
-
* Pure diff
|
|
345
|
-
* gated tier with no current files is skipped; a tier absent from the baseline
|
|
346
|
-
* is skipped. `grown` and `absent` entries fail the gate; `shrunk` entries are
|
|
347
|
-
* reported and written back by the close (Story #5313) — see the ratchet
|
|
348
|
-
* semantics in the module header.
|
|
146
|
+
* Pure diff against the baseline; empty or unrecorded tiers are skipped.
|
|
349
147
|
*
|
|
350
148
|
* @param {{ tiers: Record<string, Array<{ path: string, bytes: number }>> }} tierMap
|
|
351
149
|
* @param {{ toleranceBytes?: number, tiers?: Record<string, { totalBytes: number }> }} baseline
|
|
@@ -364,7 +162,7 @@ export function diffBudget(tierMap, baseline) {
|
|
|
364
162
|
const shrunk = [];
|
|
365
163
|
const absent = [];
|
|
366
164
|
const skipped = [];
|
|
367
|
-
for (const tier of
|
|
165
|
+
for (const tier of MEASURED_TIERS) {
|
|
368
166
|
const files = tierMap.tiers[tier] ?? [];
|
|
369
167
|
const current = tierTotalBytes(files);
|
|
370
168
|
const baseTier = baseline?.tiers?.[tier];
|
|
@@ -386,9 +184,7 @@ export function diffBudget(tierMap, baseline) {
|
|
|
386
184
|
delta: current - baselineBytes,
|
|
387
185
|
});
|
|
388
186
|
} else if (current < baselineBytes) {
|
|
389
|
-
//
|
|
390
|
-
// churn from a trivial *addition*; mirroring it downward would hide a
|
|
391
|
-
// gain from the write-back that locks it in (Story #5313).
|
|
187
|
+
// Zero-tolerance downward, so the write-back never misses a small gain.
|
|
392
188
|
shrunk.push({
|
|
393
189
|
tier,
|
|
394
190
|
current,
|
|
@@ -402,33 +198,51 @@ export function diffBudget(tierMap, baseline) {
|
|
|
402
198
|
}
|
|
403
199
|
|
|
404
200
|
/**
|
|
405
|
-
*
|
|
406
|
-
*
|
|
407
|
-
|
|
408
|
-
|
|
201
|
+
* @param {{ tier?: string }} entry
|
|
202
|
+
* @returns {boolean}
|
|
203
|
+
*/
|
|
204
|
+
function isEnforced(entry) {
|
|
205
|
+
return ENFORCED_TIERS.includes(entry?.tier);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* The single definition of the failure set: enforced-tier `grown` + `absent`.
|
|
409
210
|
*
|
|
410
211
|
* @param {ReturnType<typeof diffBudget>} diff
|
|
411
212
|
* @returns {number}
|
|
412
213
|
*/
|
|
413
214
|
export function budgetFailureCount(diff) {
|
|
414
|
-
|
|
215
|
+
const grown = (diff?.grown ?? []).filter(isEnforced).length;
|
|
216
|
+
const absent = (diff?.absent ?? []).filter(isEnforced).length;
|
|
217
|
+
return grown + absent;
|
|
415
218
|
}
|
|
416
219
|
|
|
220
|
+
const REPORT_ONLY_NOTE = ' — reported, never gated';
|
|
221
|
+
|
|
417
222
|
/**
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
* (informational — the close writes the lower total back) or rows naming a
|
|
421
|
-
* path the tree no longer carries (a gate failure). A one-line summary
|
|
422
|
-
* always follows.
|
|
223
|
+
* A report-only row is marked `~` with an inline note, so the line itself
|
|
224
|
+
* says whether it broke the build.
|
|
423
225
|
*
|
|
226
|
+
* @param {{ tier: string }} row
|
|
227
|
+
* @param {string} enforcedPrefix
|
|
228
|
+
* @returns {{ prefix: string, note: string }}
|
|
229
|
+
*/
|
|
230
|
+
function gateMarks(row, enforcedPrefix) {
|
|
231
|
+
return isEnforced(row)
|
|
232
|
+
? { prefix: enforcedPrefix, note: '' }
|
|
233
|
+
: { prefix: '~', note: REPORT_ONLY_NOTE };
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
424
237
|
* @param {ReturnType<typeof diffBudget>} diff
|
|
425
238
|
* @returns {string}
|
|
426
239
|
*/
|
|
427
240
|
export function renderDiff(diff) {
|
|
428
241
|
const lines = [];
|
|
429
242
|
for (const g of diff.grown) {
|
|
243
|
+
const { prefix, note } = gateMarks(g, '+');
|
|
430
244
|
lines.push(
|
|
431
|
-
|
|
245
|
+
`${prefix} ${g.tier}: ${g.current} bytes exceeds budget ${g.baseline} + tolerance ${g.tolerance} (delta +${g.delta})${note}`,
|
|
432
246
|
);
|
|
433
247
|
}
|
|
434
248
|
for (const s of diff.shrunk) {
|
|
@@ -437,8 +251,9 @@ export function renderDiff(diff) {
|
|
|
437
251
|
);
|
|
438
252
|
}
|
|
439
253
|
for (const a of diff.absent ?? []) {
|
|
254
|
+
const { prefix, note } = gateMarks(a, '-');
|
|
440
255
|
lines.push(
|
|
441
|
-
|
|
256
|
+
`${prefix} ${a.tier}: recorded row ${a.path} names a path the measured tier no longer contains — refresh baselines/context-budget.json${note}`,
|
|
442
257
|
);
|
|
443
258
|
}
|
|
444
259
|
const tag = budgetFailureCount(diff) > 0 ? '(gate fail)' : '(ok)';
|
|
@@ -449,9 +264,7 @@ export function renderDiff(diff) {
|
|
|
449
264
|
}
|
|
450
265
|
|
|
451
266
|
/**
|
|
452
|
-
*
|
|
453
|
-
* (Story #4752). Returns `''` when there is no workflow tier to report, so the
|
|
454
|
-
* caller can stay a one-liner.
|
|
267
|
+
* The workflow reachable-closure line, or `''`.
|
|
455
268
|
*
|
|
456
269
|
* @param {{ workflowClosure?: { reachableTotalBytes?: number, entryPoints?: unknown[] } }} tierMap
|
|
457
270
|
* @param {{ workflowClosure?: { reachableTotalBytes?: number } } | null} [baseline]
|
|
@@ -468,22 +281,20 @@ export function renderReachable(tierMap, baseline) {
|
|
|
468
281
|
}
|
|
469
282
|
|
|
470
283
|
/**
|
|
471
|
-
*
|
|
472
|
-
* tmpdir fixture with an injected config and sinks.
|
|
284
|
+
* The agent-boot size line (total and largest role def), or `''`.
|
|
473
285
|
*
|
|
474
|
-
* @param {{
|
|
475
|
-
*
|
|
476
|
-
* cwd?: string,
|
|
477
|
-
* config?: object,
|
|
478
|
-
* stdout?: { write: (s: string) => void },
|
|
479
|
-
* stderr?: { write: (s: string) => void },
|
|
480
|
-
* }} [opts]
|
|
481
|
-
* @returns {Promise<number>} 0 = clean / within tolerance / shrink-only / no-op;
|
|
482
|
-
* 1 = a gated tier grew beyond tolerance or a recorded row is unbacked
|
|
286
|
+
* @param {{ tiers?: { agentBoot?: Array<{ path: string, bytes: number }> } }} tierMap
|
|
287
|
+
* @returns {string}
|
|
483
288
|
*/
|
|
289
|
+
function renderAgentBoot(tierMap) {
|
|
290
|
+
const files = tierMap?.tiers?.agentBoot ?? [];
|
|
291
|
+
if (files.length === 0) return '';
|
|
292
|
+
const largest = files.reduce((a, b) => (b.bytes > a.bytes ? b : a));
|
|
293
|
+
return ` agentBoot: ${tierTotalBytes(files)} bytes across ${files.length} role defs, largest ${largest.path} at ${largest.bytes} — reported, never gated`;
|
|
294
|
+
}
|
|
295
|
+
|
|
484
296
|
/**
|
|
485
|
-
*
|
|
486
|
-
* silently widens the gate it is refreshing.
|
|
297
|
+
* Preserves the recorded tolerance so `--update` never widens the gate.
|
|
487
298
|
*
|
|
488
299
|
* @param {object} params
|
|
489
300
|
* @returns {0}
|
|
@@ -512,9 +323,6 @@ function writeUpdatedBaseline({ tierMap, resolvedBaselinePath, json, stdout }) {
|
|
|
512
323
|
}
|
|
513
324
|
|
|
514
325
|
/**
|
|
515
|
-
* An absent budget is a no-op, not a failure: a consumer that has never
|
|
516
|
-
* recorded one has nothing to regress against.
|
|
517
|
-
*
|
|
518
326
|
* @param {object} params
|
|
519
327
|
* @returns {0}
|
|
520
328
|
*/
|
|
@@ -527,7 +335,7 @@ function reportMissingBaseline({
|
|
|
527
335
|
}) {
|
|
528
336
|
if (json) {
|
|
529
337
|
stdout.write(
|
|
530
|
-
`${JSON.stringify({ kind: 'context-budget-report', baselinePath: resolvedBaselinePath, tiers: tierMap.tiers, grown: [], shrunk: [], absent: [], skipped:
|
|
338
|
+
`${JSON.stringify({ kind: 'context-budget-report', baselinePath: resolvedBaselinePath, tiers: tierMap.tiers, grown: [], shrunk: [], absent: [], skipped: MEASURED_TIERS, exitCode: 0, noBaseline: true }, null, 2)}\n`,
|
|
531
339
|
);
|
|
532
340
|
} else {
|
|
533
341
|
stderr.write(
|
|
@@ -538,28 +346,14 @@ function reportMissingBaseline({
|
|
|
538
346
|
}
|
|
539
347
|
|
|
540
348
|
/**
|
|
541
|
-
*
|
|
542
|
-
* renderers below present is decided here, so they cannot disagree about what
|
|
543
|
-
* failed or drift apart in which fields they surface.
|
|
349
|
+
* Every verdict is decided here, so the two renderers cannot disagree.
|
|
544
350
|
*
|
|
545
351
|
* @param {{ tierMap: object, baseline: object }} params
|
|
546
|
-
* @returns {{ diff: object,
|
|
352
|
+
* @returns {{ diff: object, exitCode: 0 | 1 }}
|
|
547
353
|
*/
|
|
548
354
|
function evaluateBudget({ tierMap, baseline }) {
|
|
549
355
|
const diff = diffBudget(tierMap, baseline);
|
|
550
|
-
|
|
551
|
-
? baseline.agentBoot.ceilingBytes
|
|
552
|
-
: AGENT_BOOT_CEILING_BYTES;
|
|
553
|
-
const bootOverflow = agentBootOverflow(tierMap, ceiling);
|
|
554
|
-
const bootDrift = agentBootDrift(tierMap, baseline, ceiling);
|
|
555
|
-
const permissiveDrift = bootDrift.filter((d) => d.direction === 'permissive');
|
|
556
|
-
const exitCode =
|
|
557
|
-
budgetFailureCount(diff) > 0 ||
|
|
558
|
-
bootOverflow.length > 0 ||
|
|
559
|
-
permissiveDrift.length > 0
|
|
560
|
-
? 1
|
|
561
|
-
: 0;
|
|
562
|
-
return { diff, ceiling, bootOverflow, bootDrift, permissiveDrift, exitCode };
|
|
356
|
+
return { diff, exitCode: budgetFailureCount(diff) > 0 ? 1 : 0 };
|
|
563
357
|
}
|
|
564
358
|
|
|
565
359
|
/**
|
|
@@ -573,7 +367,7 @@ function renderJsonReport({
|
|
|
573
367
|
report,
|
|
574
368
|
stdout,
|
|
575
369
|
}) {
|
|
576
|
-
const { diff,
|
|
370
|
+
const { diff, exitCode } = report;
|
|
577
371
|
const envelope = {
|
|
578
372
|
kind: 'context-budget-report',
|
|
579
373
|
baselinePath: resolvedBaselinePath,
|
|
@@ -581,15 +375,14 @@ function renderJsonReport({
|
|
|
581
375
|
? baseline.toleranceBytes
|
|
582
376
|
: 0,
|
|
583
377
|
current: Object.fromEntries(
|
|
584
|
-
|
|
378
|
+
MEASURED_TIERS.map((t) => [t, tierTotalBytes(tierMap.tiers[t] ?? [])]),
|
|
585
379
|
),
|
|
586
380
|
grown: diff.grown,
|
|
587
381
|
shrunk: diff.shrunk,
|
|
588
382
|
absent: diff.absent,
|
|
589
383
|
skipped: diff.skipped,
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
agentBootDrift: bootDrift,
|
|
384
|
+
enforcedTiers: ENFORCED_TIERS,
|
|
385
|
+
agentBoot: tierMap.tiers?.agentBoot ?? [],
|
|
593
386
|
workflowReachableBytes: tierMap.workflowClosure?.reachableTotalBytes ?? 0,
|
|
594
387
|
exitCode,
|
|
595
388
|
};
|
|
@@ -597,58 +390,59 @@ function renderJsonReport({
|
|
|
597
390
|
}
|
|
598
391
|
|
|
599
392
|
/**
|
|
600
|
-
*
|
|
601
|
-
* differently (trim a role def vs refresh the budget), so a single generic
|
|
602
|
-
* message would leave the author guessing which applies.
|
|
393
|
+
* One remediation line per failing condition (each is fixed differently).
|
|
603
394
|
*
|
|
604
395
|
* @param {object} params
|
|
605
396
|
* @returns {void}
|
|
606
397
|
*/
|
|
607
398
|
function renderFailureDiagnostics({ report, stderr }) {
|
|
608
|
-
const { diff
|
|
609
|
-
if (
|
|
610
|
-
stderr.write(
|
|
611
|
-
`[context-budget] ❌ a recorded agentBoot row understates the file it describes, so it overstates the headroom an author would size an edit against — refresh it with \`node .agents/scripts/check-context-budget.js --update\` (the ceiling is unchanged)\n`,
|
|
612
|
-
);
|
|
613
|
-
}
|
|
614
|
-
if (bootOverflow.length > 0) {
|
|
399
|
+
const { diff } = report;
|
|
400
|
+
if (diff.grown.some(isEnforced)) {
|
|
615
401
|
stderr.write(
|
|
616
|
-
`[context-budget] ❌
|
|
402
|
+
`[context-budget] ❌ the always-loaded documentation tier grew beyond tolerance — every session and every subagent spawn re-pays it. Refresh the budget consciously with \`node .agents/scripts/check-context-budget.js --update\` once the growth is intentional\n`,
|
|
617
403
|
);
|
|
618
404
|
}
|
|
619
|
-
if (diff.
|
|
405
|
+
if (diff.absent.some(isEnforced)) {
|
|
620
406
|
stderr.write(
|
|
621
|
-
`[context-budget] ❌ a
|
|
622
|
-
);
|
|
623
|
-
}
|
|
624
|
-
if (diff.absent.length > 0) {
|
|
625
|
-
stderr.write(
|
|
626
|
-
`[context-budget] ❌ a recorded row names a path the measured tier no longer contains — its bytes inflate the recorded total against nothing. Refresh with \`node .agents/scripts/check-context-budget.js --update\`\n`,
|
|
407
|
+
`[context-budget] ❌ a recorded always-loaded row names a path the measured tier no longer contains — its bytes inflate the recorded total against nothing. Refresh with \`node .agents/scripts/check-context-budget.js --update\`\n`,
|
|
627
408
|
);
|
|
628
409
|
}
|
|
629
410
|
}
|
|
630
411
|
|
|
412
|
+
/**
|
|
413
|
+
* @param {{ tierMap: object, baseline: object | null }} params
|
|
414
|
+
* @returns {string[]}
|
|
415
|
+
*/
|
|
416
|
+
function optionalReportLines({ tierMap, baseline }) {
|
|
417
|
+
return [renderReachable(tierMap, baseline), renderAgentBoot(tierMap)].filter(
|
|
418
|
+
Boolean,
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
|
|
631
422
|
/**
|
|
632
423
|
* @param {object} params
|
|
633
424
|
* @returns {void}
|
|
634
425
|
*/
|
|
635
426
|
function renderTextReport({ tierMap, baseline, report, stdout, stderr }) {
|
|
636
|
-
const { diff,
|
|
427
|
+
const { diff, exitCode } = report;
|
|
637
428
|
stdout.write(`\n--- context-budget preview ---\n`);
|
|
638
429
|
stdout.write(`${renderDiff(diff)}\n`);
|
|
639
|
-
const
|
|
640
|
-
if (reachable) stdout.write(`${reachable}\n`);
|
|
641
|
-
for (const o of bootOverflow) {
|
|
642
|
-
stdout.write(
|
|
643
|
-
`+ agentBoot: ${o.path} is ${o.bytes} bytes, over the ${o.ceiling}-byte per-agent ceiling\n`,
|
|
644
|
-
);
|
|
645
|
-
}
|
|
646
|
-
for (const line of renderBootDrift(bootDrift)) {
|
|
430
|
+
for (const line of optionalReportLines({ tierMap, baseline })) {
|
|
647
431
|
stdout.write(`${line}\n`);
|
|
648
432
|
}
|
|
649
433
|
if (exitCode === 1) renderFailureDiagnostics({ report, stderr });
|
|
650
434
|
}
|
|
651
435
|
|
|
436
|
+
/**
|
|
437
|
+
* @param {{
|
|
438
|
+
* argv?: string[],
|
|
439
|
+
* cwd?: string,
|
|
440
|
+
* config?: object,
|
|
441
|
+
* stdout?: { write: (s: string) => void },
|
|
442
|
+
* stderr?: { write: (s: string) => void },
|
|
443
|
+
* }} [opts]
|
|
444
|
+
* @returns {Promise<number>} 1 only for enforced-tier drift.
|
|
445
|
+
*/
|
|
652
446
|
export async function runCli({
|
|
653
447
|
argv = process.argv.slice(2),
|
|
654
448
|
cwd = process.cwd(),
|