mandrel 2.60.0 → 2.62.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/README.md +10 -10
- package/.agents/agents/story-worker.md +1 -1
- package/.agents/docs/agentrc-reference.json +4 -82
- package/.agents/docs/configuration.md +20 -87
- package/.agents/docs/workflows.md +1 -1
- package/.agents/instructions.md +1 -3
- package/.agents/rules/gherkin-standards.md +4 -0
- package/.agents/schemas/agentrc.schema.json +11 -486
- package/.agents/schemas/story-deliver-terminal.schema.json +10 -0
- package/.agents/schemas/validation-evidence.schema.json +2 -1
- package/.agents/scripts/README.md +14 -14
- package/.agents/scripts/acceptance-eval.js +32 -164
- package/.agents/scripts/agents-bootstrap-github.js +27 -129
- package/.agents/scripts/apply-quality-bootstrap.js +4 -40
- package/.agents/scripts/audit-baselines.js +6 -27
- package/.agents/scripts/audit-labels-bootstrap.js +5 -29
- package/.agents/scripts/audit-to-stories.js +91 -361
- package/.agents/scripts/boot-sweep.js +19 -72
- package/.agents/scripts/bootstrap.js +74 -395
- package/.agents/scripts/ceremony-derive.js +9 -45
- package/.agents/scripts/check-arch-cycles.js +14 -64
- package/.agents/scripts/check-baselines.js +8 -48
- package/.agents/scripts/check-context-budget.js +46 -172
- package/.agents/scripts/check-cyclomatic.js +12 -44
- package/.agents/scripts/check-dead-exports.js +13 -64
- package/.agents/scripts/check-doc-links.js +38 -186
- package/.agents/scripts/check-gherkin-corpus.js +24 -127
- package/.agents/scripts/check-test-temp-hygiene.js +28 -169
- package/.agents/scripts/coverage-capture.js +32 -99
- package/.agents/scripts/deliver-light.js +14 -101
- package/.agents/scripts/deliver-recover.js +6 -42
- package/.agents/scripts/deliver-run.js +36 -133
- package/.agents/scripts/diagnose-friction.js +24 -116
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +23 -85
- package/.agents/scripts/file-ci-gap.js +10 -50
- package/.agents/scripts/generate-config-docs.js +30 -170
- package/.agents/scripts/generate-lens-checklists.js +8 -52
- package/.agents/scripts/generate-skills-index.js +14 -112
- package/.agents/scripts/generate-workflows-doc.js +10 -70
- package/.agents/scripts/git-cleanup.js +2 -34
- package/.agents/scripts/lib/Graph.js +24 -81
- package/.agents/scripts/lib/ITicketingProvider.js +47 -143
- package/.agents/scripts/lib/Logger.js +14 -76
- package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
- package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
- package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
- package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
- package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
- package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
- package/.agents/scripts/lib/audit-baselines/read.js +3 -16
- package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
- package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
- package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
- package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
- package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
- package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
- package/.agents/scripts/lib/audit-suite/findings.js +12 -52
- package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
- package/.agents/scripts/lib/audit-suite/index.js +1 -15
- package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
- package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
- package/.agents/scripts/lib/audit-suite/runner.js +13 -43
- package/.agents/scripts/lib/audit-suite/selector.js +49 -349
- package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
- package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
- package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
- package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
- package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
- package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
- package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
- package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
- package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
- package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
- package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
- package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
- package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
- package/.agents/scripts/lib/baseline-loader.js +12 -51
- package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
- package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
- package/.agents/scripts/lib/baselines/components.js +10 -61
- package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
- package/.agents/scripts/lib/baselines/crap-preview-incremental.js +5 -21
- package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
- package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
- package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
- package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
- package/.agents/scripts/lib/baselines/envelope.js +13 -129
- package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
- package/.agents/scripts/lib/baselines/git-base.js +23 -142
- package/.agents/scripts/lib/baselines/kernel.js +11 -111
- package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
- package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
- package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
- package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
- package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
- package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
- package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
- package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
- package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
- package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
- package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
- package/.agents/scripts/lib/baselines/path-canon.js +19 -128
- package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
- package/.agents/scripts/lib/baselines/reader.js +14 -107
- package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
- package/.agents/scripts/lib/baselines/scope.js +11 -135
- package/.agents/scripts/lib/baselines/writer.js +16 -149
- package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
- package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
- package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
- package/.agents/scripts/lib/bdd-step-index.js +26 -100
- package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
- package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
- package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
- package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
- package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
- package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
- package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
- package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
- package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
- package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
- package/.agents/scripts/lib/bootstrap/summary.js +1 -8
- package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
- package/.agents/scripts/lib/branch-name-guard.js +4 -23
- package/.agents/scripts/lib/changed-files.js +31 -143
- package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
- package/.agents/scripts/lib/checks/index.js +18 -101
- package/.agents/scripts/lib/checks/loop-health.js +11 -53
- package/.agents/scripts/lib/checks/state.js +16 -91
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
- package/.agents/scripts/lib/child-exec.js +39 -108
- package/.agents/scripts/lib/cli/standard-args.js +9 -116
- package/.agents/scripts/lib/cli-args.js +31 -146
- package/.agents/scripts/lib/cli-usage.js +5 -27
- package/.agents/scripts/lib/cli-utils.js +2 -12
- package/.agents/scripts/lib/close-validation/commands.js +13 -76
- package/.agents/scripts/lib/close-validation/gates.js +92 -331
- package/.agents/scripts/lib/close-validation/process.js +121 -151
- package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
- package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
- package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
- package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
- package/.agents/scripts/lib/close-validation/runner.js +53 -110
- package/.agents/scripts/lib/command-header.js +6 -28
- package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
- package/.agents/scripts/lib/config/baselines.js +3 -14
- package/.agents/scripts/lib/config/ci.js +8 -38
- package/.agents/scripts/lib/config/commands.js +1 -15
- package/.agents/scripts/lib/config/defaults.js +4 -33
- package/.agents/scripts/lib/config/delivery-routing.js +6 -35
- package/.agents/scripts/lib/config/explain.js +9 -80
- package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +2 -30
- package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
- package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
- package/.agents/scripts/lib/config/gates/index.js +2 -17
- package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
- package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
- package/.agents/scripts/lib/config/gates/shared.js +4 -64
- package/.agents/scripts/lib/config/github.js +4 -22
- package/.agents/scripts/lib/config/limits.js +4 -57
- package/.agents/scripts/lib/config/paths.js +2 -21
- package/.agents/scripts/lib/config/qa.js +4 -38
- package/.agents/scripts/lib/config/quality.js +76 -432
- package/.agents/scripts/lib/config/runners.js +12 -56
- package/.agents/scripts/lib/config/runtime.js +13 -57
- package/.agents/scripts/lib/config/shared.js +2 -16
- package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
- package/.agents/scripts/lib/config/temp-paths.js +40 -280
- package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
- package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
- package/.agents/scripts/lib/config-resolver.js +10 -52
- package/.agents/scripts/lib/config-schema-shared.js +1 -4
- package/.agents/scripts/lib/config-settings-schema-delivery.js +12 -294
- package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
- package/.agents/scripts/lib/config-settings-schema.js +37 -274
- package/.agents/scripts/lib/coverage-baseline.js +20 -110
- package/.agents/scripts/lib/coverage-capture-fullscope.js +12 -37
- package/.agents/scripts/lib/coverage-capture-incremental.js +12 -43
- package/.agents/scripts/lib/coverage-capture-usage.js +4 -24
- package/.agents/scripts/lib/coverage-capture.js +99 -224
- package/.agents/scripts/lib/coverage-utils.js +14 -79
- package/.agents/scripts/lib/cpu-pool.js +17 -123
- package/.agents/scripts/lib/crap-baseline-join.js +16 -88
- package/.agents/scripts/lib/crap-coordinates.js +6 -25
- package/.agents/scripts/lib/crap-engine.js +40 -153
- package/.agents/scripts/lib/crap-method-identity.js +16 -78
- package/.agents/scripts/lib/crap-utils.js +31 -155
- package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
- package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
- package/.agents/scripts/lib/dead-exports-knip.js +18 -56
- package/.agents/scripts/lib/dead-exports-mode.js +5 -24
- package/.agents/scripts/lib/degraded-mode.js +3 -26
- package/.agents/scripts/lib/dependency-parser.js +8 -40
- package/.agents/scripts/lib/dependency-version.js +13 -35
- package/.agents/scripts/lib/detect-package-manager.js +6 -36
- package/.agents/scripts/lib/doc-tiers.js +22 -126
- package/.agents/scripts/lib/duplicate-search.js +8 -72
- package/.agents/scripts/lib/env-loader.js +5 -27
- package/.agents/scripts/lib/error-redactor.js +6 -31
- package/.agents/scripts/lib/errors/index.js +2 -22
- package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
- package/.agents/scripts/lib/escomplex-kernel.js +21 -123
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +93 -419
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -151
- package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
- package/.agents/scripts/lib/findings/classify-finding.js +14 -69
- package/.agents/scripts/lib/findings/promote-finding.js +14 -112
- package/.agents/scripts/lib/findings/provenance-field.js +11 -52
- package/.agents/scripts/lib/findings/route-finding.js +37 -255
- package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
- package/.agents/scripts/lib/findings/severity.js +18 -104
- package/.agents/scripts/lib/format-generated-json.js +12 -44
- package/.agents/scripts/lib/full-suite-lock.js +160 -429
- package/.agents/scripts/lib/full-suite-queue.js +213 -0
- package/.agents/scripts/lib/gates/baseline-store.js +5 -9
- package/.agents/scripts/lib/gates/friction.js +1 -3
- package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
- package/.agents/scripts/lib/gh-exec.js +31 -259
- package/.agents/scripts/lib/git/cached-fetch.js +9 -52
- package/.agents/scripts/lib/git/sync-from-base.js +15 -107
- package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
- package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
- package/.agents/scripts/lib/git-utils.js +37 -161
- package/.agents/scripts/lib/github/framework-repo.js +8 -71
- package/.agents/scripts/lib/github-url.js +2 -17
- package/.agents/scripts/lib/import-graph.js +11 -38
- package/.agents/scripts/lib/install-cmd-parser.js +4 -13
- package/.agents/scripts/lib/json-utils.js +3 -18
- package/.agents/scripts/lib/label-constants.js +16 -111
- package/.agents/scripts/lib/label-taxonomy.js +4 -30
- package/.agents/scripts/lib/maintainability-engine.js +12 -80
- package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
- package/.agents/scripts/lib/maintainability-utils.js +16 -92
- package/.agents/scripts/lib/mandrel-catalog.js +12 -70
- package/.agents/scripts/lib/notifications/notifier.js +13 -38
- package/.agents/scripts/lib/npm-scripts.js +4 -23
- package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
- package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
- package/.agents/scripts/lib/observability/signal-validator.js +5 -37
- package/.agents/scripts/lib/observability/signals-writer.js +11 -121
- package/.agents/scripts/lib/observability/source-classifier.js +21 -203
- package/.agents/scripts/lib/observability/terse-result.js +14 -47
- package/.agents/scripts/lib/onboard/init-tail.js +13 -74
- package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
- package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
- package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +5 -75
- package/.agents/scripts/lib/orchestration/change-set.js +7 -36
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
- package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
- package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
- package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
- package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
- package/.agents/scripts/lib/orchestration/check-state.js +92 -0
- package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +42 -189
- package/.agents/scripts/lib/orchestration/code-review.js +24 -128
- package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
- package/.agents/scripts/lib/orchestration/complexity-gate.js +42 -214
- package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
- package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
- package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
- package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
- package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
- package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
- package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
- package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
- package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
- package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
- package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
- package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
- package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
- package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
- package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
- package/.agents/scripts/lib/orchestration/light-suitability.js +26 -231
- package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
- package/.agents/scripts/lib/orchestration/merge-queue.js +158 -0
- package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
- package/.agents/scripts/lib/orchestration/plan-context.js +52 -303
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
- package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
- package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
- package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
- package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
- package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +14 -78
- package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
- package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
- package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
- package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +49 -248
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
- package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
- package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
- package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
- package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
- package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
- package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
- package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
- package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
- package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
- package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
- package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
- package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
- package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
- package/.agents/scripts/lib/orchestration/review-depth.js +12 -94
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
- package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
- package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
- package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
- package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
- package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
- package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
- package/.agents/scripts/lib/orchestration/run-epilogue.js +40 -199
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
- package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
- package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
- package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +190 -280
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +18 -80
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +183 -485
- package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
- package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +9 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +110 -290
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
- package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
- package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
- package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
- package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -201
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
- package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
- package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
- package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
- package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -126
- package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
- package/.agents/scripts/lib/orchestration/ticket-validator.js +39 -181
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
- package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
- package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
- package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
- package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
- package/.agents/scripts/lib/path-security.js +3 -6
- package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
- package/.agents/scripts/lib/preflight-runner.js +13 -69
- package/.agents/scripts/lib/process-group.js +143 -0
- package/.agents/scripts/lib/project-root.js +2 -8
- package/.agents/scripts/lib/provider-factory.js +2 -25
- package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
- package/.agents/scripts/lib/qa/qa-session.js +15 -69
- package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
- package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
- package/.agents/scripts/lib/reserved-test-ids.js +9 -47
- package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
- package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
- package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
- package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
- package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
- package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
- package/.agents/scripts/lib/signals/detectors/common.js +12 -38
- package/.agents/scripts/lib/signals/index.js +2 -19
- package/.agents/scripts/lib/signals/schema.js +14 -109
- package/.agents/scripts/lib/signals/write.js +2 -11
- package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
- package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
- package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
- package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
- package/.agents/scripts/lib/single-story-sweep.js +14 -97
- package/.agents/scripts/lib/skills/parse-skill.js +13 -59
- package/.agents/scripts/lib/skills/skills-index.js +8 -29
- package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
- package/.agents/scripts/lib/source-extensions.js +11 -42
- package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
- package/.agents/scripts/lib/stdio-flush.js +9 -36
- package/.agents/scripts/lib/story-adjacency.js +8 -40
- package/.agents/scripts/lib/story-body/body-format-lints.js +22 -83
- package/.agents/scripts/lib/story-body/footer-block.js +11 -44
- package/.agents/scripts/lib/story-body/story-body.js +83 -358
- package/.agents/scripts/lib/temp-retention.js +42 -143
- package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
- package/.agents/scripts/lib/test-env.js +12 -65
- package/.agents/scripts/lib/test-run-credit.js +10 -65
- package/.agents/scripts/lib/test-runner-contract.js +19 -74
- package/.agents/scripts/lib/test-temp.js +38 -184
- package/.agents/scripts/lib/test-tiers.js +12 -96
- package/.agents/scripts/lib/ticket-body-sections.js +21 -96
- package/.agents/scripts/lib/transpile.js +15 -74
- package/.agents/scripts/lib/util/concurrent-map.js +6 -25
- package/.agents/scripts/lib/util/parse-id-list.js +8 -34
- package/.agents/scripts/lib/util/poll-loop.js +8 -28
- package/.agents/scripts/lib/util/with-timeout.js +2 -11
- package/.agents/scripts/lib/validation-evidence.js +21 -96
- package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
- package/.agents/scripts/lib/wave-runner/live-probe.js +53 -221
- package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
- package/.agents/scripts/lib/workers/crap-worker.js +11 -64
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
- package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
- package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
- package/.agents/scripts/lib/workflow-closure.js +22 -105
- package/.agents/scripts/lib/workspace-provisioner.js +16 -54
- package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
- package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
- package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
- package/.agents/scripts/lib/worktree-manager.js +15 -40
- package/.agents/scripts/lint-issue-body.js +12 -68
- package/.agents/scripts/mandrel-update-preflight.js +10 -70
- package/.agents/scripts/merge-baseline.js +30 -104
- package/.agents/scripts/nav-registry-diff.js +22 -108
- package/.agents/scripts/notify.js +12 -69
- package/.agents/scripts/plan-context.js +27 -111
- package/.agents/scripts/plan-critics.js +12 -66
- package/.agents/scripts/plan-persist.js +31 -148
- package/.agents/scripts/plan-run-epilogue.js +11 -37
- package/.agents/scripts/pr-watch-with-update.js +76 -267
- package/.agents/scripts/providers/github/auth.js +3 -8
- package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
- package/.agents/scripts/providers/github/board-add.js +5 -21
- package/.agents/scripts/providers/github/branch-protection.js +11 -43
- package/.agents/scripts/providers/github/cache.js +2 -14
- package/.agents/scripts/providers/github/comments.js +7 -40
- package/.agents/scripts/providers/github/compose.js +3 -19
- package/.agents/scripts/providers/github/errors.js +22 -125
- package/.agents/scripts/providers/github/issues.js +31 -123
- package/.agents/scripts/providers/github/labels.js +24 -124
- package/.agents/scripts/providers/github/mappers.js +5 -27
- package/.agents/scripts/providers/github/merge-methods.js +3 -22
- package/.agents/scripts/providers/github/project-board.js +2 -17
- package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
- package/.agents/scripts/providers/github/request-helpers.js +5 -32
- package/.agents/scripts/providers/github/search-budget.js +9 -39
- package/.agents/scripts/providers/github/search-query.js +5 -26
- package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
- package/.agents/scripts/providers/github/sub-issues.js +7 -36
- package/.agents/scripts/providers/github/tickets.js +32 -134
- package/.agents/scripts/providers/github.js +18 -59
- package/.agents/scripts/prune-plan-run-labels.js +12 -46
- package/.agents/scripts/quality-preview.js +35 -220
- package/.agents/scripts/resolve-doc-tiers.js +3 -26
- package/.agents/scripts/resolve-stories.js +16 -67
- package/.agents/scripts/resync-status-column.js +6 -25
- package/.agents/scripts/run-tests.js +29 -104
- package/.agents/scripts/single-story-close.js +23 -135
- package/.agents/scripts/single-story-confirm-merge.js +32 -139
- package/.agents/scripts/single-story-init.js +47 -209
- package/.agents/scripts/stories-wave-tick.js +102 -472
- package/.agents/scripts/sync-agentrc.js +3 -21
- package/.agents/scripts/sync-claude-agents.js +9 -55
- package/.agents/scripts/sync-claude-commands.js +20 -110
- package/.agents/scripts/test-wrapper.js +6 -43
- package/.agents/scripts/update-coverage-baseline.js +5 -22
- package/.agents/scripts/update-crap-baseline.js +7 -30
- package/.agents/scripts/update-duplication-baseline.js +16 -92
- package/.agents/scripts/update-maintainability-baseline.js +8 -62
- package/.agents/scripts/update-ticket-state.js +1 -7
- package/.agents/scripts/validate-skills.js +6 -26
- package/.agents/templates/agent-protocol.md +2 -2
- package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
- package/.agents/workflows/audit-accessibility.md +4 -7
- package/.agents/workflows/audit-adrs.md +3 -6
- package/.agents/workflows/audit-architecture.md +3 -11
- package/.agents/workflows/audit-baselines.md +6 -9
- package/.agents/workflows/audit-clean-code.md +8 -12
- package/.agents/workflows/audit-data-model.md +3 -7
- package/.agents/workflows/audit-dependencies.md +4 -7
- package/.agents/workflows/audit-devops.md +4 -8
- package/.agents/workflows/audit-documentation.md +1 -4
- package/.agents/workflows/audit-mobile.md +4 -7
- package/.agents/workflows/audit-navigability.md +3 -6
- package/.agents/workflows/audit-performance.md +2 -4
- package/.agents/workflows/audit-privacy.md +4 -7
- package/.agents/workflows/audit-quality.md +4 -7
- package/.agents/workflows/audit-security.md +4 -7
- package/.agents/workflows/audit-seo.md +4 -7
- package/.agents/workflows/audit-sre.md +4 -7
- package/.agents/workflows/audit-to-stories.md +17 -30
- package/.agents/workflows/audit-ux-ui.md +4 -7
- package/.agents/workflows/helpers/audit-lens-core.md +1 -1
- package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
- package/.agents/workflows/helpers/deliver-digest.md +6 -4
- package/.agents/workflows/helpers/deliver-reference.md +114 -188
- package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
- package/.agents/workflows/helpers/plan-reference.md +86 -139
- package/.agents/workflows/helpers/qa-core.md +12 -0
- package/.agents/workflows/memory-consolidate.md +1 -1
- package/.agents/workflows/qa-assist.md +27 -71
- package/.agents/workflows/qa-explore.md +19 -59
- package/.agents/workflows/qa-run.md +11 -33
- package/README.md +1 -1
- package/bin/mandrel.js +5 -46
- package/bin/postinstall.js +18 -107
- package/docs/CHANGELOG.md +32 -0
- package/lib/cli/doctor.js +11 -71
- package/lib/cli/init.js +26 -165
- package/lib/cli/migrate.js +5 -64
- package/lib/cli/registry.js +84 -467
- package/lib/cli/sync-agents.js +4 -64
- package/lib/cli/sync-commands.js +11 -64
- package/lib/cli/sync.js +34 -213
- package/lib/cli/uninstall.js +40 -219
- package/lib/cli/update.js +105 -661
- package/lib/cli/version-check.js +8 -72
- package/lib/cli/version-helpers.js +14 -87
- package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
- package/lib/migrations/index.js +15 -92
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
- package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
- package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
- package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
- package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
- package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
- package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
- package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +2 -21
- package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
- package/package.json +16 -14
- package/.agents/docs/SDLC.md +0 -590
- package/.agents/docs/quality-gates.md +0 -1183
- package/.agents/rules/known-tooling-behavior.md +0 -200
- package/.agents/rules/orchestration-error-handling.md +0 -61
- package/.agents/rules/test-seams.md +0 -59
- package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
- package/.agents/schemas/baselines/lint.schema.json +0 -47
- package/.agents/scripts/check-action-pinning.js +0 -260
- package/.agents/scripts/check-audit-attribution.js +0 -302
- package/.agents/scripts/check-baseline-drift.js +0 -211
- package/.agents/scripts/check-baseline-scope.js +0 -362
- package/.agents/scripts/check-generated-validator.js +0 -202
- package/.agents/scripts/check-knip-entries.js +0 -159
- package/.agents/scripts/check-lifecycle-lint.js +0 -294
- package/.agents/scripts/check-pinned-override-notes.js +0 -102
- package/.agents/scripts/check-schema-references.js +0 -368
- package/.agents/scripts/check-test-portability.js +0 -512
- package/.agents/scripts/check-workflow-citations.js +0 -218
- package/.agents/scripts/check-workflow-cli-lint.js +0 -299
- package/.agents/scripts/check-workflow-timeouts.js +0 -291
- package/.agents/scripts/install-matrix-assert.js +0 -326
- package/.agents/scripts/lib/audit-advisories.js +0 -195
- package/.agents/scripts/lib/audit-attribution.js +0 -134
- package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
- package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
- package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
- package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
- package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
- package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
- package/.agents/scripts/lib/c8-cli-path.js +0 -21
- package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
- package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
- package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
- package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
- package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
- package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
- package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
- package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
- package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
- package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
- package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
- package/.agents/scripts/lib/fs-walk.js +0 -52
- package/.agents/scripts/lib/knip-config-resolver.js +0 -181
- package/.agents/scripts/lib/knip-entry-sync.js +0 -452
- package/.agents/scripts/lib/pinned-override-notes.js +0 -88
- package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
- package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
- package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
- package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
- package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
- package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
- package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
- package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
- package/.agents/scripts/lib/test-isolate/runner.js +0 -483
- package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
- package/.agents/scripts/lib/test-profile/render-report.js +0 -45
- package/.agents/scripts/lint-label-vocabulary.js +0 -214
- package/.agents/scripts/post-structured-comment.js +0 -127
- package/.agents/scripts/provision-git-hooks.js +0 -85
- package/.agents/scripts/prune-baseline-orphans.js +0 -181
- package/.agents/scripts/run-coverage.js +0 -197
- package/.agents/scripts/run-lint.js +0 -133
- package/.agents/scripts/run-test-profile.js +0 -129
- package/.agents/scripts/run-verify.js +0 -125
- package/.agents/scripts/test-isolate.js +0 -55
- package/.agents/scripts/update-dead-exports-baseline.js +0 -321
|
@@ -1,70 +1,11 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// `check-baselines.js` dispatcher: `resolveDispatchScope` in
|
|
5
|
-
// `lib/orchestration/check-baselines/phases/compare.js` is its one
|
|
6
|
-
// caller. Routing the read side's scope decision through a single pure
|
|
7
|
-
// function keeps the precedence rules from being re-implemented per gate.
|
|
8
|
-
//
|
|
9
|
-
// It is NOT the writers' resolver. `lib/baselines/refresh-service.js`
|
|
10
|
-
// defines its own private `resolveScope` (Story #3658) over a different
|
|
11
|
-
// input set, and the header here used to claim otherwise — a claim that
|
|
12
|
-
// made the read/write pair look coupled when it is not. Corrected in
|
|
13
|
-
// Story #4922.
|
|
14
|
-
//
|
|
15
|
-
// The resolver is intentionally pure — it takes already-extracted
|
|
16
|
-
// inputs and returns a frozen ScopeResolution. Env reading and config
|
|
17
|
-
// loading happen in the caller; that keeps this module trivially
|
|
18
|
-
// testable.
|
|
19
|
-
//
|
|
20
|
-
// Precedence (highest → lowest):
|
|
21
|
-
//
|
|
22
|
-
// 1. Environment — `BASELINE_SCOPE` ('full' | 'diff') and
|
|
23
|
-
// `BASELINE_REF` (any git ref). The dispatcher reads these from
|
|
24
|
-
// `process.env` and forwards via `envScope` / `envRef` so the
|
|
25
|
-
// resolver itself never touches process state. CI sets these.
|
|
26
|
-
// 2. Config — `configScope` ('full' | 'diff') and `configRef` (any
|
|
27
|
-
// git ref) from `delivery.quality.gateScoping` in `.agentrc.json`.
|
|
28
|
-
// 3. Default — `mode='diff'` against `ref='main'`. This is the
|
|
29
|
-
// framework-wide fallback when nothing else is configured.
|
|
30
|
-
//
|
|
31
|
-
// Story #4922 removed a fourth, highest-precedence layer: a
|
|
32
|
-
// `cliFlags.fullScope` / `cliFlags.changedSinceRef` operator override,
|
|
33
|
-
// plus the `cliFlags.changedFiles` → `files` plumbing that fed it. No
|
|
34
|
-
// production caller ever populated any of the three — only this module's
|
|
35
|
-
// own unit tests did — so the layer's only effect was to advertise a
|
|
36
|
-
// `--full-scope` / `--changed-since` contract that `check-baselines.js`
|
|
37
|
-
// does not implement, and a `files` set that no consumer read. Operators
|
|
38
|
-
// who need full scope set `BASELINE_SCOPE=full`, which is what CI does.
|
|
39
|
-
// (`mergeRowsByScope` below still takes a `files`-bearing scope — that
|
|
40
|
-
// one comes from the refresh service's own resolver, not from here.)
|
|
41
|
-
//
|
|
42
|
-
// Missing-ref fallback: when the resolved mode is `'diff'` but no ref
|
|
43
|
-
// is supplied at any layer, the resolver falls back to `'main'` rather
|
|
44
|
-
// than producing a half-resolved scope with `ref=null`. The dispatcher
|
|
45
|
-
// would have to invent a default anyway; centralising it here keeps
|
|
46
|
-
// every gate aligned.
|
|
47
|
-
//
|
|
48
|
-
// `kind` (e.g. `'lint'`, `'coverage'`, `'crap'`) is currently echoed
|
|
49
|
-
// through to the resolution unchanged. The argument exists so future
|
|
50
|
-
// per-kind overrides (e.g. "lint always runs full") have a place to
|
|
51
|
-
// land without breaking call signatures. Today: pass it; ignore it.
|
|
52
|
-
//
|
|
53
|
-
// Returned shape:
|
|
54
|
-
//
|
|
55
|
-
// {
|
|
56
|
-
// kind: string, // echoed back for caller convenience
|
|
57
|
-
// mode: 'full' | 'diff',
|
|
58
|
-
// ref: string | null, // null in full mode; ref string in diff mode
|
|
59
|
-
// source: string, // which layer won (debug / friction signal)
|
|
60
|
-
// }
|
|
1
|
+
// Read-side scope resolution for the `check-baselines` dispatcher (the
|
|
2
|
+
// refresh service has its own resolver). Pure: the caller extracts
|
|
3
|
+
// `BASELINE_SCOPE` / `BASELINE_REF`; env wins, else diff against `main`.
|
|
61
4
|
|
|
62
5
|
const VALID_MODES = new Set(['full', 'diff']);
|
|
63
6
|
const DEFAULT_DIFF_REF = 'main';
|
|
64
7
|
|
|
65
8
|
/**
|
|
66
|
-
* Coerce a candidate value to a non-empty string, or `null`.
|
|
67
|
-
*
|
|
68
9
|
* @param {unknown} v
|
|
69
10
|
* @returns {string | null}
|
|
70
11
|
*/
|
|
@@ -73,10 +14,7 @@ function asNonEmptyString(v) {
|
|
|
73
14
|
}
|
|
74
15
|
|
|
75
16
|
/**
|
|
76
|
-
*
|
|
77
|
-
* `null` if it is not a recognised mode. Unknown strings are dropped
|
|
78
|
-
* rather than coerced — the layer "did not specify" rather than
|
|
79
|
-
* "specified an invalid value".
|
|
17
|
+
* An unknown string means "unspecified", not invalid.
|
|
80
18
|
*
|
|
81
19
|
* @param {unknown} v
|
|
82
20
|
* @returns {'full' | 'diff' | null}
|
|
@@ -86,13 +24,10 @@ function asMode(v) {
|
|
|
86
24
|
}
|
|
87
25
|
|
|
88
26
|
/**
|
|
89
|
-
*
|
|
90
|
-
* default). Pure; no I/O.
|
|
27
|
+
* `source` names the winning layer; `ref` is null in full mode.
|
|
91
28
|
*
|
|
92
29
|
* @param {object} input
|
|
93
|
-
* @param {string} input.kind -
|
|
94
|
-
* @param {string} [input.configScope] - `'full'` | `'diff'` from agentrc.
|
|
95
|
-
* @param {string} [input.configRef] - Diff ref from agentrc.
|
|
30
|
+
* @param {string} input.kind - Echoed back.
|
|
96
31
|
* @param {string} [input.envScope] - From `BASELINE_SCOPE`.
|
|
97
32
|
* @param {string} [input.envRef] - From `BASELINE_REF`.
|
|
98
33
|
* @returns {{
|
|
@@ -108,7 +43,6 @@ export function resolveScope(input = {}) {
|
|
|
108
43
|
? input.kind
|
|
109
44
|
: 'unknown';
|
|
110
45
|
|
|
111
|
-
// ---- Layer 1: Environment (extracted by the caller) ------------------
|
|
112
46
|
const envMode = asMode(input.envScope);
|
|
113
47
|
if (envMode === 'full') {
|
|
114
48
|
return Object.freeze({
|
|
@@ -128,29 +62,6 @@ export function resolveScope(input = {}) {
|
|
|
128
62
|
});
|
|
129
63
|
}
|
|
130
64
|
|
|
131
|
-
// ---- Layer 2: Config (delivery.quality.gateScoping) ------------------
|
|
132
|
-
const cfgMode = asMode(input.configScope);
|
|
133
|
-
if (cfgMode === 'full') {
|
|
134
|
-
return Object.freeze({
|
|
135
|
-
kind,
|
|
136
|
-
mode: 'full',
|
|
137
|
-
ref: null,
|
|
138
|
-
source: 'config:gateScoping.scope=full',
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
const cfgRef = asNonEmptyString(input.configRef);
|
|
142
|
-
if (cfgMode === 'diff' || cfgRef) {
|
|
143
|
-
return Object.freeze({
|
|
144
|
-
kind,
|
|
145
|
-
mode: 'diff',
|
|
146
|
-
ref: cfgRef ?? DEFAULT_DIFF_REF,
|
|
147
|
-
source: cfgRef
|
|
148
|
-
? 'config:gateScoping.diffRef'
|
|
149
|
-
: 'config:gateScoping.scope=diff',
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// ---- Layer 3: Default ------------------------------------------------
|
|
154
65
|
return Object.freeze({
|
|
155
66
|
kind,
|
|
156
67
|
mode: 'diff',
|
|
@@ -160,44 +71,17 @@ export function resolveScope(input = {}) {
|
|
|
160
71
|
}
|
|
161
72
|
|
|
162
73
|
/**
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* the field used to identify the file the row belongs to (path / route /
|
|
167
|
-
* bundle). This helper does the actual merge:
|
|
168
|
-
*
|
|
169
|
-
* - `scope.mode === 'full'` (or `scope` is null/undefined / `scope.files`
|
|
170
|
-
* is empty): regenerated wins everywhere — returned as-is. This keeps
|
|
171
|
-
* the legacy "always rewrite" behaviour intact when no scope filter is
|
|
172
|
-
* applied.
|
|
173
|
-
* - `scope.mode === 'diff'`: rows whose `scopeKey` value is OUTSIDE
|
|
174
|
-
* `scope.files` are preserved from `prior` verbatim. Rows whose
|
|
175
|
-
* `scopeKey` value is INSIDE `scope.files` are taken from
|
|
176
|
-
* `regenerated` (the regenerated values for in-scope files). Prior
|
|
177
|
-
* rows for in-scope files are dropped (regen replaces them); regen
|
|
178
|
-
* rows for out-of-scope files are dropped (the writer should not have
|
|
179
|
-
* computed them, but we filter defensively).
|
|
180
|
-
* - Missing `prior` (null / undefined / empty) — regenerated wins
|
|
181
|
-
* everywhere; behaves like full mode.
|
|
182
|
-
*
|
|
183
|
-
* Identity matching uses the per-kind `identity(row)` function — for
|
|
184
|
-
* coverage / lint / maintainability / mutation / lighthouse / bundle-size
|
|
185
|
-
* the identity is the keyField value; for crap it's a composite
|
|
186
|
-
* `path::method@startLine`. The merge preserves row ordering by
|
|
187
|
-
* concatenating in-scope regen rows then out-of-scope prior rows; the
|
|
188
|
-
* downstream `sortRows` from the per-kind module re-sorts before write.
|
|
189
|
-
*
|
|
190
|
-
* Pure. No I/O.
|
|
74
|
+
* Scope-aware row merge. Full mode, no scope, or no prior: regenerated wins.
|
|
75
|
+
* Diff mode: in-scope rows come from `regenerated`, out-of-scope rows from
|
|
76
|
+
* `prior` verbatim (regen rows outside scope are dropped). Output is unsorted.
|
|
191
77
|
*
|
|
192
78
|
* @template TRow
|
|
193
79
|
* @param {object} args
|
|
194
80
|
* @param {Array<TRow>|null|undefined} args.prior
|
|
195
81
|
* @param {Array<TRow>|null|undefined} args.regenerated
|
|
196
82
|
* @param {{mode?: 'full'|'diff', files?: Set<string>|Iterable<string>}|null|undefined} args.scope
|
|
197
|
-
* @param {(row: TRow) => string} args.scopeKey
|
|
198
|
-
*
|
|
199
|
-
* @param {(row: TRow) => string} [args.identity] Per-kind identity extractor — defaults to
|
|
200
|
-
* the same as `scopeKey`. CRAP overrides this with `path::method@startLine`.
|
|
83
|
+
* @param {(row: TRow) => string} args.scopeKey The file key matched against `scope.files`.
|
|
84
|
+
* @param {(row: TRow) => string} [args.identity] Defaults to `scopeKey`.
|
|
201
85
|
* @returns {Array<TRow>}
|
|
202
86
|
*/
|
|
203
87
|
export function mergeRowsByScope({
|
|
@@ -214,23 +98,15 @@ export function mergeRowsByScope({
|
|
|
214
98
|
}
|
|
215
99
|
const idFn = typeof identity === 'function' ? identity : scopeKey;
|
|
216
100
|
|
|
217
|
-
// No scope filter / full mode / no prior → regen wins everywhere.
|
|
218
101
|
const mode = scope?.mode;
|
|
219
102
|
if (!scope || mode === 'full' || priorRows.length === 0) {
|
|
220
103
|
return regenRows.slice();
|
|
221
104
|
}
|
|
222
105
|
|
|
223
|
-
// Coerce scope.files to a Set for O(1) membership tests. An empty Set in
|
|
224
|
-
// diff mode means "no files in scope" — every prior row is preserved
|
|
225
|
-
// and every regen row is dropped (defensive: writer feeds in-scope rows).
|
|
226
106
|
const filesSet =
|
|
227
107
|
scope.files instanceof Set ? scope.files : new Set(scope.files ?? []);
|
|
228
108
|
|
|
229
|
-
// In-scope regen rows: keep regen.
|
|
230
109
|
const regenInScope = regenRows.filter((row) => filesSet.has(scopeKey(row)));
|
|
231
|
-
// Out-of-scope prior rows: keep prior, but drop any whose identity
|
|
232
|
-
// collides with an in-scope regen row (defensive — should not happen
|
|
233
|
-
// since identity within a kind is keyField-derived).
|
|
234
110
|
const inScopeIds = new Set(regenInScope.map((row) => idFn(row)));
|
|
235
111
|
const priorOutOfScope = priorRows.filter(
|
|
236
112
|
(row) => !filesSet.has(scopeKey(row)) && !inScopeIds.has(idFn(row)),
|
|
@@ -1,41 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* `update-maintainability-baseline.js`, `lib/coverage-baseline.js`,
|
|
6
|
-
* the auto-refresh evaluator, now inside `auto-refresh-runner.js`) used to assemble its own envelope and
|
|
7
|
-
* call `fs.writeFileSync`. That meant the path canonicalisation, rollup
|
|
8
|
-
* math, kernel-version stamping, and JSON-serialisation conventions were
|
|
9
|
-
* duplicated five-ish times, each with subtly different rules. The
|
|
10
|
-
* worktree-prefix bug that prompted Story #1891 is the proof: each
|
|
11
|
-
* refresh path had to remember to strip `.worktrees/<workspace>/` on its
|
|
12
|
-
* own, and the maintainability path forgot.
|
|
13
|
-
*
|
|
14
|
-
* `write({ kind, rows, components, kernelVersion?, generatedAt? })` is
|
|
15
|
-
* the single funnel:
|
|
16
|
-
*
|
|
17
|
-
* 1. Look up the per-kind module via the kernel registry. The module
|
|
18
|
-
* declares the `keyField`, `projectRow`, `sortRows`, `rollup`, and
|
|
19
|
-
* `kernelVersion()` functions.
|
|
20
|
-
* 2. Run every row through `projectRow` — that's where the path is
|
|
21
|
-
* canonicalised via `path-canon.canonicalise()`. After projection,
|
|
22
|
-
* the writer asserts every key field is already canonical
|
|
23
|
-
* (`path-canon.assertCanonical()`), refusing to silently rewrite
|
|
24
|
-
* identity.
|
|
25
|
-
* 3. Sort the rows for deterministic on-disk diffs.
|
|
26
|
-
* 4. Compute the per-component rollup (always including `*`).
|
|
27
|
-
* 5. Stamp the envelope via `buildEnvelope` — `$schema`, `kernelVersion`,
|
|
28
|
-
* `generatedAt`.
|
|
29
|
-
* 6. Validate the envelope via `assertEnvelope` (AJV against the per-kind
|
|
30
|
-
* schema).
|
|
31
|
-
* 7. Return the envelope object. Callers serialise via `writeFile()`
|
|
32
|
-
* (separate seam so tests can round-trip without touching disk).
|
|
33
|
-
*
|
|
34
|
-
* `writeFile(absPath, envelope)` is the serialise + flush seam. It
|
|
35
|
-
* stringifies the envelope with two-space indent, appends a trailing
|
|
36
|
-
* newline, creates the parent directory, and writes atomically (write to
|
|
37
|
-
* `<path>.tmp` then `rename` — `rename` is atomic on every platform we
|
|
38
|
-
* support).
|
|
2
|
+
* Shared baseline writer, the single funnel for envelope assembly
|
|
3
|
+
* (`write`: project, canonical-assert, merge, stabilise, sort, rollup, stamp,
|
|
4
|
+
* validate) and serialisation (`writeFile`: atomic tmp + rename).
|
|
39
5
|
*
|
|
40
6
|
* @module lib/baselines/writer
|
|
41
7
|
*/
|
|
@@ -48,42 +14,11 @@ import { currentKernelVersion, getKindModule } from './kernel.js';
|
|
|
48
14
|
import { assertCanonical } from './path-canon.js';
|
|
49
15
|
|
|
50
16
|
/**
|
|
51
|
-
* Assemble
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* `epsilon` parameters. When both are present, the writer calls the
|
|
57
|
-
* per-kind `applyEpsilon(prior, regenerated, epsilon)` stabilizer
|
|
58
|
-
* **after** projection but **before** sort/rollup/serialise. Sub-epsilon
|
|
59
|
-
* row deltas resolve to the prior bytes, so env variance never rewrites
|
|
60
|
-
* the on-disk envelope. When either is absent (`undefined`), behaviour is
|
|
61
|
-
* unchanged from the pre-#1964 contract — this is regression-fail-safe by
|
|
62
|
-
* design so existing call sites stay untouched.
|
|
63
|
-
*
|
|
64
|
-
* Story #1974 (s-diff-scoped-writes) added the optional `scope` parameter.
|
|
65
|
-
* When `scope` is present *and* `prior` is supplied, the writer calls the
|
|
66
|
-
* per-kind `mergeRows(prior, projected, scope)` filter **after** projection
|
|
67
|
-
* but **before** `applyEpsilon`. The composition is intentional: scope-
|
|
68
|
-
* filter first (preserve out-of-scope prior rows verbatim), then stabilise
|
|
69
|
-
* the in-scope rows against the same prior under epsilon. The merged result
|
|
70
|
-
* is sorted, rolled up, and serialised exactly as before. When `scope` is
|
|
71
|
-
* absent (or `prior` is absent), behaviour is unchanged from the pre-#1974
|
|
72
|
-
* contract — also regression-fail-safe.
|
|
73
|
-
*
|
|
74
|
-
* `prior` MUST be an array of rows already in canonical (per-kind
|
|
75
|
-
* `projectRow`) shape — the on-disk baseline format is canonical
|
|
76
|
-
* end-to-end, and the writer no longer re-projects prior rows on entry.
|
|
77
|
-
*
|
|
78
|
-
* Story #2135 (Task #2146) added the structural-equality short-circuit on
|
|
79
|
-
* top of `prior`. When a `prior` envelope (or `priorEnvelope`) is supplied
|
|
80
|
-
* and the projected `rows + rollup` deep-equal the prior's `rows + rollup`,
|
|
81
|
-
* the writer returns the prior envelope unchanged — same `generatedAt`,
|
|
82
|
-
* same kernelVersion, same byte payload. Without this guard every
|
|
83
|
-
* auto-refresh that ran on a no-op Story would stamp a fresh
|
|
84
|
-
* `generatedAt` and surface a spurious one-line diff. The short-circuit
|
|
85
|
-
* is the semantic replacement for the legacy byte-equality compare that
|
|
86
|
-
* lived in `baseline-snapshot.js`.
|
|
17
|
+
* Assemble and validate an envelope (no I/O). With `scope`, out-of-scope
|
|
18
|
+
* `prior` rows are preserved first; with `epsilon`, sub-epsilon deltas then
|
|
19
|
+
* resolve to prior bytes. `prior` rows must already be canonical. When rows
|
|
20
|
+
* and rollup deep-equal the prior envelope, the prior is returned unchanged
|
|
21
|
+
* so a no-op refresh leaves no `generatedAt` diff.
|
|
87
22
|
*
|
|
88
23
|
* @param {{
|
|
89
24
|
* kind: string,
|
|
@@ -127,11 +62,7 @@ export function write({
|
|
|
127
62
|
}
|
|
128
63
|
});
|
|
129
64
|
|
|
130
|
-
//
|
|
131
|
-
// The per-kind `projectRow` already funnels paths through `canonicalise`,
|
|
132
|
-
// but the assertion catches a future per-kind module that forgets — and
|
|
133
|
-
// catches absolute paths in inputs that the canonicaliser would also
|
|
134
|
-
// throw on (we surface a writer-scoped error pointing at the row).
|
|
65
|
+
// Catches a kind module whose `projectRow` forgets to canonicalise.
|
|
135
66
|
if (mod.keyField === 'path') {
|
|
136
67
|
projected.forEach((row, idx) => {
|
|
137
68
|
try {
|
|
@@ -150,30 +81,19 @@ export function write({
|
|
|
150
81
|
const sortedRows = mod.sortRows(stabilised);
|
|
151
82
|
const rollup = mod.rollup(sortedRows, components ?? []);
|
|
152
83
|
|
|
153
|
-
// The rollup() implementations always seed `*` from `aggregate()`, but
|
|
154
|
-
// the AC pins this explicitly: the envelope ALWAYS carries `*` even
|
|
155
|
-
// when `components` is undefined or empty. Belt-and-braces.
|
|
156
84
|
if (!Object.hasOwn(rollup, '*')) {
|
|
157
85
|
throw new Error(
|
|
158
86
|
`writer.write: ${kind} rollup is missing the required "*" key`,
|
|
159
87
|
);
|
|
160
88
|
}
|
|
161
89
|
|
|
162
|
-
// Story #2135 / Task #2146 — structural-equality short-circuit. When the
|
|
163
|
-
// caller supplies a `priorEnvelope` (or, for backwards-compatibility, the
|
|
164
|
-
// bare `prior` array is itself a full envelope object), and the projected
|
|
165
|
-
// rows + rollup deep-equal what's on the prior, return the prior envelope
|
|
166
|
-
// unchanged. This is the semantic replacement for the byte-equality
|
|
167
|
-
// compare in `baseline-snapshot.js` and is what makes a no-op auto-refresh
|
|
168
|
-
// produce a zero-byte baseline diff.
|
|
169
90
|
const priorEnv = resolvePriorEnvelope(priorEnvelope, prior);
|
|
170
91
|
if (
|
|
171
92
|
priorEnv &&
|
|
172
93
|
deepEqual(sortedRows, priorEnv.rows) &&
|
|
173
94
|
deepEqual(rollup, priorEnv.rollup)
|
|
174
95
|
) {
|
|
175
|
-
//
|
|
176
|
-
// an invalid envelope through the short-circuit.
|
|
96
|
+
// No smuggling an invalid envelope through the short-circuit.
|
|
177
97
|
assertEnvelope(priorEnv);
|
|
178
98
|
return priorEnv;
|
|
179
99
|
}
|
|
@@ -191,14 +111,7 @@ export function write({
|
|
|
191
111
|
return envelope;
|
|
192
112
|
}
|
|
193
113
|
|
|
194
|
-
/**
|
|
195
|
-
* Resolve the prior envelope used by the structural-equality short-circuit.
|
|
196
|
-
* Accepts either an explicit `priorEnvelope` (preferred) or, for backwards
|
|
197
|
-
* compatibility, recognises when `prior` is itself a full envelope object
|
|
198
|
-
* carrying `rows` + `rollup` rather than a bare rows array. Returns null
|
|
199
|
-
* when neither yields a usable envelope — the short-circuit is opt-in by
|
|
200
|
-
* design.
|
|
201
|
-
*/
|
|
114
|
+
/** `priorEnvelope`, else `prior` when it is a whole envelope, else null. */
|
|
202
115
|
function resolvePriorEnvelope(priorEnvelope, prior) {
|
|
203
116
|
if (
|
|
204
117
|
priorEnvelope &&
|
|
@@ -224,21 +137,8 @@ function resolvePriorEnvelope(priorEnvelope, prior) {
|
|
|
224
137
|
}
|
|
225
138
|
|
|
226
139
|
/**
|
|
227
|
-
* Serialise
|
|
228
|
-
* trailing newline
|
|
229
|
-
* already sorted by the per-kind module's `sortRows`). Atomic: writes to
|
|
230
|
-
* `<absPath>.tmp` then `rename`s onto the destination so a crash mid-write
|
|
231
|
-
* never leaves a half-flushed envelope on disk.
|
|
232
|
-
*
|
|
233
|
-
* Story #2135 / Task #2146 — the optional `fsImpl` seam lets tests inject
|
|
234
|
-
* a virtual filesystem (or an in-memory recorder) the way the legacy
|
|
235
|
-
* saver helpers allowed. Production callers omit it and fall through to
|
|
236
|
-
* `node:fs`. The seam covers `mkdirSync`, `writeFileSync`, and
|
|
237
|
-
* `renameSync` — the three calls this function actually makes — so a mock
|
|
238
|
-
* that exposes a subset of `fs` works without leaking real disk I/O.
|
|
239
|
-
*
|
|
240
|
-
* Backwards-compatible: two-argument callers (`writeFile(abs, env)`)
|
|
241
|
-
* continue to work unchanged.
|
|
140
|
+
* Serialise deterministically (fixed top-level key order, two-space indent,
|
|
141
|
+
* trailing newline) and atomically (tmp + rename).
|
|
242
142
|
*
|
|
243
143
|
* @param {string} absPath
|
|
244
144
|
* @param {object} envelope
|
|
@@ -251,29 +151,13 @@ export function writeFile(absPath, envelope, opts = {}) {
|
|
|
251
151
|
`writer.writeFile: absPath must be an absolute path (got ${JSON.stringify(absPath)})`,
|
|
252
152
|
);
|
|
253
153
|
}
|
|
254
|
-
//
|
|
255
|
-
// `write()` and `writeFile()`.
|
|
154
|
+
// The caller may have mutated the envelope since `write()`.
|
|
256
155
|
assertEnvelope(envelope);
|
|
257
156
|
|
|
258
157
|
const fsImpl = opts?.fsImpl ? opts.fsImpl : fs;
|
|
259
158
|
|
|
260
|
-
//
|
|
261
|
-
//
|
|
262
|
-
// declaration order; the row sort is done by `sortRows()`.
|
|
263
|
-
//
|
|
264
|
-
// The projection is deliberately explicit (Story #4775): a per-kind envelope
|
|
265
|
-
// stamp reaches disk only if it is named here, so an unlisted one is present
|
|
266
|
-
// in memory, passes validation, and is absent from the file it exists to
|
|
267
|
-
// protect. That is not hypothetical — Story #4901 added `provenanceStamped`
|
|
268
|
-
// to `envelopeExtras()` and not to this list, and every baseline written
|
|
269
|
-
// between then and Story #4969 lost it at this boundary, leaving the
|
|
270
|
-
// `provenance-unstamped` axis reading an absence its own writer had
|
|
271
|
-
// manufactured.
|
|
272
|
-
//
|
|
273
|
-
// A stamp a kind does not set is simply `undefined`, and `JSON.stringify`
|
|
274
|
-
// omits an undefined-valued key — so naming all three unconditionally emits
|
|
275
|
-
// exactly what the per-key `undefined` guards used to, with nothing to
|
|
276
|
-
// half-apply when the next stamp is added.
|
|
159
|
+
// A kind's envelope stamp reaches disk only if named here — add every new
|
|
160
|
+
// `envelopeExtras()` key. Unset stamps are undefined and JSON omits them.
|
|
277
161
|
const canonical = {
|
|
278
162
|
$schema: envelope.$schema,
|
|
279
163
|
kernelVersion: envelope.kernelVersion,
|
|
@@ -292,29 +176,12 @@ export function writeFile(absPath, envelope, opts = {}) {
|
|
|
292
176
|
return absPath;
|
|
293
177
|
}
|
|
294
178
|
|
|
295
|
-
/**
|
|
296
|
-
* Story #1974 — s-diff-scoped-writes scope-merge dispatch. When `scope` is
|
|
297
|
-
* present, defer to the per-kind `mergeRows(prior, projected, scope)` to
|
|
298
|
-
* preserve out-of-scope prior rows verbatim. Returns `projected` unchanged
|
|
299
|
-
* when `scope` is omitted, when the kind doesn't ship the merger
|
|
300
|
-
* (forward-compatible), or when `prior` is absent (nothing to preserve).
|
|
301
|
-
*/
|
|
302
179
|
function scopeMergeRows(mod, projected, prior, scope) {
|
|
303
180
|
if (scope === undefined || scope === null) return projected;
|
|
304
181
|
if (typeof mod.mergeRows !== 'function') return projected;
|
|
305
|
-
// mergeRows treats null/undefined/empty prior as "no preservation needed"
|
|
306
|
-
// and returns projected verbatim — that branch is covered upstream and
|
|
307
|
-
// here for symmetry.
|
|
308
182
|
return mod.mergeRows(prior ?? [], projected, scope);
|
|
309
183
|
}
|
|
310
184
|
|
|
311
|
-
/**
|
|
312
|
-
* Story #1964 — s-stability-epsilon stabilizer dispatch. When both
|
|
313
|
-
* `prior` and `epsilon` are present, fold sub-epsilon row deltas back to
|
|
314
|
-
* the prior bytes via the per-kind `applyEpsilon`. Returns `projected`
|
|
315
|
-
* unchanged when either is omitted, or when the kind doesn't ship the
|
|
316
|
-
* stabilizer (forward-compatible).
|
|
317
|
-
*/
|
|
318
185
|
function stabiliseRows(mod, projected, prior, epsilon) {
|
|
319
186
|
if (prior === undefined || epsilon === undefined) return projected;
|
|
320
187
|
if (!Array.isArray(prior)) {
|
|
@@ -1,40 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* BDD runner detection
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* files marked `@pending` / `@skip` ahead of the implementation Stories) or
|
|
9
|
-
* fall back to **dependencies-first** ordering (no pending tag → cannot
|
|
10
|
-
* suspend an unimplemented scenario without a permanent red, so Stories run
|
|
11
|
-
* in dependency order and the AC reconciler defers).
|
|
12
|
-
*
|
|
13
|
-
* The verification is **static**: we inspect `package.json` for a known BDD
|
|
14
|
-
* runner dependency, and consult a small lookup table of which runners
|
|
15
|
-
* support which pending/skip tag. We do not boot the runner. This keeps
|
|
16
|
-
* `/mandrel-plan` Phase 7 hermetic and offline.
|
|
17
|
-
*
|
|
18
|
-
* **Workspace awareness (Story #2956).** In a pnpm / npm / yarn monorepo the
|
|
19
|
-
* BDD runner is rarely a root devDependency — it lives in the workspace
|
|
20
|
-
* package that owns the e2e suite (e.g. `apps/web/package.json`). The
|
|
21
|
-
* detector reads the root `package.json` first and then unions in
|
|
22
|
-
* dependencies from every declared workspace package, so an `apps/*` shaped
|
|
23
|
-
* monorepo no longer falls back to "no runner detected" when the runner
|
|
24
|
-
* sits one level down. Workspace declarations are read from
|
|
25
|
-
* `pnpm-workspace.yaml` (`packages:` field) or the root `package.json`
|
|
26
|
-
* `workspaces` field (array or `{ packages: [] }` object form).
|
|
27
|
-
* Preferred-first ordering is preserved by iterating
|
|
28
|
-
* `BDD_RUNNER_TAG_TABLE` against the union of all collected deps — the
|
|
29
|
-
* first runner present in *any* package wins.
|
|
30
|
-
*
|
|
31
|
-
* Output shape (returned to the planner-context envelope):
|
|
32
|
-
*
|
|
33
|
-
* { runner: 'cucumber-js', pendingTag: '@skip', supported: true, fallback: false }
|
|
34
|
-
* { runner: 'playwright-bdd', pendingTag: '@skip', supported: true, fallback: false }
|
|
35
|
-
* { runner: '@cucumber/cucumber', pendingTag: '@skip', supported: true, fallback: false }
|
|
36
|
-
* { runner: null, pendingTag: null, supported: false, fallback: true,
|
|
37
|
-
* reason: 'no-bdd-runner-detected' }
|
|
2
|
+
* Static BDD runner detection: does the project ship a runner with a
|
|
3
|
+
* pending/skip tag? If so the planner can order features-first (scenarios
|
|
4
|
+
* land `@skip` ahead of the implementation); if not, dependencies-first,
|
|
5
|
+
* since an unimplemented scenario would be a permanent red. Reads the root
|
|
6
|
+
* `package.json` plus every workspace package (runners usually live in one),
|
|
7
|
+
* never boots the runner.
|
|
38
8
|
*/
|
|
39
9
|
|
|
40
10
|
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
@@ -45,13 +15,7 @@ import picomatch from 'picomatch';
|
|
|
45
15
|
|
|
46
16
|
import { Logger } from './Logger.js';
|
|
47
17
|
|
|
48
|
-
/**
|
|
49
|
-
* Known BDD runner package names → pending-tag string the runner honours.
|
|
50
|
-
*
|
|
51
|
-
* Keys MUST match the literal npm package name as it appears in
|
|
52
|
-
* `dependencies` or `devDependencies`. Order is preferred-first: if multiple
|
|
53
|
-
* runners are present (rare), the first match wins.
|
|
54
|
-
*/
|
|
18
|
+
/** npm package name → pending tag. Preferred-first: the first match wins. */
|
|
55
19
|
export const BDD_RUNNER_TAG_TABLE = Object.freeze({
|
|
56
20
|
'playwright-bdd': '@skip',
|
|
57
21
|
'@cucumber/cucumber': '@skip',
|
|
@@ -60,21 +24,8 @@ export const BDD_RUNNER_TAG_TABLE = Object.freeze({
|
|
|
60
24
|
});
|
|
61
25
|
|
|
62
26
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* pending-tag value in `BDD_RUNNER_TAG_TABLE` (today `@skip` / `skip`).
|
|
66
|
-
*
|
|
67
|
-
* Both the prefixed (`@skip`) and the unprefixed (`skip`) form of each
|
|
68
|
-
* tag are included so consumers can look up either the raw tag string
|
|
69
|
-
* (as it appears in a `.feature` file) or the normalized token form
|
|
70
|
-
* produced by tag-block parsers that strip the leading `@`.
|
|
71
|
-
*
|
|
72
|
-
* Consumers:
|
|
73
|
-
* - `acceptance-spec-reconciler.classifyCoverage` — membership check
|
|
74
|
-
* against parsed scenario tag sets.
|
|
75
|
-
* - Contract tests that walk `BDD_RUNNER_TAG_TABLE` and assert each
|
|
76
|
-
* pending tag is registered here, guarding against drift when a
|
|
77
|
-
* new runner is added.
|
|
27
|
+
* Tags meaning "coverage pending, not satisfied", in both `@skip` and
|
|
28
|
+
* `skip` forms (parsers may strip the `@`).
|
|
78
29
|
*/
|
|
79
30
|
export const PENDING_TAGS = Object.freeze(
|
|
80
31
|
new Set(
|
|
@@ -85,11 +36,6 @@ export const PENDING_TAGS = Object.freeze(
|
|
|
85
36
|
),
|
|
86
37
|
);
|
|
87
38
|
|
|
88
|
-
/**
|
|
89
|
-
* Result returned when no supported BDD runner is detected. The acceptance
|
|
90
|
-
* spec body will print "Fallback: dependencies-first ordering" and Phase 8
|
|
91
|
-
* decomposer ordering reverts to topological dependency order.
|
|
92
|
-
*/
|
|
93
39
|
const FALLBACK = Object.freeze({
|
|
94
40
|
runner: null,
|
|
95
41
|
pendingTag: null,
|
|
@@ -99,19 +45,11 @@ const FALLBACK = Object.freeze({
|
|
|
99
45
|
});
|
|
100
46
|
|
|
101
47
|
/**
|
|
102
|
-
* Verify which BDD runner (if any) the project ships and whether it
|
|
103
|
-
* supports a pending/skip tag. Reads the root `package.json` and (when
|
|
104
|
-
* declared) every workspace `package.json` so monorepos that house the
|
|
105
|
-
* runner in `apps/<name>` or `packages/<name>` resolve correctly.
|
|
106
|
-
*
|
|
107
48
|
* @param {object} [opts]
|
|
108
|
-
* @param {string} [opts.cwd]
|
|
109
|
-
* @param {(p: string) => Promise<string>} [opts.readPkg]
|
|
110
|
-
* tests; receives the resolved absolute path to a `package.json`.
|
|
49
|
+
* @param {string} [opts.cwd]
|
|
50
|
+
* @param {(p: string) => Promise<string>} [opts.readPkg] Test seam.
|
|
111
51
|
* @param {(ctx: { cwd: string, rootPkg: object, readPkg: Function }) => Promise<string[]>} [opts.listWorkspacePkgPaths]
|
|
112
|
-
*
|
|
113
|
-
* files. Defaults to scanning `pnpm-workspace.yaml` then the root
|
|
114
|
-
* `package.json` `workspaces` field and expanding their glob patterns.
|
|
52
|
+
* Test seam.
|
|
115
53
|
* @returns {Promise<{ runner: string|null, pendingTag: string|null, supported: boolean, fallback: boolean, reason?: string }>}
|
|
116
54
|
*/
|
|
117
55
|
export async function verifyBddRunnerPendingTag(opts = {}) {
|
|
@@ -153,7 +91,6 @@ export async function verifyBddRunnerPendingTag(opts = {}) {
|
|
|
153
91
|
logger,
|
|
154
92
|
});
|
|
155
93
|
} catch (err) {
|
|
156
|
-
// Workspace discovery failure is non-fatal: degrade to root-only scan.
|
|
157
94
|
logger.debug(
|
|
158
95
|
`[bdd-runner-detect] workspace discovery failed for ${cwd}: ${err?.message ?? err}`,
|
|
159
96
|
);
|
|
@@ -201,18 +138,8 @@ export async function verifyBddRunnerPendingTag(opts = {}) {
|
|
|
201
138
|
}
|
|
202
139
|
|
|
203
140
|
/**
|
|
204
|
-
*
|
|
205
|
-
* field
|
|
206
|
-
* glob patterns against `cwd`, and return the resulting workspace
|
|
207
|
-
* `package.json` absolute paths.
|
|
208
|
-
*
|
|
209
|
-
* Returns `[]` (silent) on any of:
|
|
210
|
-
* - no `pnpm-workspace.yaml` and no `workspaces` field
|
|
211
|
-
* - YAML parse failure
|
|
212
|
-
* - patterns matching no on-disk directories
|
|
213
|
-
*
|
|
214
|
-
* Failures here are non-fatal so a malformed workspace file can never
|
|
215
|
-
* block planner-context emission.
|
|
141
|
+
* Workspace `package.json` paths from `pnpm-workspace.yaml`, else the root
|
|
142
|
+
* `workspaces` field. Non-fatal: `[]` on any failure.
|
|
216
143
|
*
|
|
217
144
|
* @returns {Promise<string[]>}
|
|
218
145
|
*/
|
|
@@ -233,7 +160,6 @@ function readWorkspacePatterns(cwd, rootPkg, logger) {
|
|
|
233
160
|
return parsed.packages.filter((p) => typeof p === 'string');
|
|
234
161
|
}
|
|
235
162
|
} catch (err) {
|
|
236
|
-
// unparseable yaml → fall through to package.json workspaces
|
|
237
163
|
logger.debug(
|
|
238
164
|
`[bdd-runner-detect] pnpm-workspace.yaml parse failed for ${yamlPath}: ${err?.message ?? err}`,
|
|
239
165
|
);
|
|
@@ -253,14 +179,7 @@ function readWorkspacePatterns(cwd, rootPkg, logger) {
|
|
|
253
179
|
return [];
|
|
254
180
|
}
|
|
255
181
|
|
|
256
|
-
/**
|
|
257
|
-
* Expand a list of workspace glob patterns into absolute paths to each
|
|
258
|
-
* matching `package.json`. Handles:
|
|
259
|
-
* - literal directory entries (no glob chars): `apps/web`
|
|
260
|
-
* - single-segment globs: `apps/*`, `packages/*`
|
|
261
|
-
* - recursive globs: `packages/**`
|
|
262
|
-
* - exclusion patterns prefixed with `!` (pnpm/npm convention)
|
|
263
|
-
*/
|
|
182
|
+
/** Handles literal dirs, `*` and `**` globs, and `!` exclusions. */
|
|
264
183
|
function expandWorkspacePatterns(cwd, patterns, logger) {
|
|
265
184
|
const includes = patterns.filter((p) => !p.startsWith('!'));
|
|
266
185
|
const excludes = patterns
|
|
@@ -366,13 +285,7 @@ function existsSyncDir(p, logger) {
|
|
|
366
285
|
}
|
|
367
286
|
}
|
|
368
287
|
|
|
369
|
-
/**
|
|
370
|
-
* Canonical directories a project might use to house `.feature` files.
|
|
371
|
-
* Probed in order; the first existing directory wins. The list is
|
|
372
|
-
* deliberately short — projects that house features elsewhere will need
|
|
373
|
-
* to land an explicit config surface for it, which Story #2637 leaves
|
|
374
|
-
* out of scope.
|
|
375
|
-
*/
|
|
288
|
+
/** Canonical `.feature` directories; there is no config key for others. */
|
|
376
289
|
const CANONICAL_FEATURE_ROOTS = Object.freeze([
|
|
377
290
|
'tests/features',
|
|
378
291
|
'features',
|
|
@@ -380,17 +293,10 @@ const CANONICAL_FEATURE_ROOTS = Object.freeze([
|
|
|
380
293
|
]);
|
|
381
294
|
|
|
382
295
|
/**
|
|
383
|
-
*
|
|
384
|
-
* canonical directory that exists under `cwd`. Returns an empty array
|
|
385
|
-
* when no feature directory is present (the project has not adopted
|
|
386
|
-
* BDD), so downstream scanners can degrade silently to "no scenarios".
|
|
387
|
-
*
|
|
388
|
-
* Story #2637 — the Phase 7 BDD-scenario scanner consumes this so the
|
|
389
|
-
* planner can cross-reference acceptance criteria against existing
|
|
390
|
-
* scenarios without introducing a new config key.
|
|
296
|
+
* Existing canonical feature roots; `[]` when the project has not adopted BDD.
|
|
391
297
|
*
|
|
392
298
|
* @param {{ cwd?: string }} [opts]
|
|
393
|
-
* @returns {string[]}
|
|
299
|
+
* @returns {string[]}
|
|
394
300
|
*/
|
|
395
301
|
export function resolveFeatureRoots(opts = {}) {
|
|
396
302
|
const cwd = opts.cwd ?? process.cwd();
|
|
@@ -403,7 +309,6 @@ export function resolveFeatureRoots(opts = {}) {
|
|
|
403
309
|
roots.push(abs);
|
|
404
310
|
}
|
|
405
311
|
} catch (err) {
|
|
406
|
-
// Unreadable path → treat as absent. Non-blocking by design.
|
|
407
312
|
logger.debug(
|
|
408
313
|
`[bdd-runner-detect] feature-root probe failed for ${abs}: ${err?.message ?? err}`,
|
|
409
314
|
);
|