mandrel 2.60.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 +10 -10
- package/.agents/agents/story-worker.md +1 -1
- package/.agents/docs/agentrc-reference.json +4 -82
- package/.agents/docs/configuration.md +20 -87
- package/.agents/docs/workflows.md +1 -1
- package/.agents/instructions.md +1 -3
- package/.agents/rules/gherkin-standards.md +4 -0
- package/.agents/schemas/agentrc.schema.json +11 -486
- package/.agents/schemas/story-deliver-terminal.schema.json +10 -0
- package/.agents/schemas/validation-evidence.schema.json +2 -1
- package/.agents/scripts/README.md +14 -14
- package/.agents/scripts/acceptance-eval.js +32 -164
- 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 +9 -45
- package/.agents/scripts/check-arch-cycles.js +14 -64
- package/.agents/scripts/check-baselines.js +8 -48
- package/.agents/scripts/check-context-budget.js +46 -172
- 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 +32 -99
- package/.agents/scripts/deliver-light.js +14 -101
- package/.agents/scripts/deliver-recover.js +6 -42
- package/.agents/scripts/deliver-run.js +36 -133
- 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 +10 -50
- 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 +5 -21
- 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 +31 -143
- 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 -35
- package/.agents/scripts/lib/config/explain.js +9 -80
- package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +2 -30
- 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 +10 -52
- package/.agents/scripts/lib/config-schema-shared.js +1 -4
- package/.agents/scripts/lib/config-settings-schema-delivery.js +12 -294
- 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 +12 -37
- package/.agents/scripts/lib/coverage-capture-incremental.js +12 -43
- package/.agents/scripts/lib/coverage-capture-usage.js +4 -24
- 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 -126
- 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 +93 -419
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -151
- 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 +31 -259
- 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 +21 -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 +5 -75
- 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 +42 -189
- 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 +42 -214
- 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 +26 -231
- 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 +52 -303
- 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 +14 -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 +49 -248
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
- 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 -94
- 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 +40 -199
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
- 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 +18 -80
- 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 +9 -50
- 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 +110 -290
- 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 -201
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
- package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
- 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 -126
- 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 +39 -181
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
- 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 +22 -83
- package/.agents/scripts/lib/story-body/footer-block.js +11 -44
- package/.agents/scripts/lib/story-body/story-body.js +83 -358
- package/.agents/scripts/lib/temp-retention.js +42 -143
- package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
- 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 +53 -221
- 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 -104
- package/.agents/scripts/nav-registry-diff.js +22 -108
- package/.agents/scripts/notify.js +12 -69
- package/.agents/scripts/plan-context.js +27 -111
- package/.agents/scripts/plan-critics.js +12 -66
- package/.agents/scripts/plan-persist.js +31 -148
- package/.agents/scripts/plan-run-epilogue.js +11 -37
- package/.agents/scripts/pr-watch-with-update.js +76 -267
- 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 -209
- package/.agents/scripts/stories-wave-tick.js +102 -472
- 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/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/audit-lens-core.md +1 -1
- package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
- package/.agents/workflows/helpers/deliver-digest.md +6 -4
- package/.agents/workflows/helpers/deliver-reference.md +114 -188
- package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
- package/.agents/workflows/helpers/plan-reference.md +86 -139
- package/.agents/workflows/helpers/qa-core.md +12 -0
- 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 +25 -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 +105 -661
- 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 +15 -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 +2 -21
- package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
- package/package.json +16 -14
- package/.agents/docs/SDLC.md +0 -590
- package/.agents/docs/quality-gates.md +0 -1183
- package/.agents/rules/known-tooling-behavior.md +0 -200
- 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/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 -368
- package/.agents/scripts/check-test-portability.js +0 -512
- package/.agents/scripts/check-workflow-citations.js +0 -218
- 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/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 -125
- package/.agents/scripts/test-isolate.js +0 -55
- package/.agents/scripts/update-dead-exports-baseline.js +0 -321
|
@@ -1,74 +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.
|
|
19
|
-
*
|
|
20
|
-
* **One tier gates: `alwaysLoaded`.** It is the only tier every session and
|
|
21
|
-
* every subagent spawn pays unconditionally, so growth there is a real tax on
|
|
22
|
-
* every future turn. The other tiers are measured, recorded and printed, and
|
|
23
|
-
* never fail the command (Story #5340). Demoting them is what makes workflow
|
|
24
|
-
* prose editable again: under the old rule a prose fix had to be paid for with
|
|
25
|
-
* an unrelated trim in the same commit, and that is how three reference
|
|
26
|
-
* sections came to describe mechanisms the code had already retired. The
|
|
27
|
-
* measurement is still worth seeing on every change, so it is kept as a
|
|
28
|
-
* report rather than deleted. See `docs/decisions.md`, ADR 20260917-5340.
|
|
29
|
-
*
|
|
30
|
-
* The role-scoped agent-boot tier (`.agents/agents/*.md`) is recorded the same
|
|
31
|
-
* way. Its former per-file 8 KB ceiling and the row-vs-tree drift gate are
|
|
32
|
-
* gone with the same ADR — nothing enforces a per-file ceiling or a minimum
|
|
33
|
-
* headroom on a workflow or agent file any more.
|
|
34
|
-
*
|
|
35
|
-
* A read-tier that resolves **empty** is skipped silently (the `docsContextFiles`
|
|
36
|
-
* half skips when unconfigured / its files are absent), so a repo with no
|
|
37
|
-
* `CLAUDE.md` and no context docs is a clean no-op.
|
|
38
|
-
*
|
|
39
|
-
* Ratchet semantics (mirroring the sibling ratchets):
|
|
40
|
-
* - The `alwaysLoaded` tier grows beyond `baseline.tiers.alwaysLoaded
|
|
41
|
-
* .totalBytes + baseline.toleranceBytes` → exit 1, naming the tier and its
|
|
42
|
-
* delta. Growth in any other measured tier is printed and exits 0.
|
|
43
|
-
* - A measured tier shrinks below its baseline total → **exit 0**, reported
|
|
44
|
-
* as an informational `-` line (Story #5313). This deliberately reverses
|
|
45
|
-
* Story #4872's "shrink fails" rule: that rule made every trim a red gate
|
|
46
|
-
* whose only remedy was a hand-run `--update`, so the gain was paid for
|
|
47
|
-
* twice. The concern it answered — a stale total silently absorbing the
|
|
48
|
-
* next growth — is now met by the close's write-back seam
|
|
49
|
-
* (`story-close/context-budget-writeback.js`), which rewrites the lower
|
|
50
|
-
* total into `baselines/context-budget.json` on the Story branch so the
|
|
51
|
-
* gain locks in without a failing gate. Shrinkage stays zero-tolerance
|
|
52
|
-
* in the *report* (every byte under the total is listed) so a sub-
|
|
53
|
-
* tolerance gain is never discarded by the write-back either.
|
|
54
|
-
* - A recorded `alwaysLoaded` row naming a path the measured tier no longer
|
|
55
|
-
* contains → exit 1. The row describes a file that has been deleted or
|
|
56
|
-
* de-listed, so the bytes it contributes to the recorded total are fiction.
|
|
57
|
-
* The same drift in a report-only tier is printed, not failed.
|
|
58
|
-
* - Within tolerance / clean → exit 0.
|
|
59
|
-
* - Baseline file absent → warn + exit 0 (no-op; nothing to ratchet against).
|
|
60
|
-
*
|
|
61
|
-
* Tolerance lives in the baseline JSON (`toleranceBytes`) — there is **no**
|
|
62
|
-
* `.agentrc.json` config key; this is a framework-internal dogfooding ratchet,
|
|
63
|
-
* like arch-cycles.
|
|
64
|
-
*
|
|
65
|
-
* Flags:
|
|
66
|
-
* --baseline <path> override the budget path (default
|
|
67
|
-
* `baselines/context-budget.json`, resolved from cwd).
|
|
68
|
-
* --root <path> resolve tiers against an explicit repo root (default cwd).
|
|
69
|
-
* --update reseed the baseline from the current measurement (keeps
|
|
70
|
-
* the existing `toleranceBytes`, or defaults it) and exit 0.
|
|
71
|
-
* --json write the structured envelope to stdout.
|
|
13
|
+
* Flags: --baseline <path>, --root <path>, --update (keeps tolerance), --json.
|
|
72
14
|
*/
|
|
73
15
|
|
|
74
16
|
import fs from 'node:fs';
|
|
@@ -79,34 +21,24 @@ import { resolveConfig } from './lib/config-resolver.js';
|
|
|
79
21
|
import { resolveDocTiers, tierTotalBytes } from './lib/doc-tiers.js';
|
|
80
22
|
|
|
81
23
|
/**
|
|
82
|
-
*
|
|
83
|
-
* `digestVisible`, `onDemand` and `workflowOnDemand` are resolved by the tier
|
|
84
|
-
* map for the lens, but the byte budget intentionally measures only the tiers
|
|
85
|
-
* a session is *forced* to read.
|
|
24
|
+
* Measured tiers, in report order — only those a session is forced to read.
|
|
86
25
|
* @type {Array<'alwaysLoaded' | 'mandatoryRead' | 'workflow'>}
|
|
87
26
|
*/
|
|
88
27
|
export const MEASURED_TIERS = ['alwaysLoaded', 'mandatoryRead', 'workflow'];
|
|
89
28
|
|
|
90
29
|
/**
|
|
91
|
-
*
|
|
92
|
-
* is paid by every session and every subagent spawn unconditionally, so it is
|
|
93
|
-
* the one tier where growth is a tax nobody opted into. Everything else in
|
|
94
|
-
* {@link MEASURED_TIERS} is a report.
|
|
30
|
+
* Tiers whose drift fails the command; the rest are report-only.
|
|
95
31
|
* @type {Array<'alwaysLoaded'>}
|
|
96
32
|
*/
|
|
97
33
|
export const ENFORCED_TIERS = ['alwaysLoaded'];
|
|
98
34
|
|
|
99
35
|
/**
|
|
100
|
-
*
|
|
101
|
-
* existing baseline carries none.
|
|
36
|
+
* Seeded by `--update` when the baseline carries none.
|
|
102
37
|
* @type {number}
|
|
103
38
|
*/
|
|
104
39
|
export const DEFAULT_TOLERANCE_BYTES = 2048;
|
|
105
40
|
|
|
106
41
|
/**
|
|
107
|
-
* Parse argv for `--baseline <path>`, `--root <path>`, `--update`, `--json`.
|
|
108
|
-
* Exported so unit tests can pin the parser.
|
|
109
|
-
*
|
|
110
42
|
* @param {string[]} argv
|
|
111
43
|
* @returns {{ baselinePath: string|null, rootPath: string|null, update: boolean, json: boolean }}
|
|
112
44
|
*/
|
|
@@ -139,8 +71,7 @@ export function parseArgv(argv = []) {
|
|
|
139
71
|
}
|
|
140
72
|
|
|
141
73
|
/**
|
|
142
|
-
*
|
|
143
|
-
* `null` when the file is missing or unparseable.
|
|
74
|
+
* `null` when missing or unparseable.
|
|
144
75
|
*
|
|
145
76
|
* @param {string} baselinePath
|
|
146
77
|
* @returns {{ toleranceBytes?: number, tiers?: Record<string, { totalBytes: number, files?: Array<{ path: string, bytes: number }> }> } | null}
|
|
@@ -157,9 +88,6 @@ export function loadBaseline(baselinePath) {
|
|
|
157
88
|
}
|
|
158
89
|
|
|
159
90
|
/**
|
|
160
|
-
* Build the committed-baseline envelope from a resolved tier map. Only the
|
|
161
|
-
* measured tiers are recorded (each as `{ totalBytes, files }`).
|
|
162
|
-
*
|
|
163
91
|
* @param {{ tiers: Record<string, Array<{ path: string, bytes: number }>> }} tierMap
|
|
164
92
|
* @param {number} toleranceBytes
|
|
165
93
|
* @returns {object}
|
|
@@ -170,10 +98,7 @@ export function buildBaseline(tierMap, toleranceBytes) {
|
|
|
170
98
|
const files = tierMap.tiers[name] ?? [];
|
|
171
99
|
tiers[name] = { totalBytes: tierTotalBytes(files), files };
|
|
172
100
|
}
|
|
173
|
-
//
|
|
174
|
-
// carries no recorded total to diff against — it is a per-file size record
|
|
175
|
-
// the audit instruments read as hotspot rows. Keeping it out of `tiers`
|
|
176
|
-
// keeps the ratchet diff loop unambiguous.
|
|
101
|
+
// Top-level, not under `tiers`: a per-file size record with no total to diff.
|
|
177
102
|
const agentBootFiles = (tierMap.tiers.agentBoot ?? []).map((f) => ({
|
|
178
103
|
path: f.path,
|
|
179
104
|
bytes: f.bytes,
|
|
@@ -186,8 +111,7 @@ export function buildBaseline(tierMap, toleranceBytes) {
|
|
|
186
111
|
agentBoot: {
|
|
187
112
|
files: agentBootFiles,
|
|
188
113
|
},
|
|
189
|
-
// Recorded, never gated
|
|
190
|
-
// entry point.
|
|
114
|
+
// Recorded, never gated.
|
|
191
115
|
workflowClosure: {
|
|
192
116
|
reachableTotalBytes: tierMap.workflowClosure?.reachableTotalBytes ?? 0,
|
|
193
117
|
entryPoints: tierMap.workflowClosure?.entryPoints ?? [],
|
|
@@ -196,11 +120,8 @@ export function buildBaseline(tierMap, toleranceBytes) {
|
|
|
196
120
|
}
|
|
197
121
|
|
|
198
122
|
/**
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* resolved tier, and so does one that has been de-listed from the read set —
|
|
202
|
-
* either way the row's bytes are counted into a recorded total that no live
|
|
203
|
-
* 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.
|
|
204
125
|
*
|
|
205
126
|
* @param {string} tier
|
|
206
127
|
* @param {Array<{ path: string, bytes: number }>} files live tier measurement
|
|
@@ -222,12 +143,7 @@ function absentRows(tier, files, baseTier) {
|
|
|
222
143
|
}
|
|
223
144
|
|
|
224
145
|
/**
|
|
225
|
-
* Pure diff
|
|
226
|
-
* measured tier with no current files is skipped; a tier absent from the
|
|
227
|
-
* baseline is skipped. `grown` and `absent` entries in an {@link
|
|
228
|
-
* ENFORCED_TIERS} tier fail the gate; every other entry — and every `shrunk`
|
|
229
|
-
* entry — is reported (Story #5340, Story #5313) and `shrunk` is what the
|
|
230
|
-
* close writes back. See the ratchet semantics in the module header.
|
|
146
|
+
* Pure diff against the baseline; empty or unrecorded tiers are skipped.
|
|
231
147
|
*
|
|
232
148
|
* @param {{ tiers: Record<string, Array<{ path: string, bytes: number }>> }} tierMap
|
|
233
149
|
* @param {{ toleranceBytes?: number, tiers?: Record<string, { totalBytes: number }> }} baseline
|
|
@@ -268,9 +184,7 @@ export function diffBudget(tierMap, baseline) {
|
|
|
268
184
|
delta: current - baselineBytes,
|
|
269
185
|
});
|
|
270
186
|
} else if (current < baselineBytes) {
|
|
271
|
-
//
|
|
272
|
-
// churn from a trivial *addition*; mirroring it downward would hide a
|
|
273
|
-
// gain from the write-back that locks it in (Story #5313).
|
|
187
|
+
// Zero-tolerance downward, so the write-back never misses a small gain.
|
|
274
188
|
shrunk.push({
|
|
275
189
|
tier,
|
|
276
190
|
current,
|
|
@@ -284,8 +198,6 @@ export function diffBudget(tierMap, baseline) {
|
|
|
284
198
|
}
|
|
285
199
|
|
|
286
200
|
/**
|
|
287
|
-
* True when a diff entry belongs to a tier whose drift still fails the gate.
|
|
288
|
-
*
|
|
289
201
|
* @param {{ tier?: string }} entry
|
|
290
202
|
* @returns {boolean}
|
|
291
203
|
*/
|
|
@@ -294,11 +206,7 @@ function isEnforced(entry) {
|
|
|
294
206
|
}
|
|
295
207
|
|
|
296
208
|
/**
|
|
297
|
-
*
|
|
298
|
-
* recorded row the tree no longer backs, **in an {@link ENFORCED_TIERS} tier
|
|
299
|
-
* only** (Story #5340). Shrinkage is not in the set (Story #5313 — the close
|
|
300
|
-
* writes it back instead). This is the one place the failure set is defined
|
|
301
|
-
* and both the summary tag and the exit code read it.
|
|
209
|
+
* The single definition of the failure set: enforced-tier `grown` + `absent`.
|
|
302
210
|
*
|
|
303
211
|
* @param {ReturnType<typeof diffBudget>} diff
|
|
304
212
|
* @returns {number}
|
|
@@ -309,25 +217,11 @@ export function budgetFailureCount(diff) {
|
|
|
309
217
|
return grown + absent;
|
|
310
218
|
}
|
|
311
219
|
|
|
312
|
-
/**
|
|
313
|
-
* Render the human-readable diff. `+` lines are enforced tiers that grew
|
|
314
|
-
* beyond tolerance; `-` lines are tiers that shrank below their recorded total
|
|
315
|
-
* (informational — the close writes the lower total back) or rows naming a
|
|
316
|
-
* path the tree no longer carries. Drift in a report-only tier is prefixed
|
|
317
|
-
* with `~` and says so on the line, so a reader never has to cross-reference
|
|
318
|
-
* {@link ENFORCED_TIERS} to know whether it broke the build. A one-line
|
|
319
|
-
* summary always follows.
|
|
320
|
-
*
|
|
321
|
-
* @param {ReturnType<typeof diffBudget>} diff
|
|
322
|
-
* @returns {string}
|
|
323
|
-
*/
|
|
324
220
|
const REPORT_ONLY_NOTE = ' — reported, never gated';
|
|
325
221
|
|
|
326
222
|
/**
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
* with `~` and says so inline, so a reader never has to cross-reference
|
|
330
|
-
* {@link ENFORCED_TIERS} to know whether the line broke the build.
|
|
223
|
+
* A report-only row is marked `~` with an inline note, so the line itself
|
|
224
|
+
* says whether it broke the build.
|
|
331
225
|
*
|
|
332
226
|
* @param {{ tier: string }} row
|
|
333
227
|
* @param {string} enforcedPrefix
|
|
@@ -339,6 +233,10 @@ function gateMarks(row, enforcedPrefix) {
|
|
|
339
233
|
: { prefix: '~', note: REPORT_ONLY_NOTE };
|
|
340
234
|
}
|
|
341
235
|
|
|
236
|
+
/**
|
|
237
|
+
* @param {ReturnType<typeof diffBudget>} diff
|
|
238
|
+
* @returns {string}
|
|
239
|
+
*/
|
|
342
240
|
export function renderDiff(diff) {
|
|
343
241
|
const lines = [];
|
|
344
242
|
for (const g of diff.grown) {
|
|
@@ -366,9 +264,7 @@ export function renderDiff(diff) {
|
|
|
366
264
|
}
|
|
367
265
|
|
|
368
266
|
/**
|
|
369
|
-
*
|
|
370
|
-
* (Story #4752). Returns `''` when there is no workflow tier to report, so the
|
|
371
|
-
* caller can stay a one-liner.
|
|
267
|
+
* The workflow reachable-closure line, or `''`.
|
|
372
268
|
*
|
|
373
269
|
* @param {{ workflowClosure?: { reachableTotalBytes?: number, entryPoints?: unknown[] } }} tierMap
|
|
374
270
|
* @param {{ workflowClosure?: { reachableTotalBytes?: number } } | null} [baseline]
|
|
@@ -385,11 +281,7 @@ export function renderReachable(tierMap, baseline) {
|
|
|
385
281
|
}
|
|
386
282
|
|
|
387
283
|
/**
|
|
388
|
-
*
|
|
389
|
-
* #5340 removed the per-file ceiling. It names the largest boot context
|
|
390
|
-
* because that is the number an author sizing a role-def edit wants, and the
|
|
391
|
-
* total because that is what the whole role surface costs. Returns `''` when
|
|
392
|
-
* the tree carries no role defs.
|
|
284
|
+
* The agent-boot size line (total and largest role def), or `''`.
|
|
393
285
|
*
|
|
394
286
|
* @param {{ tiers?: { agentBoot?: Array<{ path: string, bytes: number }> } }} tierMap
|
|
395
287
|
* @returns {string}
|
|
@@ -402,23 +294,7 @@ function renderAgentBoot(tierMap) {
|
|
|
402
294
|
}
|
|
403
295
|
|
|
404
296
|
/**
|
|
405
|
-
*
|
|
406
|
-
* tmpdir fixture with an injected config and sinks.
|
|
407
|
-
*
|
|
408
|
-
* @param {{
|
|
409
|
-
* argv?: string[],
|
|
410
|
-
* cwd?: string,
|
|
411
|
-
* config?: object,
|
|
412
|
-
* stdout?: { write: (s: string) => void },
|
|
413
|
-
* stderr?: { write: (s: string) => void },
|
|
414
|
-
* }} [opts]
|
|
415
|
-
* @returns {Promise<number>} 0 = clean / within tolerance / shrink-only / no-op;
|
|
416
|
-
* 1 = the always-loaded tier grew beyond tolerance or one of its recorded
|
|
417
|
-
* rows is unbacked
|
|
418
|
-
*/
|
|
419
|
-
/**
|
|
420
|
-
* Write a fresh budget, preserving the recorded tolerance so `--update` never
|
|
421
|
-
* silently widens the gate it is refreshing.
|
|
297
|
+
* Preserves the recorded tolerance so `--update` never widens the gate.
|
|
422
298
|
*
|
|
423
299
|
* @param {object} params
|
|
424
300
|
* @returns {0}
|
|
@@ -447,9 +323,6 @@ function writeUpdatedBaseline({ tierMap, resolvedBaselinePath, json, stdout }) {
|
|
|
447
323
|
}
|
|
448
324
|
|
|
449
325
|
/**
|
|
450
|
-
* An absent budget is a no-op, not a failure: a consumer that has never
|
|
451
|
-
* recorded one has nothing to regress against.
|
|
452
|
-
*
|
|
453
326
|
* @param {object} params
|
|
454
327
|
* @returns {0}
|
|
455
328
|
*/
|
|
@@ -473,9 +346,7 @@ function reportMissingBaseline({
|
|
|
473
346
|
}
|
|
474
347
|
|
|
475
348
|
/**
|
|
476
|
-
*
|
|
477
|
-
* renderers below present is decided here, so they cannot disagree about what
|
|
478
|
-
* failed or drift apart in which fields they surface.
|
|
349
|
+
* Every verdict is decided here, so the two renderers cannot disagree.
|
|
479
350
|
*
|
|
480
351
|
* @param {{ tierMap: object, baseline: object }} params
|
|
481
352
|
* @returns {{ diff: object, exitCode: 0 | 1 }}
|
|
@@ -519,10 +390,7 @@ function renderJsonReport({
|
|
|
519
390
|
}
|
|
520
391
|
|
|
521
392
|
/**
|
|
522
|
-
*
|
|
523
|
-
* differently, so a single generic message would leave the author guessing
|
|
524
|
-
* which applies. Only {@link ENFORCED_TIERS} drift speaks here — the report-
|
|
525
|
-
* only lines are already marked `~` in the preview above.
|
|
393
|
+
* One remediation line per failing condition (each is fixed differently).
|
|
526
394
|
*
|
|
527
395
|
* @param {object} params
|
|
528
396
|
* @returns {void}
|
|
@@ -542,14 +410,6 @@ function renderFailureDiagnostics({ report, stderr }) {
|
|
|
542
410
|
}
|
|
543
411
|
|
|
544
412
|
/**
|
|
545
|
-
* @param {object} params
|
|
546
|
-
* @returns {void}
|
|
547
|
-
*/
|
|
548
|
-
/**
|
|
549
|
-
* The optional closure lines, in print order, with the empty ones dropped.
|
|
550
|
-
* Both renderers return `''` when they have nothing to say, so filtering here
|
|
551
|
-
* keeps {@link renderTextReport} free of one branch per optional line.
|
|
552
|
-
*
|
|
553
413
|
* @param {{ tierMap: object, baseline: object | null }} params
|
|
554
414
|
* @returns {string[]}
|
|
555
415
|
*/
|
|
@@ -559,6 +419,10 @@ function optionalReportLines({ tierMap, baseline }) {
|
|
|
559
419
|
);
|
|
560
420
|
}
|
|
561
421
|
|
|
422
|
+
/**
|
|
423
|
+
* @param {object} params
|
|
424
|
+
* @returns {void}
|
|
425
|
+
*/
|
|
562
426
|
function renderTextReport({ tierMap, baseline, report, stdout, stderr }) {
|
|
563
427
|
const { diff, exitCode } = report;
|
|
564
428
|
stdout.write(`\n--- context-budget preview ---\n`);
|
|
@@ -569,6 +433,16 @@ function renderTextReport({ tierMap, baseline, report, stdout, stderr }) {
|
|
|
569
433
|
if (exitCode === 1) renderFailureDiagnostics({ report, stderr });
|
|
570
434
|
}
|
|
571
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
|
+
*/
|
|
572
446
|
export async function runCli({
|
|
573
447
|
argv = process.argv.slice(2),
|
|
574
448
|
cwd = process.cwd(),
|
|
@@ -1,26 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI: ratchet on cyclomatic
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* promises "the close-validation chain refuses the merge") while being read by
|
|
8
|
-
* nothing. This is the consumer that makes the promise true. It joins the
|
|
9
|
-
* standalone-ratchet family — `check-arch-cycles.js`, `check-dead-exports.js`,
|
|
10
|
-
* `check-context-budget.js` — which the CI `baselines` job runs as a required
|
|
11
|
-
* check, and it follows their contract exactly:
|
|
12
|
-
*
|
|
13
|
-
* - Reads the committed breach baseline at `baselines/cyclomatic.json`
|
|
14
|
-
* (override with `--baseline <path>`).
|
|
15
|
-
* - Walks the maintainability gate's `targetDirs` / `ignoreGlobs` and scores
|
|
16
|
-
* every function with the in-repo escomplex kernel — no coverage artifact
|
|
17
|
-
* required, so the verdict is available on a cold checkout.
|
|
18
|
-
* - Exit 0 when clean, improved, or shrinking; exit 1 when a file gains an
|
|
19
|
-
* over-ceiling function or its worst function gets worse.
|
|
20
|
-
*
|
|
21
|
-
* `--update` rewrites the baseline from the current tree. That is the
|
|
22
|
-
* sanctioned motion after a deliberate refactor lands, and the only way the
|
|
23
|
-
* recorded breach count is allowed to rise.
|
|
2
|
+
* CLI: ratchet on the fixed cyclomatic ceiling of 12 against
|
|
3
|
+
* `baselines/cyclomatic.json`. Scores every function in the maintainability
|
|
4
|
+
* gate's `targetDirs` with the in-repo escomplex kernel — no coverage artifact,
|
|
5
|
+
* so it works on a cold checkout. Exit 1 when a file gains an over-ceiling
|
|
6
|
+
* function or its worst function worsens.
|
|
24
7
|
*/
|
|
25
8
|
|
|
26
9
|
import fs from 'node:fs';
|
|
@@ -39,8 +22,6 @@ import {
|
|
|
39
22
|
import { resolveScanScope } from './lib/cyclomatic-scope.js';
|
|
40
23
|
|
|
41
24
|
/**
|
|
42
|
-
* Parse `--baseline <path>`, `--json`, and `--update`.
|
|
43
|
-
*
|
|
44
25
|
* @param {string[]} argv
|
|
45
26
|
* @returns {{ baselinePath: string | null, json: boolean, update: boolean }}
|
|
46
27
|
*/
|
|
@@ -66,10 +47,8 @@ function parseArgv(argv = []) {
|
|
|
66
47
|
}
|
|
67
48
|
|
|
68
49
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
* makes the very first run report every existing breach as `added` rather than
|
|
72
|
-
* silently passing.
|
|
50
|
+
* `null` when missing or unparseable — treated as empty, so a first run
|
|
51
|
+
* reports every breach rather than silently passing.
|
|
73
52
|
*
|
|
74
53
|
* @param {string} baselinePath
|
|
75
54
|
* @returns {{ ceiling?: number, rows?: Array<object> } | null}
|
|
@@ -85,9 +64,7 @@ function loadCyclomaticBaseline(baselinePath) {
|
|
|
85
64
|
}
|
|
86
65
|
|
|
87
66
|
/**
|
|
88
|
-
* `--update`:
|
|
89
|
-
* sanctioned motion after a deliberate refactor lands, and the only way the
|
|
90
|
-
* recorded breach count is allowed to rise.
|
|
67
|
+
* `--update`: the only way the recorded breach count may rise.
|
|
91
68
|
*
|
|
92
69
|
* @param {{ scan: object, ceiling: number, baselinePath: string, writeFileImpl: Function, stdout: { write: (s: string) => void } }} args
|
|
93
70
|
* @returns {number} Always 0 — writing a baseline cannot fail the ratchet.
|
|
@@ -108,8 +85,6 @@ function writeUpdatedBaseline({
|
|
|
108
85
|
}
|
|
109
86
|
|
|
110
87
|
/**
|
|
111
|
-
* `--json`: the machine-readable comparison envelope.
|
|
112
|
-
*
|
|
113
88
|
* @param {{ policy: object, baseline: object|null, baselineRows: Array<object>, baselinePath: string, scan: object, diff: object, exitCode: number }} args
|
|
114
89
|
* @returns {string}
|
|
115
90
|
*/
|
|
@@ -142,10 +117,8 @@ function renderJsonReport({
|
|
|
142
117
|
}
|
|
143
118
|
|
|
144
119
|
/**
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
* failures — the diff still runs, and staying silent is what would let an
|
|
148
|
-
* operator read a meaningless verdict as a clean one.
|
|
120
|
+
* Warn (not fail) on an absent baseline or one recorded at another ceiling,
|
|
121
|
+
* so a meaningless verdict is never read as clean.
|
|
149
122
|
*
|
|
150
123
|
* @param {{ baseline: object|null, mustFix: number, baselinePath: string, stderr: { write: (s: string) => void } }} args
|
|
151
124
|
* @returns {void}
|
|
@@ -165,9 +138,6 @@ function warnAboutBaseline({ baseline, mustFix, baselinePath, stderr }) {
|
|
|
165
138
|
}
|
|
166
139
|
|
|
167
140
|
/**
|
|
168
|
-
* Top-level CLI entry. Exported so tests can drive the whole pipeline through
|
|
169
|
-
* the injected seams below without spawning a process.
|
|
170
|
-
*
|
|
171
141
|
* @param {{
|
|
172
142
|
* argv?: string[],
|
|
173
143
|
* cwd?: string,
|
|
@@ -199,10 +169,8 @@ export async function runCli({
|
|
|
199
169
|
baselinePath ?? DEFAULT_CYCLOMATIC_BASELINE,
|
|
200
170
|
);
|
|
201
171
|
|
|
202
|
-
//
|
|
203
|
-
//
|
|
204
|
-
// `BASELINE_SCOPE=full` is the operator's explicit "re-derive everything",
|
|
205
|
-
// so both opt out of scoping entirely.
|
|
172
|
+
// Before scanning: baseline rows are half the scan scope. `--update` and
|
|
173
|
+
// `BASELINE_SCOPE=full` scan the whole tree.
|
|
206
174
|
const baseline = loadBaselineImpl(resolvedBaselinePath);
|
|
207
175
|
const baselineRows = Array.isArray(baseline?.rows) ? baseline.rows : [];
|
|
208
176
|
const scopeFiles = resolveScanScope({ cwd, config, update, baselineRows });
|
|
@@ -1,42 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI: ratchet-down dead-export gate built on knip.
|
|
2
|
+
* CLI: ratchet-down dead-export gate built on knip. Diffs knip's unused
|
|
3
|
+
* exports — plus a `{ file, symbol: '*' }` row per module nothing imports —
|
|
4
|
+
* against `baselines/dead-exports.json` by `(file, symbol)`. Exit 1 only on an
|
|
5
|
+
* added row; a knip spawn/parse failure is advisory (exit 0 + warning) so a
|
|
6
|
+
* broken knip cannot block CI.
|
|
3
7
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* only removals are detected (the baseline is shrinking, which is the success
|
|
8
|
-
* signal). Knip spawn failures remain advisory (exit 0 + stderr warning) so a
|
|
9
|
-
* misconfigured knip installation cannot block CI when we have no current
|
|
10
|
-
* snapshot to compare against.
|
|
11
|
-
*
|
|
12
|
-
* Story #4575 adds the **production pass** (`--production`), the test-only-
|
|
13
|
-
* importer discount: default mode counts a test as an importer, so
|
|
14
|
-
* production-dead code hides behind its own tests. See
|
|
15
|
-
* `lib/dead-exports-mode.js` for why the two passes carry separate baselines.
|
|
16
|
-
*
|
|
17
|
-
* Story #5001 widens what the ratchet can see: knip's `files` category (a
|
|
18
|
-
* module nothing imports) now maps to a `{ file, symbol: '*' }` row alongside
|
|
19
|
-
* the per-export rows, and `knip.json` lists `.agents/scripts/*.js` entry
|
|
20
|
-
* points explicitly instead of by blanket glob — so a top-level CLI that
|
|
21
|
-
* nothing invokes surfaces as dead instead of being declared live by the glob.
|
|
22
|
-
*
|
|
23
|
-
* Contract:
|
|
24
|
-
* - Reads the committed baseline at `baselines/dead-exports.json` — or
|
|
25
|
-
* `baselines/dead-exports-production.json` under `--production`
|
|
26
|
-
* (override either with `--baseline <path>`). Envelope shape:
|
|
27
|
-
* { $schema, kernelVersion, generatedAt, rows: [{ file, symbol }] }
|
|
28
|
-
* - Spawns `npx knip --reporter json --no-progress` (plus `--production`),
|
|
29
|
-
* parses stdout, extracts `{ file, symbol }` rows from `issues[].exports[]`
|
|
30
|
-
* **and** `issues[].files[]` — the latter as one `{ file, symbol: '*' }`
|
|
31
|
-
* whole-file row per module nothing imports (Story #5001).
|
|
32
|
-
* - Diffs current vs. baseline by `(file, symbol)` identity.
|
|
33
|
-
* - Prints `+ <file>: <symbol>` for each added dead export and
|
|
34
|
-
* `- <file>: <symbol>` for each removed one, then a summary line.
|
|
35
|
-
* - With `--json`: writes the structured envelope to stdout and skips the
|
|
36
|
-
* human summary. The envelope still includes `added`, `removed`,
|
|
37
|
-
* `baselineRows`, `currentRows`, and `exitCode`.
|
|
38
|
-
* - Exit codes: 0 = clean or removals-only; 1 = added exports detected.
|
|
39
|
-
* Knip spawn/parse failure exits 0 (advisory) with a stderr warning.
|
|
8
|
+
* `--production` discounts test-only importers (production-dead code hides
|
|
9
|
+
* behind its own tests) and uses its own baseline — see
|
|
10
|
+
* `lib/dead-exports-mode.js`.
|
|
40
11
|
*/
|
|
41
12
|
|
|
42
13
|
import fs from 'node:fs';
|
|
@@ -51,9 +22,7 @@ import {
|
|
|
51
22
|
import { resolveDeadExportsMode } from './lib/dead-exports-mode.js';
|
|
52
23
|
|
|
53
24
|
/**
|
|
54
|
-
*
|
|
55
|
-
* `--production`. `--knip-output` is a test seam: pass a pre-captured knip JSON
|
|
56
|
-
* file instead of spawning knip. Exported so unit tests can pin the parser.
|
|
25
|
+
* `--knip-output` is a test seam: a pre-captured knip JSON instead of a spawn.
|
|
57
26
|
*
|
|
58
27
|
* @param {string[]} argv
|
|
59
28
|
* @returns {{ baselinePath: string | null, json: boolean, knipOutputPath: string | null, production: boolean }}
|
|
@@ -87,9 +56,7 @@ export function parseArgv(argv = []) {
|
|
|
87
56
|
}
|
|
88
57
|
|
|
89
58
|
/**
|
|
90
|
-
*
|
|
91
|
-
* or `null` when the file is missing or unparseable. Exported for tests so
|
|
92
|
-
* they can feed fixture paths.
|
|
59
|
+
* `null` when missing or unparseable.
|
|
93
60
|
*
|
|
94
61
|
* @param {string} baselinePath
|
|
95
62
|
* @returns {{ kernelVersion?: string, generatedAt?: string, rows?: Array<{file: string, symbol: string}> } | null}
|
|
@@ -107,11 +74,7 @@ export function loadBaseline(baselinePath) {
|
|
|
107
74
|
}
|
|
108
75
|
|
|
109
76
|
/**
|
|
110
|
-
*
|
|
111
|
-
* current but not baseline) and `removed` (in baseline but not current).
|
|
112
|
-
* Identity is `<file>\0<symbol>`. Exported as the AC's "diff helper" — the
|
|
113
|
-
* sibling test exercises both the added and removed branches against fixture
|
|
114
|
-
* baselines without spawning knip.
|
|
77
|
+
* Diff two row sets by `(file, symbol)`, sorted for stable output.
|
|
115
78
|
*
|
|
116
79
|
* @param {Array<{ file: string, symbol: string }>} baselineRows
|
|
117
80
|
* @param {Array<{ file: string, symbol: string }>} currentRows
|
|
@@ -126,7 +89,6 @@ export function diffRows(baselineRows, currentRows) {
|
|
|
126
89
|
const currentSet = new Set((currentRows ?? []).map(key));
|
|
127
90
|
const added = (currentRows ?? []).filter((r) => !baselineSet.has(key(r)));
|
|
128
91
|
const removed = (baselineRows ?? []).filter((r) => !currentSet.has(key(r)));
|
|
129
|
-
// Sort deterministically so output is stable across runs.
|
|
130
92
|
const sortFn = (a, b) =>
|
|
131
93
|
a.file.localeCompare(b.file) || a.symbol.localeCompare(b.symbol);
|
|
132
94
|
return {
|
|
@@ -136,15 +98,8 @@ export function diffRows(baselineRows, currentRows) {
|
|
|
136
98
|
}
|
|
137
99
|
|
|
138
100
|
/**
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* `- <file>: <symbol>` for removed rows
|
|
142
|
-
* Followed by a one-line summary even on a clean diff so operators see the
|
|
143
|
-
* "no drift" signal. When added rows are present the summary includes a
|
|
144
|
-
* "(gate fail)" marker so the ratchet violation is visible in CI output.
|
|
145
|
-
*
|
|
146
|
-
* `label` distinguishes the two passes in CI logs, which run back to back and
|
|
147
|
-
* would otherwise emit two identical-looking summaries.
|
|
101
|
+
* `+`/`-` rows then a summary line. `label` tells the two back-to-back passes
|
|
102
|
+
* apart in CI logs.
|
|
148
103
|
*
|
|
149
104
|
* @param {{ added: Array, removed: Array }} diff
|
|
150
105
|
* @param {string} [label='dead-exports']
|
|
@@ -162,9 +117,6 @@ export function renderDiff(diff, label = 'dead-exports') {
|
|
|
162
117
|
}
|
|
163
118
|
|
|
164
119
|
/**
|
|
165
|
-
* Top-level CLI entry. Exported so tests can drive the full pipeline through
|
|
166
|
-
* injected hooks without spawning knip.
|
|
167
|
-
*
|
|
168
120
|
* @param {{
|
|
169
121
|
* argv?: string[],
|
|
170
122
|
* cwd?: string,
|
|
@@ -213,9 +165,6 @@ export async function runCli({
|
|
|
213
165
|
const currentRows = extractRowsFromKnip(knipEnvelope);
|
|
214
166
|
const diff = diffRows(baselineRows, currentRows);
|
|
215
167
|
|
|
216
|
-
// Ratchet-down gate: fail when new dead exports are introduced. Removals are
|
|
217
|
-
// the success signal (baseline shrinking). Knip spawn failures stay advisory
|
|
218
|
-
// so a misconfigured knip installation cannot block CI without a snapshot.
|
|
219
168
|
const exitCode = knipError === null && diff.added.length > 0 ? 1 : 0;
|
|
220
169
|
|
|
221
170
|
if (json) {
|