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,13 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Row shape: `{ path, method, startLine, crap }`. The per-kind v2 envelope
|
|
5
|
-
* schema settles on `path` to match every other kind; the on-disk
|
|
6
|
-
* baseline carries canonical `path:` rows end-to-end.
|
|
7
|
-
*
|
|
8
|
-
* `kernelVersion()` returns the installed `typhonjs-escomplex` package
|
|
9
|
-
* version — the CRAP score depends on escomplex's cyclomatic-complexity
|
|
10
|
-
* output, so drift in that dependency invalidates every committed row.
|
|
2
|
+
* Per-kind module for the CRAP baseline. Row shape:
|
|
3
|
+
* `{ path, method, startLine, crap }`.
|
|
11
4
|
*/
|
|
12
5
|
|
|
13
6
|
import fs from 'node:fs';
|
|
@@ -45,37 +38,18 @@ import {
|
|
|
45
38
|
export const name = 'crap';
|
|
46
39
|
export const keyField = 'path';
|
|
47
40
|
|
|
48
|
-
// The CRAP baseline read path (Story #5002) lives in `_crap-read.js` — the ONE
|
|
49
|
-
// door, re-exported here so `preview-gates.js` and every existing importer keep
|
|
50
|
-
// reaching it through this module.
|
|
51
41
|
export { loadCrapBaseline } from './_crap-read.js';
|
|
52
42
|
|
|
53
43
|
const __filename = fileURLToPath(import.meta.url);
|
|
54
44
|
|
|
55
|
-
/**
|
|
56
|
-
* Package whose resolved version is stamped as the CRAP scorer identity.
|
|
57
|
-
*
|
|
58
|
-
* `escomplex-plugin-metrics-module` owns the Halstead and cyclomatic math. The
|
|
59
|
-
* displaced `typhonjs-escomplex` shell contributed a parser and a plugin bus
|
|
60
|
-
* and never computed a metric, so stamping it described the shell.
|
|
61
|
-
*/
|
|
45
|
+
/** The package that computes the metrics; its version stamps the scorer identity. */
|
|
62
46
|
const SCORER_PACKAGE = 'escomplex-plugin-metrics-module';
|
|
63
47
|
|
|
64
48
|
/**
|
|
65
|
-
* Resolve the
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* metrics. It was `typhonjs-escomplex` until Story #5336 replaced that shell's
|
|
70
|
-
* parse and dispatch layers; reading a package that no longer exists would
|
|
71
|
-
* yield the sentinel below on every fresh install, and the writer would refuse
|
|
72
|
-
* to persist a baseline. (Locally it can look fine anyway — the walk-up escapes
|
|
73
|
-
* a worktree into the parent checkout, whose `node_modules` may still hold the
|
|
74
|
-
* removed package. CI's fresh clone has no such parent.)
|
|
75
|
-
*
|
|
76
|
-
* Returns `'0.0.0'` when the dependency cannot be found — callers treat that
|
|
77
|
-
* sentinel as "unknown environment" and the writer refuses to persist a
|
|
78
|
-
* baseline.
|
|
49
|
+
* Resolve the scorer version from the nearest `node_modules/<SCORER_PACKAGE>`,
|
|
50
|
+
* walking up. Returns the `'0.0.0'` "unknown environment" sentinel when not
|
|
51
|
+
* found, which makes the writer refuse to persist. The walk-up can escape a
|
|
52
|
+
* worktree into the parent checkout, so a local pass does not prove CI's.
|
|
79
53
|
*
|
|
80
54
|
* @returns {string}
|
|
81
55
|
*/
|
|
@@ -108,56 +82,21 @@ export function kernelVersion() {
|
|
|
108
82
|
}
|
|
109
83
|
|
|
110
84
|
/**
|
|
111
|
-
* Scoring-semantics stamp
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* dropped when unresolved) are not comparable to rows scored by the join
|
|
118
|
-
* that replaced it (original-source coordinates, containment matching,
|
|
119
|
-
* honest `requireCoverage: false`): the same method can carry a different
|
|
120
|
-
* `crap`, a different `startLine`, or exist in one baseline and not the
|
|
121
|
-
* other. Comparing across that boundary produces phantom regressions and,
|
|
122
|
-
* worse, phantom passes.
|
|
123
|
-
*
|
|
124
|
-
* The stamp makes the boundary explicit and fails closed. Bump it whenever
|
|
125
|
-
* the coverage join, the line coordinate system, the unresolved-method policy,
|
|
126
|
-
* or the **method identity rule** changes.
|
|
127
|
-
*
|
|
128
|
-
* Story #4969 bumped it to `method-identity-v3` for the last of those. An
|
|
129
|
-
* anonymous method used to be keyed by escomplex's `<anon method-N>` ordinal
|
|
130
|
-
* and is now keyed by its enclosing-scope path; 34.6% of rows changed identity
|
|
131
|
-
* in one step. Rows keyed the old way and rows keyed the new way describe the
|
|
132
|
-
* same functions under different names, so pairing them is exactly the
|
|
133
|
-
* mis-keyed join this stamp exists to refuse — hence the bump, which is what
|
|
134
|
-
* makes the migration report nothing rather than a wall of phantom verdicts.
|
|
135
|
-
*
|
|
136
|
-
* Deliberately module-local: `envelopeExtras()` is the single production door
|
|
137
|
-
* to this value, so exporting the bare constant would add a second entry
|
|
138
|
-
* point that nothing in production reaches. Callers and tests that need the
|
|
139
|
-
* string read it off `envelopeExtras().scoringSemantics`.
|
|
85
|
+
* Scoring-semantics stamp. The scorer version does not move when this repo's
|
|
86
|
+
* coverage join changes, yet rows scored under different joins are not
|
|
87
|
+
* comparable (phantom regressions and phantom passes), so the stamp fails
|
|
88
|
+
* closed across that boundary. Bump it whenever the coverage join, the line
|
|
89
|
+
* coordinate system, the unresolved-method policy, or the method identity
|
|
90
|
+
* rule changes. Module-local: read it via `envelopeExtras().scoringSemantics`.
|
|
140
91
|
*/
|
|
141
92
|
const SCORING_SEMANTICS = 'method-identity-v3';
|
|
142
93
|
|
|
143
94
|
/**
|
|
144
|
-
* Envelope
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
* `
|
|
148
|
-
*
|
|
149
|
-
* so, and that map is the transpiler's output — so a transpiler change can
|
|
150
|
-
* move every TS row's coordinate, which is half the row identity key. Without
|
|
151
|
-
* the stamp on disk the `ts-transpiler-drift` axis had nothing to compare and
|
|
152
|
-
* passed vacuously.
|
|
153
|
-
*
|
|
154
|
-
* `provenanceStamped` joined in Story #4901 as a **positive** marker: the
|
|
155
|
-
* writer asserting it recorded per-row provenance at all. Absence is the only
|
|
156
|
-
* evidence a pre-#4866 baseline leaves, and no other stamp detects it —
|
|
157
|
-
* `kernelVersion` / `escomplexVersion` track the escomplex package (unmoved
|
|
158
|
-
* by the fix), `scoringSemantics` did not change, and `tsTranspilerVersion`
|
|
159
|
-
* is unreliable in the negative (the `'0.0.0'` sentinel). See the
|
|
160
|
-
* `provenance-unstamped` axis.
|
|
95
|
+
* Envelope stamps this kind adds, consumed by `writer.write`. A transpiler
|
|
96
|
+
* change can move every TS row's `startLine` (half the row identity key), so
|
|
97
|
+
* `tsTranspilerVersion` is stamped for the `ts-transpiler-drift` axis.
|
|
98
|
+
* `provenanceStamped` is a positive marker that per-row provenance was
|
|
99
|
+
* recorded; no other stamp can detect its absence.
|
|
161
100
|
*
|
|
162
101
|
* @returns {{scoringSemantics: string, tsTranspilerVersion: string,
|
|
163
102
|
* provenanceStamped: boolean}}
|
|
@@ -171,13 +110,9 @@ export function envelopeExtras() {
|
|
|
171
110
|
}
|
|
172
111
|
|
|
173
112
|
/**
|
|
174
|
-
* Project a scan row onto the persisted
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
* `original` (Story #4866). A pure-JavaScript scan therefore emits the exact
|
|
178
|
-
* four-key row it always did — byte-identical baselines, no refresh — while a
|
|
179
|
-
* row that kept transpiled coordinates is distinguishable on disk from one
|
|
180
|
-
* whose sourcemap lookup resolved.
|
|
113
|
+
* Project a scan row onto the persisted row shape. `coordinateSystem` and
|
|
114
|
+
* `anonymous` are written only when non-default, so a plain JS row stays the
|
|
115
|
+
* four-key row and existing baselines stay byte-identical.
|
|
181
116
|
*/
|
|
182
117
|
export function projectRow(row) {
|
|
183
118
|
const projected = {
|
|
@@ -189,9 +124,7 @@ export function projectRow(row) {
|
|
|
189
124
|
if (row.coordinateSystem === COORDINATE_TRANSPILED) {
|
|
190
125
|
projected.coordinateSystem = COORDINATE_TRANSPILED;
|
|
191
126
|
}
|
|
192
|
-
//
|
|
193
|
-
// `method` that is a derived scope-path identity rather than a name the
|
|
194
|
-
// source carries. A named row stays the exact four-key row it always was.
|
|
127
|
+
// `anonymous`: `method` is a derived scope-path identity, not a source name.
|
|
195
128
|
if (row.anonymous === true) {
|
|
196
129
|
projected.anonymous = true;
|
|
197
130
|
}
|
|
@@ -199,12 +132,8 @@ export function projectRow(row) {
|
|
|
199
132
|
}
|
|
200
133
|
|
|
201
134
|
/**
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
* A baseline written before Story #4866 carries no stamp at all, and every
|
|
205
|
-
* such row IS an original-source coordinate — un-remapped rows could not
|
|
206
|
-
* reach a `requireCoverage: true` baseline, and the pure-JavaScript case was
|
|
207
|
-
* never affected. Defaulting is therefore back-compatible, not a guess.
|
|
135
|
+
* A row's coordinate provenance. An unstamped row is always an
|
|
136
|
+
* original-source coordinate, so the default is sound, not a guess.
|
|
208
137
|
*
|
|
209
138
|
* @param {{coordinateSystem?: string}|null|undefined} row
|
|
210
139
|
* @returns {string}
|
|
@@ -221,8 +150,6 @@ export function sortRows(rows) {
|
|
|
221
150
|
});
|
|
222
151
|
}
|
|
223
152
|
|
|
224
|
-
// Re-export percentile so existing consumers that imported it from crap.js
|
|
225
|
-
// keep working without an import path change.
|
|
226
153
|
export { percentile };
|
|
227
154
|
|
|
228
155
|
const aggregate = makeAggregate({
|
|
@@ -241,23 +168,9 @@ const aggregate = makeAggregate({
|
|
|
241
168
|
export const rollup = makeRollup({ aggregate });
|
|
242
169
|
|
|
243
170
|
/**
|
|
244
|
-
* Pure compare(head, base)
|
|
245
|
-
* `
|
|
246
|
-
*
|
|
247
|
-
* Higher CRAP = worse. A row regresses when its crap score increases vs
|
|
248
|
-
* base; improves when it decreases; unchanged when equal. New methods
|
|
249
|
-
* land in the `additions` bucket; absolute-ceiling enforcement is the
|
|
250
|
-
* unified `check-baselines` gate's job (the per-method ceiling is a
|
|
251
|
-
* different concern from regression vs base). Removed methods with
|
|
252
|
-
* prior crap > 0 count as improvements.
|
|
253
|
-
*
|
|
254
|
-
* Story #2012 — sibling fix to maintainability.compare. The prior
|
|
255
|
-
* behaviour treated any new method with crap > 0 as a regression, which
|
|
256
|
-
* conflated "new code with a non-zero score" with "existing code that
|
|
257
|
-
* got worse". New methods are now `additions` so a Story that lands a
|
|
258
|
-
* new file no longer fails close-validation through the regression arm.
|
|
259
|
-
*
|
|
260
|
-
* No I/O. No process exit. No friction emission.
|
|
171
|
+
* Pure compare(head, base) keyed by `path::method@startLine`; higher CRAP is
|
|
172
|
+
* worse. New methods are `additions`, not regressions — the new-method
|
|
173
|
+
* ceiling is `check-baselines`' job.
|
|
261
174
|
*/
|
|
262
175
|
export const compare = makeCompare({
|
|
263
176
|
identity: rowIdentity,
|
|
@@ -268,17 +181,9 @@ export const compare = makeCompare({
|
|
|
268
181
|
});
|
|
269
182
|
|
|
270
183
|
/**
|
|
271
|
-
* Canonical
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
* This kind is the reason identity is a separate concept from `keyField`.
|
|
276
|
-
* `keyField` is `'path'` because the rollup groups by file, but a file
|
|
277
|
-
* ships one row per method, so a merge keyed on `keyField` would collapse
|
|
278
|
-
* every method in a file to one row and drop the rest. `compare`,
|
|
279
|
-
* `applyEpsilon` and `mergeRows` have always keyed on this composite;
|
|
280
|
-
* exporting it makes the same identity available to callers that used to
|
|
281
|
-
* have no choice but to guess from `keyField`.
|
|
184
|
+
* Canonical row identity. Distinct from `keyField` (`'path'`, the rollup
|
|
185
|
+
* grouping): a file has one row per method, so keying a merge on `keyField`
|
|
186
|
+
* would collapse them.
|
|
282
187
|
*
|
|
283
188
|
* @param {{path: string, method: string, startLine: number}} row
|
|
284
189
|
* @returns {string}
|
|
@@ -287,17 +192,8 @@ export function rowIdentity(row) {
|
|
|
287
192
|
return `${row.path}::${row.method}@${row.startLine}`;
|
|
288
193
|
}
|
|
289
194
|
|
|
290
|
-
// `methodIdentityKey` / `indexBaselineRowsByFile` (Story #4981) are now
|
|
291
|
-
// module-local to `crap-baseline-join.js` (Story #5002): after that module
|
|
292
|
-
// absorbed the per-file queue wiring, both callers are inside it, so the
|
|
293
|
-
// exports — and the re-export that used to live here — were reachable from
|
|
294
|
-
// tests alone. `resolveIncrementalContext` is the production door to the
|
|
295
|
-
// index; `rowIdentity` above is the composite key it halves.
|
|
296
|
-
|
|
297
195
|
/**
|
|
298
|
-
*
|
|
299
|
-
* by the composite `path::method@startLine` identity. Sub-epsilon CRAP
|
|
300
|
-
* deltas resolve to the prior row bytes; missing-prior rows fall through.
|
|
196
|
+
* Sub-epsilon CRAP deltas resolve to the prior row bytes.
|
|
301
197
|
*
|
|
302
198
|
* @param {Array<{path: string, method: string, startLine: number, crap: number}>} prior
|
|
303
199
|
* @param {Array<{path: string, method: string, startLine: number, crap: number}>} regenerated
|
|
@@ -310,12 +206,8 @@ export const applyEpsilon = makeEpsilon({
|
|
|
310
206
|
});
|
|
311
207
|
|
|
312
208
|
/**
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
* filter applies on `path` alone (a Story diff identifies files, not
|
|
316
|
-
* methods). In diff mode, rows whose `path` is OUTSIDE `scope.files` are
|
|
317
|
-
* preserved from `prior` verbatim — including every method on that file.
|
|
318
|
-
* In full mode (or no scope), regenerated wins everywhere.
|
|
209
|
+
* Scope-aware merge: identity is per method, but scope filters on `path`
|
|
210
|
+
* alone (a diff names files), so out-of-scope files keep every prior row.
|
|
319
211
|
*
|
|
320
212
|
* @param {Array<{path: string, method: string, startLine: number, crap: number}>} prior
|
|
321
213
|
* @param {Array<{path: string, method: string, startLine: number, crap: number}>} regenerated
|
|
@@ -332,20 +224,11 @@ export function mergeRows(prior, regenerated, scope) {
|
|
|
332
224
|
});
|
|
333
225
|
}
|
|
334
226
|
|
|
335
|
-
//
|
|
336
|
-
// CLI-facing pure helpers (Story #1981, Task #1989).
|
|
337
|
-
// Hoisted from `.agents/scripts/check-crap.js` so the per-kind module owns
|
|
338
|
-
// the loader / comparator / report-builder / floor-enforcer surface and the
|
|
339
|
-
// CLI shell is reduced to argv parsing + orchestration. Behavior preserved
|
|
340
|
-
// byte-for-byte vs the CLI version; only the import path changed.
|
|
341
|
-
// ---------------------------------------------------------------------------
|
|
227
|
+
// CLI-facing pure helpers for `check-crap.js`.
|
|
342
228
|
|
|
343
229
|
/**
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
* so the `--changed-since` code path treats both sides of the comparison
|
|
347
|
-
* the same way (otherwise every baseline row for an untouched file would
|
|
348
|
-
* surface as "removed" on every diff-scoped run).
|
|
230
|
+
* Narrow rows to those whose `file` is in `scopeSet`. Apply to both scan and
|
|
231
|
+
* baseline rows, or untouched files surface as "removed" on a scoped run.
|
|
349
232
|
*
|
|
350
233
|
* @template {{file: string}} R
|
|
351
234
|
* @param {R[]} rows
|
|
@@ -358,18 +241,10 @@ export function filterRowsByFileScope(rows, scopeSet) {
|
|
|
358
241
|
}
|
|
359
242
|
|
|
360
243
|
/**
|
|
361
|
-
*
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
* Trivial (cyclomatic=1) methods are exempted from the regression check.
|
|
366
|
-
* Their CRAP score collapses to a pure coverage proxy in [1, 2] — under
|
|
367
|
-
* non-deterministic Node 22 V8 instrumentation on Windows CI, single-
|
|
368
|
-
* statement wrappers like `deleteComment(ctx, id)` flap between cov=1.00
|
|
369
|
-
* (crap=1) and cov=0.17 (crap≈1.58) across runs of identical source. A
|
|
370
|
-
* real regression on a c=1 method requires it to gain branches, at which
|
|
371
|
-
* point row.cyclomatic is no longer 1 and this exemption no longer
|
|
372
|
-
* applies. New-method ceiling enforcement is unaffected.
|
|
244
|
+
* The violation for a (current, baseline) pair, or `null` when it passes.
|
|
245
|
+
* Cyclomatic-1 methods are exempt: their CRAP is a pure coverage proxy that
|
|
246
|
+
* flaps under non-deterministic V8 instrumentation on Windows CI, and a real
|
|
247
|
+
* regression would add branches and lose the exemption anyway.
|
|
373
248
|
*
|
|
374
249
|
* @param {{cyclomatic: number, crap: number}} row
|
|
375
250
|
* @param {{crap: number, startLine: number}} baseline
|
|
@@ -389,51 +264,18 @@ export function checkCrapRegression(row, baseline, tolerance, kind) {
|
|
|
389
264
|
}
|
|
390
265
|
|
|
391
266
|
/**
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
396
|
-
*
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
*
|
|
400
|
-
*
|
|
401
|
-
*
|
|
402
|
-
*
|
|
403
|
-
*
|
|
404
|
-
* (Story #4866). Reported, never scored.
|
|
405
|
-
* 4. **new** — no baseline match. Violates if crap > ceiling.
|
|
406
|
-
* 5. **removed** — baseline rows not seen in the current scan.
|
|
407
|
-
* Surfaced only; never a failure.
|
|
408
|
-
*
|
|
409
|
-
* **Why the incomparable bucket exists.** The drift heuristic assumes both
|
|
410
|
-
* rows measure the same axis and the method simply moved along it. When one
|
|
411
|
-
* row's line is an original-source coordinate and the other's is a transpiled
|
|
412
|
-
* one, the "distance" it minimises over is the gap between two coordinate
|
|
413
|
-
* systems, not a code movement — so it pairs rows arbitrarily and then scores
|
|
414
|
-
* the pairing. That is precisely how a scan that changed nothing reports a
|
|
415
|
-
* regression no edit can satisfy. Refusing is the only sound answer: a row
|
|
416
|
-
* whose provenance differs from every candidate's is counted and surfaced,
|
|
417
|
-
* and it does NOT fall through to the new-method arm (it is not new; it is
|
|
418
|
-
* unmeasurable against this baseline).
|
|
419
|
-
*
|
|
420
|
-
* **`provenanceMismatched` is captured BEFORE the provenance filter runs**
|
|
421
|
-
* (Story #4871). `incomparable` only counts rows where *every* candidate
|
|
422
|
-
* disagreed on coordinates; a row with one agreeing candidate and three
|
|
423
|
-
* disagreeing ones scores normally and leaves no trace. That made the
|
|
424
|
-
* evidence of coordinate mixing strictly narrower than the mixing itself —
|
|
425
|
-
* and the unsound-basis backstop, which needs exactly that evidence, had
|
|
426
|
-
* nothing sound to read. The counter below is incremented for **any** row
|
|
427
|
-
* with at least one provenance-mismatched candidate, whichever arm then
|
|
428
|
-
* resolves it.
|
|
429
|
-
*
|
|
430
|
-
* **Unscorable rows never reach an arm.** A row the scan could not score
|
|
431
|
-
* (`crap: null` / `coverage: null`, or an explicit `unscorable: true`) carries
|
|
432
|
-
* no measurement to compare. It is bucketed and counted, and it is excluded
|
|
433
|
-
* from `comparable` so it cannot dilute any ratio derived from this result.
|
|
434
|
-
*
|
|
435
|
-
* **A new method in a wholly-uncovered file is gated on complexity alone**
|
|
436
|
-
* (Story #5002) — see `newMethodGateScore`.
|
|
267
|
+
* Compare scanned rows to baseline rows. Match arms: **exact** (same file,
|
|
268
|
+
* method, startLine), **drifted** (same method, nearest startLine),
|
|
269
|
+
* **incomparable** (every candidate is in a different coordinate system),
|
|
270
|
+
* **new** (gated against the ceiling), **removed** (surfaced only).
|
|
271
|
+
*
|
|
272
|
+
* Across coordinate systems the drift heuristic would pair rows arbitrarily
|
|
273
|
+
* and report regressions no edit can satisfy, so such rows are counted, not
|
|
274
|
+
* scored, and never fall through to the new-method arm.
|
|
275
|
+
* `provenanceMismatched` counts any row with at least one mismatched
|
|
276
|
+
* candidate, captured before the filter discards that evidence — it feeds the
|
|
277
|
+
* unsound-basis backstop. Unscorable rows (null crap/coverage) are bucketed
|
|
278
|
+
* and excluded from `comparable` so they cannot dilute a ratio.
|
|
437
279
|
*/
|
|
438
280
|
export function compareCrap({
|
|
439
281
|
currentRows,
|
|
@@ -469,7 +311,6 @@ export function compareCrap({
|
|
|
469
311
|
const methodKey = `${row.file}::${row.method}`;
|
|
470
312
|
const rowCoords = coordinateSystemOf(row);
|
|
471
313
|
const candidates = methodIndex.get(methodKey) ?? [];
|
|
472
|
-
// Evidence first, filtering second — see the block comment above.
|
|
473
314
|
if (candidates.some((c) => coordinateSystemOf(c) !== rowCoords)) {
|
|
474
315
|
provenanceMismatched += 1;
|
|
475
316
|
}
|
|
@@ -486,9 +327,6 @@ export function compareCrap({
|
|
|
486
327
|
}
|
|
487
328
|
|
|
488
329
|
if (candidates.length > 0) {
|
|
489
|
-
// Only rows expressed in the SAME coordinate system are comparable;
|
|
490
|
-
// everything else would be resolved through a line-distance heuristic
|
|
491
|
-
// that cannot mean anything across two coordinate systems.
|
|
492
330
|
const comparable = candidates.filter(
|
|
493
331
|
(c) => coordinateSystemOf(c) === rowCoords,
|
|
494
332
|
);
|
|
@@ -531,8 +369,7 @@ export function compareCrap({
|
|
|
531
369
|
const total = currentRows?.length ?? 0;
|
|
532
370
|
return {
|
|
533
371
|
total,
|
|
534
|
-
//
|
|
535
|
-
// denominator of every ratio derived from this result.
|
|
372
|
+
// Denominator of every ratio derived from this result.
|
|
536
373
|
comparable: total - unscorableRows.length,
|
|
537
374
|
regressions,
|
|
538
375
|
newViolations,
|
|
@@ -549,12 +386,8 @@ export function compareCrap({
|
|
|
549
386
|
}
|
|
550
387
|
|
|
551
388
|
/**
|
|
552
|
-
*
|
|
553
|
-
*
|
|
554
|
-
* Deliberately strict on `null`: a scan row always sets `crap`, and the
|
|
555
|
-
* scorer's own contract is that an unresolved method yields `crap: null` /
|
|
556
|
-
* `coverage: null` rather than an inferred zero. A caller-built row that
|
|
557
|
-
* simply omits `coverage` is not making that claim and stays scorable.
|
|
389
|
+
* Strict on `null` (the scorer's "unresolved" value); a row merely omitting
|
|
390
|
+
* `coverage` stays scorable.
|
|
558
391
|
*
|
|
559
392
|
* @param {{crap?: number|null, coverage?: number|null, unscorable?: boolean}} row
|
|
560
393
|
* @returns {boolean}
|
|
@@ -566,10 +399,8 @@ function isUnscorableRow(row) {
|
|
|
566
399
|
}
|
|
567
400
|
|
|
568
401
|
/**
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
* first when every candidate has already been claimed (duplicate method
|
|
572
|
-
* names in one file).
|
|
402
|
+
* Closest unclaimed candidate by `startLine`; the first when all are claimed
|
|
403
|
+
* (duplicate method names in one file).
|
|
573
404
|
*
|
|
574
405
|
* @param {Array<{file: string, method: string, startLine: number}>} comparable
|
|
575
406
|
* @param {{startLine: number}} row
|
|
@@ -592,62 +423,24 @@ function pickDriftCandidate(comparable, row, seenBaselineKeys) {
|
|
|
592
423
|
}
|
|
593
424
|
|
|
594
425
|
/**
|
|
595
|
-
*
|
|
596
|
-
*
|
|
597
|
-
*
|
|
598
|
-
*
|
|
599
|
-
* **What this ratio must measure.** The backstop exists for one condition: the
|
|
600
|
-
* scan and the baseline expressing `startLine` in different coordinate
|
|
601
|
-
* systems, which makes the nearest-line drift heuristic pair rows arbitrarily
|
|
602
|
-
* and then score the pairing. The only quantity that evidences that condition
|
|
603
|
-
* is a provenance disagreement between a row and its baseline candidates.
|
|
604
|
-
*
|
|
605
|
-
* **Why `drifted` was the wrong numerator.** A row reaches the drift arm only
|
|
606
|
-
* *after* passing the provenance filter, so every drifted row is one whose
|
|
607
|
-
* coordinate system **agreed** with its baseline's. Counting agreements as
|
|
608
|
-
* evidence of disagreement is not a mis-calibration, it is the wrong
|
|
609
|
-
* measurement: on this pure-JavaScript repository — where a coordinate mix is
|
|
610
|
-
* structurally impossible — it read 56–68% across every diff scope, which
|
|
611
|
-
* suppressed the gate's per-method verdicts on every commit while the gate
|
|
612
|
-
* still reported success. `startLine` is half the row identity key, so any
|
|
613
|
-
* insertion re-keys every method below it; ordinary drift is the normal
|
|
614
|
-
* operating state, not an anomaly.
|
|
615
|
-
*
|
|
616
|
-
* Deliberately module-local, like `SCORING_SEMANTICS` above: the three
|
|
617
|
-
* tuning values below are reachable through `assessComparisonBasis` — which
|
|
618
|
-
* takes them as overridable options — so exporting the bare constants would
|
|
619
|
-
* add entry points nothing in production reaches.
|
|
426
|
+
* Share of comparable rows with a provenance mismatch above which the basis
|
|
427
|
+
* is unsound. The numerator must be provenance mismatch, never `drifted`:
|
|
428
|
+
* drifted rows passed the provenance filter, and ordinary insertions drift
|
|
429
|
+
* most rows.
|
|
620
430
|
*/
|
|
621
431
|
const UNSOUND_BASIS_MISMATCH_RATIO = 0.5;
|
|
622
432
|
|
|
623
|
-
/**
|
|
624
|
-
* Minimum comparable rows before the unsound-basis check is allowed to fire.
|
|
625
|
-
* A diff-scoped preview can legitimately score three methods, two of which
|
|
626
|
-
* moved; that is a normal edit, not a broken basis. Mirrors the
|
|
627
|
-
* minimum-sample discipline the coverage-join resolution floor already uses.
|
|
628
|
-
*/
|
|
433
|
+
/** Small diff-scoped samples legitimately drift; don't judge them. */
|
|
629
434
|
const UNSOUND_BASIS_MIN_SAMPLE = 20;
|
|
630
435
|
|
|
631
|
-
/** Diagnostic name for an unsound comparison basis. */
|
|
632
436
|
const UNSOUND_BASIS_DIAGNOSTIC = 'crap-unsound-comparison-basis';
|
|
633
437
|
|
|
634
|
-
/** Diagnostic name for a baseline the running scorer refuses to compare. */
|
|
635
438
|
export const INCOMPATIBLE_BASELINE_DIAGNOSTIC = 'crap-baseline-incompatible';
|
|
636
439
|
|
|
637
440
|
/**
|
|
638
|
-
*
|
|
639
|
-
*
|
|
640
|
-
*
|
|
641
|
-
* included at least one expressed in a different coordinate system, counted
|
|
642
|
-
* by `compareCrap` **before** its provenance filter discards that evidence.
|
|
643
|
-
* The denominator is `comparable`: rows that carried a measurement at all, so
|
|
644
|
-
* a method the scan could not score cannot dilute the ratio into silence.
|
|
645
|
-
*
|
|
646
|
-
* Above the ratio the per-method verdicts are noise derived from a mis-keyed
|
|
647
|
-
* join, and reporting them as regressions asks the operator to fix code that
|
|
648
|
-
* is not broken. Below it — including a scan where every row drifted, which
|
|
649
|
-
* is what an ordinary insertion produces — the verdicts stand.
|
|
650
|
-
*
|
|
441
|
+
* Whether a `compareCrap` result rests on a sound basis
|
|
442
|
+
* (`provenanceMismatched / comparable`). Above the ratio the per-method
|
|
443
|
+
* verdicts come from a mis-keyed join and must be suppressed.
|
|
651
444
|
* Returns `{ sound: true }` or `{ sound: false, diagnostic: {name, message} }`.
|
|
652
445
|
*
|
|
653
446
|
* @param {{total?: number, comparable?: number, provenanceMismatched?: number,
|
|
@@ -663,8 +456,7 @@ export function assessComparisonBasis(compareResult, opts = {}) {
|
|
|
663
456
|
: UNSOUND_BASIS_MIN_SAMPLE;
|
|
664
457
|
const comparable = compareResult?.comparable ?? compareResult?.total ?? 0;
|
|
665
458
|
if (comparable < minSample) return { sound: true };
|
|
666
|
-
// `incomparable` is
|
|
667
|
-
// it is already counted; the max guards a caller that supplies only one.
|
|
459
|
+
// `incomparable` is a subset; max guards a caller supplying only one.
|
|
668
460
|
const mismatched = Math.max(
|
|
669
461
|
compareResult?.provenanceMismatched ?? 0,
|
|
670
462
|
compareResult?.incomparable ?? 0,
|
|
@@ -692,51 +484,19 @@ export function assessComparisonBasis(compareResult, opts = {}) {
|
|
|
692
484
|
};
|
|
693
485
|
}
|
|
694
486
|
|
|
695
|
-
/**
|
|
696
|
-
* Declarative axis table for `evaluateBaselineCompatibility` (Story #2467).
|
|
697
|
-
*
|
|
698
|
-
* Each axis is a pure `{ name, severity, check }` triple. `check` receives
|
|
699
|
-
* the compat context `{ baseline, runningKernelVersion,
|
|
700
|
-
* runningEscomplexVersion, runningTsTranspilerVersion }` and returns either
|
|
701
|
-
* `null` (axis passed) or a `string` message describing the failure.
|
|
702
|
-
*
|
|
703
|
-
* - `severity: 'fatal'` — first match short-circuits the reduce and the
|
|
704
|
-
* function returns `{ ok: false, exitCode: 1, kind, message }`.
|
|
705
|
-
* - `severity: 'warn'` — every match accumulates into `warnings[]` and the
|
|
706
|
-
* function still returns `{ ok: true, warnings }`.
|
|
707
|
-
*
|
|
708
|
-
* Story #791 retired the transitional `bootstrap` exit-0 path: a missing
|
|
709
|
-
* baseline still fails closed. Story #829 (5.29.0) softened `kernelVersion`
|
|
710
|
-
* drift to **warn**, not fail, and did the same for `tsTranspilerVersion` —
|
|
711
|
-
* but that second half was re-escalated to **fatal** once Story #4866 made a
|
|
712
|
-
* TS row's `startLine` an original-source coordinate resolved through the
|
|
713
|
-
* transpiler's sourcemap. `startLine` is half the row identity key, so a
|
|
714
|
-
* transpiler change makes the rows incomparable rather than merely stale; see
|
|
715
|
-
* the `ts-transpiler-drift` axis below for the two exemptions that bound it.
|
|
716
|
-
*
|
|
717
|
-
* There is no `escomplexVersion` axis. One existed, declared `fatal`, and
|
|
718
|
-
* could not fire in either direction: the v2 envelope does not carry the
|
|
719
|
-
* field, so the loaded-envelope pass excluded it as vacuous, and the peer pass
|
|
720
|
-
* back-filled the value from the running scorer before comparing it against
|
|
721
|
-
* the running scorer. A gate that presents as fatal and cannot fail is worse
|
|
722
|
-
* than an absent one, so it was removed rather than repaired — `scoringSemantics`
|
|
723
|
-
* is the axis that actually rejects an incompatible scorer.
|
|
724
|
-
*/
|
|
725
|
-
/**
|
|
726
|
-
* The one re-seed recipe every coordinate-invalidating axis ends on. Three
|
|
727
|
-
* axes and the unsound-basis diagnostic previously carried their own copy of
|
|
728
|
-
* this sentence; a single constant keeps them from drifting apart on the
|
|
729
|
-
* command an operator is told to run.
|
|
730
|
-
*/
|
|
731
487
|
const RESEED_REMEDY =
|
|
732
488
|
"Re-derive the baseline: run 'npm run test:coverage' then " +
|
|
733
489
|
"'npm run crap:update -- --full-scope' and commit the result with a " +
|
|
734
490
|
"'baseline-refresh:' subject.";
|
|
735
491
|
|
|
492
|
+
/**
|
|
493
|
+
* Compat axes for `evaluateBaselineCompatibility`: `{ name, severity, check }`,
|
|
494
|
+
* where `check(ctx)` returns null or a failure message. The first `fatal`
|
|
495
|
+
* match fails; `warn` matches accumulate. Kernel drift only warns; a
|
|
496
|
+
* transpiler change is fatal because it moves `startLine`, half the row
|
|
497
|
+
* identity key.
|
|
498
|
+
*/
|
|
736
499
|
export const CRAP_COMPAT_AXES = [
|
|
737
|
-
// Universal axes hoisted into envelope.js (Story #2467, Task #2492). The
|
|
738
|
-
// missing-baseline and kernel-drift checks live in exactly one place;
|
|
739
|
-
// each per-kind table composes them in with its own kind label.
|
|
740
500
|
missingBaselineAxis('CRAP'),
|
|
741
501
|
kernelDriftAxis('CRAP'),
|
|
742
502
|
{
|
|
@@ -761,15 +521,10 @@ export const CRAP_COMPAT_AXES = [
|
|
|
761
521
|
if (!baseline) return null;
|
|
762
522
|
if (!isKnownVersion(runningTsTranspilerVersion)) return null;
|
|
763
523
|
const baselineTs = baseline.tsTranspilerVersion;
|
|
764
|
-
//
|
|
765
|
-
// stamp landed in Story #4866 and comparing against its absence would
|
|
766
|
-
// fail every pre-existing baseline closed for no evidence at all.
|
|
524
|
+
// Unstamped: no evidence either way (see `provenance-unstamped`).
|
|
767
525
|
if (!isKnownVersion(baselineTs)) return null;
|
|
768
526
|
if (baselineTs === runningTsTranspilerVersion) return null;
|
|
769
|
-
//
|
|
770
|
-
// transpiler change moves TS row coordinates and nothing else. A
|
|
771
|
-
// pure-JavaScript tree has no coordinate to move, so a TS bump there is
|
|
772
|
-
// not a coordinate-invalidating event and must not fail its gate.
|
|
527
|
+
// A pure-JS baseline has no transpiled coordinate to move.
|
|
773
528
|
if (!hasTranspiledRows(baseline)) return null;
|
|
774
529
|
return (
|
|
775
530
|
`[CRAP] tsTranspilerVersion changed: baseline=${baselineTs} running=${runningTsTranspilerVersion}. ` +
|
|
@@ -780,15 +535,9 @@ export const CRAP_COMPAT_AXES = [
|
|
|
780
535
|
},
|
|
781
536
|
},
|
|
782
537
|
{
|
|
783
|
-
//
|
|
784
|
-
//
|
|
785
|
-
//
|
|
786
|
-
// exactly that shape, so the one door that could catch it lets it through
|
|
787
|
-
// while it asserts by omission that all its rows are original coordinates.
|
|
788
|
-
// Keyed on a positive marker because absence alone cannot separate
|
|
789
|
-
// "written before provenance existed" from "typescript was unresolvable".
|
|
790
|
-
// Scoped like `ts-transpiler-drift`: a pure-JavaScript baseline's two
|
|
791
|
-
// coordinate systems coincide, so it was never affected and must not fail.
|
|
538
|
+
// Closes the unstamped exemption above. Keyed on a positive marker, since
|
|
539
|
+
// absence can't separate "no provenance" from "typescript unresolvable";
|
|
540
|
+
// scoped to transpiled rows because pure-JS coordinates coincide.
|
|
792
541
|
name: 'provenance-unstamped',
|
|
793
542
|
severity: 'fatal',
|
|
794
543
|
check: ({ baseline }) =>
|
|
@@ -804,20 +553,10 @@ export const CRAP_COMPAT_AXES = [
|
|
|
804
553
|
: null,
|
|
805
554
|
},
|
|
806
555
|
{
|
|
807
|
-
//
|
|
808
|
-
//
|
|
809
|
-
//
|
|
810
|
-
//
|
|
811
|
-
// for the files that were never re-scored while the writer stamps the
|
|
812
|
-
// envelope with the current semantics — the stamp says v3, some rows are
|
|
813
|
-
// still v2, and the one axis that would catch it has already passed.
|
|
814
|
-
//
|
|
815
|
-
// Such a row cannot be paired with anything: its `<anon method-N>` label
|
|
816
|
-
// matches no scope-path identity, so the comparator files the live method
|
|
817
|
-
// as NEW (scored against the ceiling, not its own baseline) and the stale
|
|
818
|
-
// row as removed. Keyed on the positive `anonymous` marker for the same
|
|
819
|
-
// reason `provenance-unstamped` is: absence is the only trace the old
|
|
820
|
-
// writer leaves.
|
|
556
|
+
// Catches a half-migrated baseline: a diff-scoped refresh keeps
|
|
557
|
+
// out-of-scope ordinal-keyed anonymous rows under a current-semantics
|
|
558
|
+
// stamp, and those rows pair with nothing. Keyed on the positive
|
|
559
|
+
// `anonymous` marker.
|
|
821
560
|
name: 'anon-identity-unstamped',
|
|
822
561
|
severity: 'fatal',
|
|
823
562
|
check: ({ baseline }) => {
|
|
@@ -843,10 +582,7 @@ export const CRAP_COMPAT_AXES = [
|
|
|
843
582
|
const TRANSPILED_SOURCE_RE = /\.(?:ts|tsx|mts|cts)$/i;
|
|
844
583
|
|
|
845
584
|
/**
|
|
846
|
-
* `'0.0.0'` is
|
|
847
|
-
* a resolved dependency version, not a real release. Treating it as a
|
|
848
|
-
* comparable value would turn "we could not resolve typescript" into
|
|
849
|
-
* "typescript changed".
|
|
585
|
+
* `'0.0.0'` is the "unknown environment" sentinel, not a comparable version.
|
|
850
586
|
*
|
|
851
587
|
* @param {unknown} version
|
|
852
588
|
* @returns {boolean}
|
|
@@ -856,9 +592,6 @@ function isKnownVersion(version) {
|
|
|
856
592
|
}
|
|
857
593
|
|
|
858
594
|
/**
|
|
859
|
-
* True when a baseline contains at least one row derived from a transpiled
|
|
860
|
-
* source — the only rows a transpiler-version change can move.
|
|
861
|
-
*
|
|
862
595
|
* @param {{rows?: Array<{path?: string, file?: string}>}|null} baseline
|
|
863
596
|
* @returns {boolean}
|
|
864
597
|
*/
|
|
@@ -868,32 +601,13 @@ function hasTranspiledRows(baseline) {
|
|
|
868
601
|
);
|
|
869
602
|
}
|
|
870
603
|
|
|
871
|
-
/**
|
|
872
|
-
* Pure decision helper for the missing-baseline / kernel-mismatch /
|
|
873
|
-
* escomplex-mismatch / tsTranspiler-mismatch gate paths. Lets tests
|
|
874
|
-
* assert the exact operator-facing message without spawning a child
|
|
875
|
-
* process.
|
|
876
|
-
*
|
|
877
|
-
* Story #2467 rewrote the body as a reduce over `CRAP_COMPAT_AXES` to
|
|
878
|
-
* collapse the cyclomatic complexity below the project ceiling. Behavior
|
|
879
|
-
* is preserved byte-for-byte vs the prior imperative implementation.
|
|
880
|
-
*/
|
|
881
604
|
export function evaluateBaselineCompatibility(ctx) {
|
|
882
605
|
return reduceCompatAxes(CRAP_COMPAT_AXES, ctx);
|
|
883
606
|
}
|
|
884
607
|
|
|
885
608
|
/**
|
|
886
|
-
*
|
|
887
|
-
*
|
|
888
|
-
* identity key. Three are about the `startLine` half: one names the join that
|
|
889
|
-
* produced the rows, one names the transpiler whose sourcemap decided what a
|
|
890
|
-
* TS row's `startLine` even means, and one (Story #4901) catches a baseline
|
|
891
|
-
* predating both questions. The fourth (Story #4969) is about the `method`
|
|
892
|
-
* half — a baseline still carrying ordinal-keyed anonymous rows.
|
|
893
|
-
*
|
|
894
|
-
* `kernel-drift` stays out: it is a warn-level axis, and this pass turns a
|
|
895
|
-
* message into a fail-closed error. (`escomplex-mismatch` was the other
|
|
896
|
-
* exclusion until it was removed outright — see `CRAP_COMPAT_AXES`.)
|
|
609
|
+
* Axes a loaded envelope can be judged on alone. `kernel-drift` is excluded:
|
|
610
|
+
* it only warns, and this pass fails closed on any message.
|
|
897
611
|
*/
|
|
898
612
|
const LOADED_ENVELOPE_AXES = [
|
|
899
613
|
'scoring-semantics-drift',
|
|
@@ -903,21 +617,11 @@ const LOADED_ENVELOPE_AXES = [
|
|
|
903
617
|
];
|
|
904
618
|
|
|
905
619
|
/**
|
|
906
|
-
* Kind-module hook
|
|
907
|
-
*
|
|
908
|
-
* `check-baselines` gate calls it straight after `reader.load` and turns a
|
|
909
|
-
* message into a fail-closed schema-class error, so a baseline written by
|
|
910
|
-
* incompatible scoring semantics — or by a different transpiler, which moves
|
|
911
|
-
* the coordinates that are half the row identity key — can never be silently
|
|
912
|
-
* compared against current scores.
|
|
913
|
-
*
|
|
914
|
-
* This is the *production* door for `ts-transpiler-drift`. Before #4866 the
|
|
915
|
-
* axis was reachable only from its own unit test: nothing in production called
|
|
916
|
-
* `evaluateBaselineCompatibility`, and this function deliberately excluded it.
|
|
620
|
+
* Kind-module hook: `check-baselines` calls it after `reader.load` and fails
|
|
621
|
+
* closed on a message, so an incompatible baseline is never silently compared.
|
|
917
622
|
*
|
|
918
623
|
* @param {object|null} baseline A loaded v2 baseline envelope.
|
|
919
|
-
* @param {{runningTsTranspilerVersion?: string}} [ctx]
|
|
920
|
-
* versions; resolved from the environment when omitted.
|
|
624
|
+
* @param {{runningTsTranspilerVersion?: string}} [ctx]
|
|
921
625
|
* @returns {string|null} Operator-facing message, or null when compatible.
|
|
922
626
|
*/
|
|
923
627
|
export function assertBaselineCompatible(baseline, ctx = {}) {
|
|
@@ -933,13 +637,8 @@ export function assertBaselineCompatible(baseline, ctx = {}) {
|
|
|
933
637
|
}
|
|
934
638
|
|
|
935
639
|
/**
|
|
936
|
-
* Build the
|
|
937
|
-
*
|
|
938
|
-
* Violations carry the same fields the stdout printer emits plus a
|
|
939
|
-
* deterministic `fixGuidance` block derived from the formula: target is
|
|
940
|
-
* the baseline for regressions and the ceiling for new-method
|
|
941
|
-
* violations. Rows are deep-cloned so callers can safely mutate the
|
|
942
|
-
* envelope without corrupting the live comparator result.
|
|
640
|
+
* Build the `--json` report. `fixGuidance` targets the baseline for a
|
|
641
|
+
* regression and the ceiling for a new method.
|
|
943
642
|
*/
|
|
944
643
|
export function buildCrapReport({
|
|
945
644
|
compareResult,
|
|
@@ -971,9 +670,7 @@ export function buildCrapReport({
|
|
|
971
670
|
fixGuidance,
|
|
972
671
|
};
|
|
973
672
|
});
|
|
974
|
-
//
|
|
975
|
-
// downstream tooling can detect whether the diff was scoped or
|
|
976
|
-
// full-repo before merging this envelope with the peer MI envelope.
|
|
673
|
+
// Consumers merging with the peer MI envelope need to know the scope.
|
|
977
674
|
const scope = scopeInfo?.scope === 'full' ? 'full' : 'diff';
|
|
978
675
|
const diffRef = scope === 'full' ? null : (scopeInfo?.diffRef ?? null);
|
|
979
676
|
return {
|
|
@@ -984,16 +681,9 @@ export function buildCrapReport({
|
|
|
984
681
|
regressions: compareResult.regressions,
|
|
985
682
|
newViolations: compareResult.newViolations,
|
|
986
683
|
drifted: compareResult.drifted,
|
|
987
|
-
// Story #4866: rows the compare refused to resolve because their
|
|
988
|
-
// coordinate provenance differs from the baseline's.
|
|
989
684
|
incomparable: compareResult.incomparable ?? 0,
|
|
990
|
-
// Story #4871: rows whose baseline candidates included at least one in a
|
|
991
|
-
// different coordinate system — the evidence the unsound-basis backstop
|
|
992
|
-
// reads, captured before the provenance filter discards it.
|
|
993
685
|
provenanceMismatched: compareResult.provenanceMismatched ?? 0,
|
|
994
|
-
//
|
|
995
|
-
// found no coverage artifact for them. Reported, never scored from an
|
|
996
|
-
// assumed zero, and never part of a ratio's denominator.
|
|
686
|
+
// Never scored from an assumed zero coverage.
|
|
997
687
|
unscorable: (compareResult.unscorable ?? 0) + skippedNoCoverage,
|
|
998
688
|
removed: compareResult.removed,
|
|
999
689
|
skippedNoCoverage,
|
|
@@ -1005,14 +695,8 @@ export function buildCrapReport({
|
|
|
1005
695
|
}
|
|
1006
696
|
|
|
1007
697
|
/**
|
|
1008
|
-
*
|
|
1009
|
-
*
|
|
1010
|
-
*
|
|
1011
|
-
* Used by the preview gate on the two conditions under which a per-method
|
|
1012
|
-
* verdict cannot mean anything: a baseline the running scorer refuses to
|
|
1013
|
-
* compare, and a comparison basis whose drifted-row ratio proves the two
|
|
1014
|
-
* sides disagree on coordinates. The counts stay so the operator can see the
|
|
1015
|
-
* evidence; only the accusations go.
|
|
698
|
+
* Replace per-method verdicts with one diagnostic, keeping the counts as
|
|
699
|
+
* evidence. Used when the baseline is incompatible or the basis unsound.
|
|
1016
700
|
*
|
|
1017
701
|
* @param {object} envelope
|
|
1018
702
|
* @param {{name: string, message: string}} diagnostic
|
|
@@ -1031,11 +715,6 @@ export function suppressVerdicts(envelope, diagnostic) {
|
|
|
1031
715
|
};
|
|
1032
716
|
}
|
|
1033
717
|
|
|
1034
|
-
/**
|
|
1035
|
-
* Logger-only printers hoisted from `check-crap.js`. Kept here so the
|
|
1036
|
-
* CLI shell stays thin and the printers can be exercised in unit tests
|
|
1037
|
-
* without spawning the CLI.
|
|
1038
|
-
*/
|
|
1039
718
|
export function printSummaryHeader(result, scanSummary) {
|
|
1040
719
|
Logger.info('\n--- CRAP Report ---');
|
|
1041
720
|
Logger.info(`Total methods scanned: ${result.total}`);
|