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,35 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* default `requireCoverage: true` policy, so a missing or stale artifact
|
|
6
|
-
* silently weakens the gate. This helper closes that hole by capturing
|
|
7
|
-
* coverage in-band when it is missing or older than the CRAP-target sources.
|
|
8
|
-
*
|
|
9
|
-
* Pure functions live here; the spawn wiring lives in
|
|
10
|
-
* `.agents/scripts/coverage-capture.js` (CLI). Importers test freshness via
|
|
11
|
-
* `isCoverageFresh` and decide whether to delegate to `runCapture`.
|
|
2
|
+
* Keep `coverage/coverage-final.json` present and fresh before a CRAP gate
|
|
3
|
+
* reads it: the scorer skips uncovered methods, so a stale artifact silently
|
|
4
|
+
* weakens the gate.
|
|
12
5
|
*/
|
|
13
|
-
import { spawnSync } from 'node:child_process';
|
|
6
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
14
7
|
import crypto from 'node:crypto';
|
|
15
8
|
import fs from 'node:fs';
|
|
16
9
|
import path from 'node:path';
|
|
10
|
+
import { LOCK_WAIT_EXPIRED_EXIT_CODE } from './full-suite-lock.js';
|
|
11
|
+
import {
|
|
12
|
+
groupSpawnOptions,
|
|
13
|
+
superviseGroup,
|
|
14
|
+
TIMEOUT_EXIT_CODE,
|
|
15
|
+
} from './process-group.js';
|
|
17
16
|
import {
|
|
18
17
|
isScorableSourceFile,
|
|
19
18
|
SCORABLE_SOURCE_EXT_RE,
|
|
20
19
|
} from './source-extensions.js';
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* the CRAP scanner walks, so freshness tracks exactly what the gate scores.
|
|
26
|
-
* Symlinks, missing dirs, and unreadable nodes resolve to 0.
|
|
27
|
-
*
|
|
28
|
-
* A 0 return means "discovery found nothing", which {@link isCoverageFresh}
|
|
29
|
-
* treats as an absence of evidence rather than as freshness — see its
|
|
30
|
-
* `no-sources` contract.
|
|
31
|
-
*
|
|
32
|
-
* Exported for unit testing.
|
|
22
|
+
* Newest mtime across the scorable sources the CRAP scanner walks; unreadable
|
|
23
|
+
* nodes are skipped. 0 means "found nothing", never "fresh".
|
|
33
24
|
*
|
|
34
25
|
* @param {string} cwd Absolute repo root.
|
|
35
26
|
* @param {string[]} targetDirs Repo-relative directories to scan.
|
|
@@ -74,11 +65,8 @@ export function newestSourceMtime(cwd, targetDirs, io = {}) {
|
|
|
74
65
|
}
|
|
75
66
|
|
|
76
67
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* moment coverage was last captured, so freshness can be decided by content
|
|
80
|
-
* rather than mtime (mtime churns on branch switches / checkouts even when
|
|
81
|
-
* content is unchanged).
|
|
68
|
+
* The stamp records the sources' content digest at capture time, so freshness
|
|
69
|
+
* survives mtime churn from checkouts.
|
|
82
70
|
*
|
|
83
71
|
* @param {string} cwd Absolute repo root.
|
|
84
72
|
* @param {string} coveragePath Repo-relative coverage artifact path.
|
|
@@ -92,13 +80,8 @@ export function captureStampPath(cwd, coveragePath) {
|
|
|
92
80
|
}
|
|
93
81
|
|
|
94
82
|
/**
|
|
95
|
-
* Fold
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
* Dirty files are not represented by their index blob SHA, so their on-disk
|
|
99
|
-
* bytes (or absence) go in explicitly. Split out of
|
|
100
|
-
* {@link computeContentDigest} to keep that function's complexity at its
|
|
101
|
-
* committed CRAP floor.
|
|
83
|
+
* Fold dirty scorable files' on-disk bytes (or absence) into `hash`; their
|
|
84
|
+
* index blob SHA does not represent them.
|
|
102
85
|
*
|
|
103
86
|
* @param {{
|
|
104
87
|
* hash: import('node:crypto').Hash,
|
|
@@ -127,19 +110,10 @@ function foldDirtySources({ hash, cwd, readFileSync, porcelain }) {
|
|
|
127
110
|
}
|
|
128
111
|
|
|
129
112
|
/**
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* when content actually changes.
|
|
135
|
-
*
|
|
136
|
-
* Returns `null` when the digest cannot be computed (git unavailable, not a
|
|
137
|
-
* repo, empty target list) so callers can fall back to the mtime heuristic.
|
|
138
|
-
* A target list that matches **no** scorable file is the same "unavailable"
|
|
139
|
-
* case, not a digest over zero files: this path is the primary freshness
|
|
140
|
-
* test, so returning a real hash of empty input would pin the artifact
|
|
141
|
-
* permanently fresh and make the mtime path's fail-closed verdict
|
|
142
|
-
* unreachable (Story #5076).
|
|
113
|
+
* Digest of the scorable sources under `targetDirs`: `git ls-files -s` of
|
|
114
|
+
* tracked content plus dirty files' bytes, so it moves only on content change.
|
|
115
|
+
* `null` means unavailable (no git, no dirs, or zero matching files — a hash
|
|
116
|
+
* of empty input would pin the artifact permanently fresh).
|
|
143
117
|
*
|
|
144
118
|
* @param {string} cwd Absolute repo root.
|
|
145
119
|
* @param {string[]} targetDirs Repo-relative directories to digest.
|
|
@@ -175,9 +149,6 @@ export function computeContentDigest(cwd, targetDirs, io = {}) {
|
|
|
175
149
|
readFileSync,
|
|
176
150
|
porcelain: git('status', '--porcelain', '--', ...dirs),
|
|
177
151
|
});
|
|
178
|
-
// Discovery found nothing to digest: hashing the empty input would yield
|
|
179
|
-
// a constant that can never go stale, so report "unavailable" instead and
|
|
180
|
-
// let the caller's fail-closed mtime path decide.
|
|
181
152
|
if (tracked.length + scorableDirty === 0) return null;
|
|
182
153
|
return hash.digest('hex');
|
|
183
154
|
} catch {
|
|
@@ -186,16 +157,9 @@ export function computeContentDigest(cwd, targetDirs, io = {}) {
|
|
|
186
157
|
}
|
|
187
158
|
|
|
188
159
|
/**
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
* `scope` / `files` / `ref` are Story #4981 additions for incremental-mode
|
|
194
|
-
* capture. They are written to the stamp **only when the caller supplies
|
|
195
|
-
* `scope`** — the default (full-scope) call sites never pass it, so the
|
|
196
|
-
* emitted JSON stays the exact `{ digest, capturedAt }` shape byte-for-byte
|
|
197
|
-
* (AC-5). `isCoverageFresh` reads `scope` back to refuse letting a scoped
|
|
198
|
-
* stamp satisfy a full-scope freshness probe (AC-4).
|
|
160
|
+
* Best-effort: a write failure returns `false` (next check falls back to
|
|
161
|
+
* mtime). Full-scope callers omit `scope`, keeping the `{ digest, capturedAt }`
|
|
162
|
+
* shape.
|
|
199
163
|
*
|
|
200
164
|
* @param {{
|
|
201
165
|
* cwd: string,
|
|
@@ -234,16 +198,10 @@ export function writeCaptureStamp({
|
|
|
234
198
|
}
|
|
235
199
|
|
|
236
200
|
/**
|
|
237
|
-
* Read a persisted capture stamp's digest and scope tag back into the shape
|
|
238
|
-
* `isCoverageFresh` needs, applying the Story #4981 scope-asymmetry rule
|
|
239
|
-
* (AC-4) in one place. Extracted so the parent function's own branching
|
|
240
|
-
* stays under the cyclomatic ceiling.
|
|
241
|
-
*
|
|
242
201
|
* @param {{digest?: unknown, scope?: unknown} | null} stamp
|
|
243
202
|
* @param {'full' | 'incremental'} requireScope
|
|
244
203
|
* @returns {{ digest: string } | { scopeMismatch: true } | null} `null`
|
|
245
|
-
*
|
|
246
|
-
* mtime heuristic.
|
|
204
|
+
* falls through to the mtime heuristic.
|
|
247
205
|
*/
|
|
248
206
|
function readStampForScope(stamp, requireScope) {
|
|
249
207
|
if (typeof stamp?.digest !== 'string' || stamp.digest.length === 0) {
|
|
@@ -257,33 +215,11 @@ function readStampForScope(stamp, requireScope) {
|
|
|
257
215
|
}
|
|
258
216
|
|
|
259
217
|
/**
|
|
260
|
-
*
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
* Branch switches and checkouts that bump mtimes without changing content
|
|
266
|
-
* no longer invalidate coverage.
|
|
267
|
-
*
|
|
268
|
-
* Fallback (stamp absent / unreadable / digest unavailable): the original
|
|
269
|
-
* mtime heuristic — artifact at least as new as the newest source file
|
|
270
|
-
* under `targetDirs`. Missing files, missing target dirs, or any IO error
|
|
271
|
-
* resolve to `false` so the caller captures rather than trusting stale data.
|
|
272
|
-
*
|
|
273
|
-
* **Both paths fail closed on an empty source set (Story #5076).** Finding no
|
|
274
|
-
* scorable source under `targetDirs` means the check learned nothing, so it
|
|
275
|
-
* reports `{ fresh: false, reason: 'no-sources' }` and the caller captures.
|
|
276
|
-
* The alternative — treating "found nothing" as "nothing changed" — is how a
|
|
277
|
-
* `js|mjs`-only selector left the CRAP gate green while measuring nothing in
|
|
278
|
-
* every TypeScript consumer.
|
|
279
|
-
*
|
|
280
|
-
* **Scope asymmetry (Story #4981, AC-4).** A stamp written by an incremental
|
|
281
|
-
* capture (`scope: 'incremental'`) only covers the files the diff touched —
|
|
282
|
-
* it must never satisfy a caller that requires the full-scope guarantee
|
|
283
|
-
* (`requireScope` defaults to `'full'`, matching every pre-existing caller
|
|
284
|
-
* byte-for-byte). A full-scope stamp (or a legacy stamp with no `scope`
|
|
285
|
-
* field, which predates this Story and is therefore full-scope by
|
|
286
|
-
* construction) satisfies either probe.
|
|
218
|
+
* Stamp digest vs current digest when a stamp exists; otherwise artifact
|
|
219
|
+
* mtime vs newest source. IO errors resolve stale. Both paths fail closed
|
|
220
|
+
* (`no-sources`) on an empty source set — "found nothing" is not "nothing
|
|
221
|
+
* changed". An incremental stamp never satisfies a full-scope probe; a stamp
|
|
222
|
+
* with no `scope` is full-scope.
|
|
287
223
|
*
|
|
288
224
|
* @param {{
|
|
289
225
|
* coveragePath: string,
|
|
@@ -345,9 +281,6 @@ export function isCoverageFresh({
|
|
|
345
281
|
statSync,
|
|
346
282
|
readdirSync,
|
|
347
283
|
});
|
|
348
|
-
// Source discovery found nothing. That is an absence of evidence, never a
|
|
349
|
-
// freshness guarantee — trusting it silently disables the capture (and with
|
|
350
|
-
// it the CRAP gate) for any tree the walk cannot see (Story #5076).
|
|
351
284
|
if (newestSrc === 0) return { fresh: false, reason: 'no-sources' };
|
|
352
285
|
return coverageMtime >= newestSrc
|
|
353
286
|
? { fresh: true, reason: 'fresh' }
|
|
@@ -355,14 +288,8 @@ export function isCoverageFresh({
|
|
|
355
288
|
}
|
|
356
289
|
|
|
357
290
|
/**
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
* Every reason but `no-sources` speaks for itself. That one does not: failing
|
|
361
|
-
* closed on an empty source walk is correct, but bare it reads as an
|
|
362
|
-
* unexplained full capture on every run, and the cause is far more often a
|
|
363
|
-
* `targetDirs` that does not name the project's sources than a genuine
|
|
364
|
-
* recapture — so the walked dirs and the key to fix are named inline
|
|
365
|
-
* (Story #5076).
|
|
291
|
+
* `no-sources` usually means a misconfigured `targetDirs`, so it names the
|
|
292
|
+
* walked dirs and the key to fix.
|
|
366
293
|
*
|
|
367
294
|
* @param {{ reason?: string }} freshness Verdict from {@link isCoverageFresh}.
|
|
368
295
|
* @param {string[]} targetDirs The CRAP scan scope that was walked.
|
|
@@ -375,37 +302,19 @@ export function describeFreshness(freshness, targetDirs) {
|
|
|
375
302
|
return `${reason} — no scorable source file found under [${dirs}]; if that does not name this project's sources, fix quality.gates.crap.targetDirs`;
|
|
376
303
|
}
|
|
377
304
|
|
|
378
|
-
/**
|
|
379
|
-
* The invocation that deposits capture credit for a Story branch. Named in
|
|
380
|
-
* the uncredited-capture announcement so a reader of a close log sees the
|
|
381
|
-
* command that would have avoided the cost, not just the cost.
|
|
382
|
-
*/
|
|
383
305
|
const CREDITING_INVOCATION =
|
|
384
306
|
'node <main-repo>/.agents/scripts/coverage-capture.js --cwd <workCwd>';
|
|
385
307
|
|
|
386
308
|
/**
|
|
387
|
-
* Announce
|
|
388
|
-
* capture
|
|
389
|
-
*
|
|
390
|
-
* Every caller invokes this immediately before it would spawn the suite, and
|
|
391
|
-
* the ordering is the whole point. The capture itself is the most expensive
|
|
392
|
-
* thing a close does; discovering that it ran uncredited is only actionable
|
|
393
|
-
* while it is still ahead of you, not once it is visible as a `durationMs`
|
|
394
|
-
* in `validation-evidence.json` twelve minutes later.
|
|
395
|
-
*
|
|
396
|
-
* The probe is read-only by construction: every caller has already decided
|
|
397
|
-
* to capture by the time it runs, and it writes nothing — so it never takes
|
|
398
|
-
* the full-suite host lock and can never itself be the reason a close waits.
|
|
309
|
+
* Announce (or, under `--require-credited`, refuse) an uncredited full-suite
|
|
310
|
+
* capture — before the spawn, while it is still actionable. Read-only, so it
|
|
311
|
+
* never takes the host lock.
|
|
399
312
|
*
|
|
400
313
|
* @param {{
|
|
401
314
|
* requireCredited?: boolean,
|
|
402
315
|
* logger: { info: Function, warn: Function, error: Function },
|
|
403
|
-
* }} opts `requireCredited`
|
|
404
|
-
*
|
|
405
|
-
* `delivery.execution.requireCreditedCapture` is set (default false →
|
|
406
|
-
* announce and run). Story #5278: it is deliberately NOT read from config
|
|
407
|
-
* here — that made the refusal cover the depositing invocation too, leaving
|
|
408
|
-
* no way to earn the credit it demanded.
|
|
316
|
+
* }} opts `requireCredited` is a per-invocation CLI opt-in, never config:
|
|
317
|
+
* from config it would also refuse the invocation that deposits credit.
|
|
409
318
|
* @returns {number | null} A non-zero exit code the caller MUST return
|
|
410
319
|
* without spawning the suite, or `null` to proceed with the capture.
|
|
411
320
|
*/
|
|
@@ -424,48 +333,25 @@ function announceUncreditedCapture({ requireCredited = false, logger }) {
|
|
|
424
333
|
}
|
|
425
334
|
|
|
426
335
|
/**
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
* This mirrors `lockedCapture`, and for the same reason: there are two
|
|
431
|
-
* capture paths (full-scope and incremental) and neither should have to
|
|
432
|
-
* remember the policy. Wrapping the runner they share means a third path
|
|
433
|
-
* added later inherits the probe for free, and that the warning can never be
|
|
434
|
-
* emitted for a capture that does not happen — or omitted for one that does.
|
|
336
|
+
* Wrap a capture runner so the announcement is inseparable from the spawn.
|
|
337
|
+
* Composes outside `lockedCapture`, so a refusal never acquires the lock.
|
|
435
338
|
*
|
|
436
|
-
*
|
|
437
|
-
* lock is never acquired for a run that is about to be declined.
|
|
438
|
-
*
|
|
439
|
-
* @param {(opts: object) => number} runCaptureFn The (possibly already
|
|
440
|
-
* lock-wrapped) capture runner.
|
|
339
|
+
* @param {(opts: object) => Promise<number>|number} runCaptureFn
|
|
441
340
|
* @param {{ requireCredited?: boolean, logger: object }} policy
|
|
442
|
-
* @returns {(opts?: object) => number}
|
|
443
|
-
*
|
|
341
|
+
* @returns {(opts?: object) => Promise<number>} Exit code, or a refusal code
|
|
342
|
+
* without spawning.
|
|
444
343
|
*/
|
|
445
344
|
export function creditedCapture(runCaptureFn, { requireCredited, logger }) {
|
|
446
|
-
return (captureOpts = {}) => {
|
|
345
|
+
return async (captureOpts = {}) => {
|
|
447
346
|
const refusal = announceUncreditedCapture({ requireCredited, logger });
|
|
448
|
-
return refusal === null ? runCaptureFn(captureOpts) : refusal;
|
|
347
|
+
return refusal === null ? await runCaptureFn(captureOpts) : refusal;
|
|
449
348
|
};
|
|
450
349
|
}
|
|
451
350
|
|
|
452
351
|
/**
|
|
453
|
-
*
|
|
454
|
-
* the
|
|
455
|
-
*
|
|
456
|
-
* The stamp is a claim about content: "coverage/coverage-final.json reflects
|
|
457
|
-
* sources digesting to X". Computing X *after* the suite finishes makes that
|
|
458
|
-
* claim false whenever anything moved while the suite ran — a sibling
|
|
459
|
-
* worktree's write, a rebase, an editor save minutes into a ten-minute run.
|
|
460
|
-
* The digest taken **before** the spawn is the one the run actually measured,
|
|
461
|
-
* so that is the value written, and a post-run digest that disagrees means
|
|
462
|
-
* the artifact describes a tree nobody has any more: no stamp is written at
|
|
463
|
-
* all, and the next reader captures rather than crediting a run against
|
|
464
|
-
* sources it never saw.
|
|
465
|
-
*
|
|
466
|
-
* A `null` on either digest is "unavailable", not "changed" — the same
|
|
467
|
-
* fail-open the pre-#5278 code had, since without a digest there is nothing
|
|
468
|
-
* to stamp.
|
|
352
|
+
* Stamp the pre-spawn digest (the tree the run measured), and write nothing
|
|
353
|
+
* when the post-run digest differs — the artifact then describes a tree no
|
|
354
|
+
* longer on disk. A `null` post-digest is "unavailable", not "changed".
|
|
469
355
|
*
|
|
470
356
|
* @param {{
|
|
471
357
|
* preDigest: string|null,
|
|
@@ -520,12 +406,7 @@ export function stampCapturedTree({
|
|
|
520
406
|
}
|
|
521
407
|
|
|
522
408
|
/**
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
* Both inputs are forward-slash-normalised; `targetDirs` are matched as path
|
|
526
|
-
* prefixes followed by `/`. Shared by `anyChangedUnderTargets` (the pre-push
|
|
527
|
-
* fast-path boolean) and the incremental-coverage scope resolver (Story
|
|
528
|
-
* #4981), which needs the actual file list rather than a yes/no.
|
|
409
|
+
* Changed files under a `targetDirs` prefix, forward-slash-normalised.
|
|
529
410
|
*
|
|
530
411
|
* @param {string[]} changedFiles
|
|
531
412
|
* @param {string[]} targetDirs
|
|
@@ -543,11 +424,7 @@ export function filterFilesUnderTargets(changedFiles, targetDirs) {
|
|
|
543
424
|
}
|
|
544
425
|
|
|
545
426
|
/**
|
|
546
|
-
*
|
|
547
|
-
* Used by the pre-push fast-path so we can skip the (slow) coverage capture
|
|
548
|
-
* when the push touches only files outside the CRAP scoring scope.
|
|
549
|
-
*
|
|
550
|
-
* An empty changed-file list returns `false`.
|
|
427
|
+
* Pre-push fast path: skip capture when nothing in CRAP scope changed.
|
|
551
428
|
*
|
|
552
429
|
* @param {string[]} changedFiles
|
|
553
430
|
* @param {string[]} targetDirs
|
|
@@ -557,75 +434,73 @@ export function anyChangedUnderTargets(changedFiles, targetDirs) {
|
|
|
557
434
|
return filterFilesUnderTargets(changedFiles, targetDirs).length > 0;
|
|
558
435
|
}
|
|
559
436
|
|
|
560
|
-
/**
|
|
561
|
-
|
|
562
|
-
* killed by the timeout watchdog. Matches the GNU `timeout(1)` convention so
|
|
563
|
-
* the close-validation caller can branch on "hang" (124) vs. "tests failed"
|
|
564
|
-
* (any other non-zero status). Story #2136 / Task #2142.
|
|
565
|
-
*/
|
|
566
|
-
export const COVERAGE_TIMEOUT_EXIT_CODE = 124;
|
|
437
|
+
/** GNU `timeout(1)` code, so callers tell a hang (124) from failing tests. */
|
|
438
|
+
export const COVERAGE_TIMEOUT_EXIT_CODE = TIMEOUT_EXIT_CODE;
|
|
567
439
|
|
|
568
440
|
/**
|
|
569
|
-
* Spawn `npm run test:coverage`
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
*
|
|
573
|
-
*
|
|
574
|
-
* The `timeoutMs` budget is enforced by `spawnSync` with `killSignal:
|
|
575
|
-
* 'SIGKILL'` — Node fires the signal at the budget boundary and the result
|
|
576
|
-
* surfaces with `signal: 'SIGKILL'`. We translate that into the GNU
|
|
577
|
-
* `timeout(1)` convention exit code 124 so callers can pattern-match a
|
|
578
|
-
* runaway runner without inspecting signal names.
|
|
579
|
-
*
|
|
580
|
-
* The spawn takes **no positional file arguments**. Story #4981 forwarded the
|
|
581
|
-
* changed-file list as `npm run test:coverage -- <files...>` on the premise
|
|
582
|
-
* that a test runner treats trailing positionals as filters over the suite.
|
|
583
|
-
* Node's runner does not: it treats each path as a test file to execute, so a
|
|
584
|
-
* forwarded *source* file runs as a trivially-passing test and the real suite
|
|
585
|
-
* never runs. `run-coverage.js` discarded the list, which is the only reason
|
|
586
|
-
* that never bit; Story #5063 measured it and Story #5065 removed the
|
|
587
|
-
* plumbing rather than leave a parameter whose obvious "fix" empties the
|
|
588
|
-
* coverage artifact.
|
|
441
|
+
* Spawn `npm run test:coverage` asynchronously as its own process group, so
|
|
442
|
+
* the lock heartbeat keeps running and a timeout or signal kills every
|
|
443
|
+
* worker. Takes no positional file args: node's runner would execute a
|
|
444
|
+
* forwarded source file as a test instead of filtering the suite.
|
|
589
445
|
*
|
|
590
446
|
* @param {{
|
|
591
447
|
* cwd: string,
|
|
592
448
|
* timeoutMs?: number,
|
|
593
|
-
*
|
|
449
|
+
* spawnImpl?: typeof spawn,
|
|
594
450
|
* log?: (m: string) => void,
|
|
595
451
|
* }} opts
|
|
596
|
-
* @returns {number}
|
|
452
|
+
* @returns {Promise<number>}
|
|
597
453
|
*/
|
|
598
454
|
export function runCapture({
|
|
599
455
|
cwd,
|
|
600
456
|
timeoutMs,
|
|
601
|
-
|
|
457
|
+
spawnImpl = spawn,
|
|
602
458
|
log = () => {},
|
|
603
459
|
} = {}) {
|
|
604
460
|
const args = ['run', 'test:coverage'];
|
|
605
461
|
log(`[coverage-capture] ▶ npm ${args.join(' ')}`);
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
462
|
+
return new Promise((resolve) => {
|
|
463
|
+
const child = spawnImpl('npm', args, {
|
|
464
|
+
cwd,
|
|
465
|
+
stdio: 'inherit',
|
|
466
|
+
shell: process.platform === 'win32',
|
|
467
|
+
...groupSpawnOptions(),
|
|
468
|
+
});
|
|
469
|
+
const supervisor = superviseGroup(child, { timeoutMs });
|
|
470
|
+
child.on('error', () => {
|
|
471
|
+
supervisor.release();
|
|
472
|
+
resolve(1);
|
|
473
|
+
});
|
|
474
|
+
child.on('exit', (code) => {
|
|
475
|
+
supervisor.release();
|
|
476
|
+
if (!supervisor.timedOut) {
|
|
477
|
+
resolve(code ?? 1);
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
log(
|
|
481
|
+
`[coverage-capture] ⏱ npm run test:coverage exceeded ${timeoutMs}ms — killed its process group. Returning exit ${COVERAGE_TIMEOUT_EXIT_CODE}.`,
|
|
482
|
+
);
|
|
483
|
+
resolve(COVERAGE_TIMEOUT_EXIT_CODE);
|
|
484
|
+
});
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Report a non-zero capture; an expired lock wait is not a failing suite.
|
|
490
|
+
*
|
|
491
|
+
* @param {number} code
|
|
492
|
+
* @param {{ info: Function, error: Function }} logger
|
|
493
|
+
* @returns {number}
|
|
494
|
+
*/
|
|
495
|
+
export function reportCaptureFailure(code, logger) {
|
|
496
|
+
if (code === LOCK_WAIT_EXPIRED_EXIT_CODE) {
|
|
497
|
+
logger.info(
|
|
498
|
+
`[coverage-capture] ⏸ the full-suite lock wait expired and this capture was deferred — no suite ran. Exiting ${code}.`,
|
|
627
499
|
);
|
|
628
|
-
return
|
|
500
|
+
return code;
|
|
629
501
|
}
|
|
630
|
-
|
|
502
|
+
logger.error(
|
|
503
|
+
`[coverage-capture] ✖ npm run test:coverage exited ${code}. Fix failing tests or coverage-threshold breaches before re-running the CRAP gate.`,
|
|
504
|
+
);
|
|
505
|
+
return code;
|
|
631
506
|
}
|
|
@@ -4,12 +4,7 @@ const COVERAGE_INDEX = Symbol('coverage-utils.coverage-index');
|
|
|
4
4
|
const ENTRY_INDEX = Symbol('coverage-utils.entry-index');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Returns the parsed object (keyed by absolute file path) on success, or
|
|
10
|
-
* `null` when the file is missing, unreadable, non-JSON, or structurally
|
|
11
|
-
* unusable. Never throws — consumers treat a null map as "no coverage
|
|
12
|
-
* available" and apply their own `requireCoverage` policy.
|
|
7
|
+
* Never throws; `null` for any missing or unusable artifact.
|
|
13
8
|
*
|
|
14
9
|
* @param {string} coveragePath
|
|
15
10
|
* @returns {object|null}
|
|
@@ -37,12 +32,7 @@ function stripLeadingDotSlash(p) {
|
|
|
37
32
|
}
|
|
38
33
|
|
|
39
34
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* Returns `{map, byNormalizedSuffix}` where `byNormalizedSuffix` is a
|
|
43
|
-
* `Map<string, object>` keyed by the POSIX-normalized form of each original
|
|
44
|
-
* key. Lookups that need exact-equality or `/`-bounded suffix matching
|
|
45
|
-
* consult that Map without re-enumerating `Object.keys(map)` on every call.
|
|
35
|
+
* Entries keyed by POSIX-normalized path.
|
|
46
36
|
*
|
|
47
37
|
* @param {object|null} map
|
|
48
38
|
* @returns {{map: object|null, byNormalizedSuffix: Map<string, object>}}
|
|
@@ -72,15 +62,8 @@ function getCoverageIndex(map) {
|
|
|
72
62
|
}
|
|
73
63
|
|
|
74
64
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* `coverage-final.json` keys are typically absolute, platform-specific paths,
|
|
78
|
-
* while callers pass POSIX-ish repo-relative strings. Match by exact equality
|
|
79
|
-
* or by `/`-bounded suffix so we tolerate both Windows and POSIX producers.
|
|
80
|
-
* If two distinct keys both end with the same `/`-bounded suffix (duplicate
|
|
81
|
-
* basenames in different trees), the suffix is ambiguous — return null
|
|
82
|
-
* rather than picking the first iteration-order hit and silently scoring
|
|
83
|
-
* the wrong file.
|
|
65
|
+
* Match a repo-relative path to an absolute key by exact or `/`-bounded
|
|
66
|
+
* suffix. An ambiguous suffix returns null rather than scoring the wrong file.
|
|
84
67
|
*/
|
|
85
68
|
function findFileEntry(map, relPath) {
|
|
86
69
|
if (!map || !relPath) return null;
|
|
@@ -103,8 +86,6 @@ function findFileEntry(map, relPath) {
|
|
|
103
86
|
export { findFileEntry as findCoverageEntry };
|
|
104
87
|
|
|
105
88
|
/**
|
|
106
|
-
* Does the map contain any entry whose path matches `relPath`?
|
|
107
|
-
*
|
|
108
89
|
* @param {object|null} map
|
|
109
90
|
* @param {string} relPath
|
|
110
91
|
* @returns {boolean}
|
|
@@ -114,17 +95,8 @@ export function hasCoverageFor(map, relPath) {
|
|
|
114
95
|
}
|
|
115
96
|
|
|
116
97
|
/**
|
|
117
|
-
*
|
|
118
|
-
* `
|
|
119
|
-
*
|
|
120
|
-
* - `fnByStartLine`: maps either `decl.start.line` or `loc.start.line` to the
|
|
121
|
-
* raw `fnMap` entry — so callers may key by the escomplex `lineStart`
|
|
122
|
-
* (which can match either, depending on producer).
|
|
123
|
-
* - `fnLocByStartLine`: same keying, value is `{fnStart, fnEnd}` derived once.
|
|
124
|
-
* - `fnRanges`: every function's `{fnStart, fnEnd, declLine}` triple, used by
|
|
125
|
-
* the containment / nearest-decl fallbacks when exact-line keying misses.
|
|
126
|
-
* - `statementsByLine`: `Map<line, {total, covered}>` so range scans don't
|
|
127
|
-
* re-walk the full statement map.
|
|
98
|
+
* Per-entry index making a method lookup `O(method-line-span)`. Functions are
|
|
99
|
+
* keyed by both `decl` and `loc` start lines (producers differ).
|
|
128
100
|
*
|
|
129
101
|
* @param {object|null} entry One inner value from a `coverage-final.json` map.
|
|
130
102
|
*/
|
|
@@ -181,36 +153,15 @@ export function buildEntryIndex(entry) {
|
|
|
181
153
|
}
|
|
182
154
|
|
|
183
155
|
/**
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
* Even after remapping to original-source coordinates (Story #4775), a
|
|
188
|
-
* method's start and istanbul's `decl.start.line` do not always agree on the
|
|
189
|
-
* token: escomplex anchors on the function node, istanbul on the declaration
|
|
190
|
-
* it instruments, and a decorator, a leading `export`, or a multi-line
|
|
191
|
-
* parameter list puts them one line apart. One line of slack absorbs that
|
|
192
|
-
* without letting an unrelated neighbouring function be claimed.
|
|
156
|
+
* escomplex and istanbul can disagree by one line on a function's start
|
|
157
|
+
* (decorator, leading `export`, multi-line params); wider would claim a
|
|
158
|
+
* neighbour.
|
|
193
159
|
*/
|
|
194
160
|
const DECL_MATCH_WINDOW = 1;
|
|
195
161
|
|
|
196
162
|
/**
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
* Three strategies, most precise first:
|
|
201
|
-
*
|
|
202
|
-
* 1. **Exact** — the line keys a `fnMap` `decl.start.line` or
|
|
203
|
-
* `loc.start.line`. This is the pre-#4775 behaviour and still wins, so
|
|
204
|
-
* every already-resolving row keeps its exact prior value.
|
|
205
|
-
* 2. **Containment** — the innermost function whose `loc` range contains
|
|
206
|
-
* the line. Smallest span wins, so a nested callback is preferred over
|
|
207
|
-
* the enclosing function that also contains the line.
|
|
208
|
-
* 3. **Nearest declaration** — the closest `decl` line within
|
|
209
|
-
* `DECL_MATCH_WINDOW`, which absorbs the ±1 token disagreement between
|
|
210
|
-
* escomplex's method start and istanbul's declaration line.
|
|
211
|
-
*
|
|
212
|
-
* Returns `null` when none of the three finds a function — the caller
|
|
213
|
-
* surfaces that as "no data" rather than "tested zero times."
|
|
163
|
+
* Exact start line, else innermost containing range, else nearest `decl`
|
|
164
|
+
* within `DECL_MATCH_WINDOW`; `null` means "no data", not "untested".
|
|
214
165
|
*
|
|
215
166
|
* @param {{fnByStartLine: Map, fnLocByStartLine: Map, fnRanges: Array}} idx
|
|
216
167
|
* @param {number} startLine
|
|
@@ -264,23 +215,9 @@ function getEntryIndex(entry) {
|
|
|
264
215
|
}
|
|
265
216
|
|
|
266
217
|
/**
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
*
|
|
270
|
-
* The ratio is the fraction of statements whose `start.line` falls within the
|
|
271
|
-
* function's `loc` range that were executed at least once. An empty range
|
|
272
|
-
* returns 0. A missing / malformed entry or no matching function returns
|
|
273
|
-
* `null` so the caller can distinguish "no data" from "tested zero times."
|
|
274
|
-
*
|
|
275
|
-
* `startLine` MUST be in the coverage entry's own (original-source)
|
|
276
|
-
* coordinate system. Callers scoring transpiled TypeScript remap escomplex's
|
|
277
|
-
* transpiled `lineStart` first — see `transpileIfNeeded`'s `withLineMap`
|
|
278
|
-
* option (Story #4775). Matching is exact-then-containment-then-nearest-decl;
|
|
279
|
-
* see `resolveFnRangeForLine`.
|
|
280
|
-
*
|
|
281
|
-
* The first call on a given entry builds and caches a per-entry index via a
|
|
282
|
-
* non-enumerable Symbol property; consecutive method lookups in the same
|
|
283
|
-
* file pay the build cost exactly once.
|
|
218
|
+
* Executed fraction of statements in the method's range (0 for an empty
|
|
219
|
+
* range, `null` for no data). `startLine` MUST be in original-source
|
|
220
|
+
* coordinates. The entry index is cached on the entry.
|
|
284
221
|
*
|
|
285
222
|
* @param {object|null} entry One inner value from a `coverage-final.json` map.
|
|
286
223
|
* @param {number} startLine The method's start line, in entry coordinates.
|
|
@@ -307,8 +244,6 @@ export function coverageForMethodInEntry(entry, startLine) {
|
|
|
307
244
|
}
|
|
308
245
|
|
|
309
246
|
/**
|
|
310
|
-
* Look up per-method coverage in a full coverage map.
|
|
311
|
-
*
|
|
312
247
|
* @param {object|null} map Parsed `coverage-final.json`.
|
|
313
248
|
* @param {string} relPath Repo-relative path of the source file.
|
|
314
249
|
* @param {number} startLine The method's start line, in entry coordinates.
|