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,39 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* This is a **bonus, not the contract.** The deposit every project can rely
|
|
7
|
-
* on is `evidence-gate.js --standalone --scope-id <id> --gate test --worktree
|
|
8
|
-
* <workCwd> -- npm test`: it spawns whatever `npm test` resolves to and
|
|
9
|
-
* stamps what it just ran, so it is honest on any runner. What this module
|
|
10
|
-
* adds is that a repo whose `test` script *is* `run-tests.js` need not type
|
|
11
|
-
* that wrapper — the runner already knows the tree it ran against, whether
|
|
12
|
-
* the run was green, and whether it ran the whole suite, so it deposits on
|
|
13
|
-
* the way out.
|
|
14
|
-
*
|
|
15
|
-
* The reach is therefore exactly one call site: `run-tests.js`. A consumer
|
|
16
|
-
* whose `npm test` is `vitest run` or `jest` never loads this module, so it
|
|
17
|
-
* deposits nothing **and prints nothing** — silence is not a signal, and no
|
|
18
|
-
* delivery surface may tell an agent to confirm credit by reading for the
|
|
19
|
-
* line below. `mandrel doctor`'s `test-credit-path` check reports which of
|
|
20
|
-
* the two shapes a project is and names the wrapper as the remedy.
|
|
21
|
-
*
|
|
22
|
-
* On a green **full-tier** run inside a `story-<id>` checkout the runner
|
|
23
|
-
* records the `test` gate's evidence in the same keyspace
|
|
24
|
-
* `close-validation/runner.js` consults — keyed on HEAD and the tree
|
|
25
|
-
* fingerprint, hashed on the exact `{ cmd: 'npm', args: ['test'], cwd }`
|
|
26
|
-
* close will spawn — so close's `test` gate short-circuits at unchanged HEAD.
|
|
27
|
-
* The freshness keying is untouched: a later commit voids the record exactly
|
|
28
|
-
* as it voids one `evidence-gate.js` wrote.
|
|
29
|
-
*
|
|
30
|
-
* What it deliberately does **not** do is write the coverage capture stamp:
|
|
31
|
-
* that stamp is a claim that `coverage/coverage-final.json` describes this
|
|
32
|
-
* tree, and a bare `npm test` produces no such artifact. The CRAP gate still
|
|
33
|
-
* runs `coverage-capture.js` when it needs one.
|
|
34
|
-
*
|
|
35
|
-
* Total: every failure — not a Story branch, no git, an unwritable evidence
|
|
36
|
-
* file — is reported by reason and never fails the test run that earned it.
|
|
2
|
+
* A green full-tier `run-tests.js` run on a `story-<id>` branch deposits the
|
|
3
|
+
* `test` evidence close reads — a bonus; `evidence-gate.js` is the contract.
|
|
4
|
+
* Other runners never load this, so absence of its line means nothing. Never
|
|
5
|
+
* writes the coverage stamp (no coverage artifact exists). Never fails the run.
|
|
37
6
|
*
|
|
38
7
|
* @module lib/test-run-credit
|
|
39
8
|
*/
|
|
@@ -48,18 +17,15 @@ import {
|
|
|
48
17
|
treeFingerprint,
|
|
49
18
|
} from './validation-evidence.js';
|
|
50
19
|
|
|
51
|
-
/** The gate name close's runner looks the record up under. */
|
|
52
20
|
const GATE_NAME = 'test';
|
|
53
21
|
|
|
54
|
-
/**
|
|
22
|
+
/** Must hash identically to the command close spawns. */
|
|
55
23
|
const GATE_COMMAND = Object.freeze({
|
|
56
24
|
cmd: 'npm',
|
|
57
25
|
args: Object.freeze(['test']),
|
|
58
26
|
});
|
|
59
27
|
|
|
60
28
|
/**
|
|
61
|
-
* Read one trimmed git stdout line, or `null` on any failure.
|
|
62
|
-
*
|
|
63
29
|
* @param {Function} gitSpawnFn
|
|
64
30
|
* @param {string} cwd
|
|
65
31
|
* @param {string[]} args
|
|
@@ -77,8 +43,6 @@ function gitLine(gitSpawnFn, cwd, args) {
|
|
|
77
43
|
}
|
|
78
44
|
|
|
79
45
|
/**
|
|
80
|
-
* The Story id a checkout's branch names, or `null` off a Story branch.
|
|
81
|
-
*
|
|
82
46
|
* @param {string|null} branch
|
|
83
47
|
* @returns {number|null}
|
|
84
48
|
*/
|
|
@@ -90,10 +54,7 @@ export function storyIdFromBranch(branch) {
|
|
|
90
54
|
}
|
|
91
55
|
|
|
92
56
|
/**
|
|
93
|
-
* The checkout
|
|
94
|
-
* checkout, which is where close runs with `--cwd <main-repo>`. From a
|
|
95
|
-
* worktree `git rev-parse --git-common-dir` names the main `.git`; from the
|
|
96
|
-
* main checkout it names its own. Either way the parent is the checkout.
|
|
57
|
+
* The main checkout (where close reads evidence), via `--git-common-dir`.
|
|
97
58
|
*
|
|
98
59
|
* @param {string} cwd
|
|
99
60
|
* @param {Function} gitSpawnFn
|
|
@@ -107,8 +68,6 @@ export function resolveEvidenceRoot(cwd, gitSpawnFn) {
|
|
|
107
68
|
}
|
|
108
69
|
|
|
109
70
|
/**
|
|
110
|
-
* Deposit the `test` gate's evidence for a green full-suite run.
|
|
111
|
-
*
|
|
112
71
|
* @param {{
|
|
113
72
|
* cwd: string,
|
|
114
73
|
* tier?: string,
|
|
@@ -151,11 +110,7 @@ export function depositTestRunCredit({
|
|
|
151
110
|
}
|
|
152
111
|
|
|
153
112
|
/**
|
|
154
|
-
* Deposit and
|
|
155
|
-
* when this runner is the one running. It names the outcome by reason, so a
|
|
156
|
-
* green run that deposited nothing (wrong branch, partial tier) says so
|
|
157
|
-
* rather than passing silently; a project on another runner prints no line
|
|
158
|
-
* at all, which is why absence of this line is never evidence either way.
|
|
113
|
+
* Deposit and report the outcome (with reason) on stderr.
|
|
159
114
|
*
|
|
160
115
|
* @param {Parameters<typeof depositTestRunCredit>[0] & { log?: (line: string) => void }} args
|
|
161
116
|
* @returns {ReturnType<typeof depositTestRunCredit>}
|
|
@@ -174,17 +129,9 @@ export function reportTestRunCredit({
|
|
|
174
129
|
}
|
|
175
130
|
|
|
176
131
|
/**
|
|
177
|
-
*
|
|
178
|
-
* `
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
* When it did, close registers the plain `test` gate beside the capture gate
|
|
182
|
-
* even though coverage-capture is the active test runner: the runner's
|
|
183
|
-
* evidence check then skips it as credited, so close REPORTS the suite the
|
|
184
|
-
* worker already ran instead of silently folding it into the capture. It is
|
|
185
|
-
* never a second spend — an uncredited tree resolves `false` and the
|
|
186
|
-
* pre-#5313 shape (capture alone runs the suite) is unchanged. Every
|
|
187
|
-
* uncertainty resolves `false`.
|
|
132
|
+
* Read side of {@link depositTestRunCredit}: when credited, close registers
|
|
133
|
+
* the plain `test` gate so it reports as credited (never a second spend).
|
|
134
|
+
* Every uncertainty resolves `false`.
|
|
188
135
|
*
|
|
189
136
|
* @param {{
|
|
190
137
|
* storyId?: number|null,
|
|
@@ -234,8 +181,6 @@ export function predictsTestEvidenceCredit({
|
|
|
234
181
|
}
|
|
235
182
|
|
|
236
183
|
/**
|
|
237
|
-
* The write itself, split out so the guard chain above stays flat.
|
|
238
|
-
*
|
|
239
184
|
* @param {{ storyId: number, sha: string, cwd: string, evidenceRoot: string, durationMs: number|null, gitSpawnFn: Function, recordPassFn: Function }} args
|
|
240
185
|
* @returns {{ deposited: boolean, reason: string, storyId: number, sha: string }}
|
|
241
186
|
*/
|
|
@@ -1,32 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The contract
|
|
3
|
-
* set
|
|
2
|
+
* The contract both full-tier runners (`run-tests.js`, `run-coverage.js`)
|
|
3
|
+
* share: the `node --test` flag set and the per-tier preflight. A flag
|
|
4
|
+
* divergence (e.g. module mocks) makes a suite pass under one runner and fail
|
|
5
|
+
* under the other, so neither restates a literal.
|
|
4
6
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* The repository has two full-tier runners — `run-tests.js` (`npm test`) and
|
|
8
|
-
* `run-coverage.js` (`npm run test:coverage`, the *required* CI job). When
|
|
9
|
-
* they disagree about a `node --test` flag, they disagree about whether a
|
|
10
|
-
* test can execute at all: `--experimental-test-module-mocks` decides whether
|
|
11
|
-
* `t.mock.module` works, so a divergence makes a suite pass under one runner
|
|
12
|
-
* and fail under the other with no source defect. `FULL_TIER_GLOBS` in
|
|
13
|
-
* [`test-tiers.js`](test-tiers.js) already solved the sibling problem for
|
|
14
|
-
* *which files* run; this module is the same fix for *how they are run*.
|
|
15
|
-
* Both runners import from here; neither restates a literal.
|
|
16
|
-
*
|
|
17
|
-
* ## The preflight is invoked, never hooked
|
|
18
|
-
*
|
|
19
|
-
* `.npmrc` sets `ignore-scripts=true` as deliberate defence against malicious
|
|
20
|
-
* postinstall hooks (CWE-1357). That setting is correct and stays — but it
|
|
21
|
-
* suppresses every `pre*` / `post*` lifecycle script for `npm run` as well as
|
|
22
|
-
* for installs, so a `pretest` entry in `package.json` never fires. The
|
|
23
|
-
* repository carried `pretest`, `pretest:quick` and `pretest:integration`
|
|
24
|
-
* entries that therefore ran for no tier at all, and Story #4922 worked
|
|
25
|
-
* around it for the coverage tier alone by having CI name `pretest:coverage`
|
|
26
|
-
* explicitly. `runTierPreflight` closes the gap for every tier by moving the
|
|
27
|
-
* invocation into the runners, where it executes under `npm test`,
|
|
28
|
-
* `npm run test:coverage`, and a bare `node .agents/scripts/run-tests.js`
|
|
29
|
-
* alike — no lifecycle hook involved.
|
|
7
|
+
* The preflight is invoked by the runners, never an npm `pre*` hook:
|
|
8
|
+
* `.npmrc`'s `ignore-scripts=true` (CWE-1357 defence) suppresses those.
|
|
30
9
|
*/
|
|
31
10
|
|
|
32
11
|
import { spawnSync } from 'node:child_process';
|
|
@@ -34,19 +13,13 @@ import os from 'node:os';
|
|
|
34
13
|
import path from 'node:path';
|
|
35
14
|
import process from 'node:process';
|
|
36
15
|
|
|
37
|
-
/** Minimum and maximum bounds for `--test-concurrency`. */
|
|
38
16
|
export const TEST_CONCURRENCY_MIN = 1;
|
|
39
17
|
export const TEST_CONCURRENCY_MAX = 16;
|
|
40
18
|
|
|
41
19
|
/**
|
|
42
|
-
*
|
|
20
|
+
* Host parallelism clamped to the concurrency bounds.
|
|
43
21
|
*
|
|
44
|
-
*
|
|
45
|
-
* range `[TEST_CONCURRENCY_MIN, TEST_CONCURRENCY_MAX]`. The `parallelism`
|
|
46
|
-
* parameter is injected in tests so the clamping logic is verifiable
|
|
47
|
-
* without touching the OS.
|
|
48
|
-
*
|
|
49
|
-
* @param {number} [parallelism] - defaults to `os.availableParallelism()`
|
|
22
|
+
* @param {number} [parallelism]
|
|
50
23
|
* @returns {number}
|
|
51
24
|
*/
|
|
52
25
|
export function resolveTestConcurrency(
|
|
@@ -58,17 +31,7 @@ export function resolveTestConcurrency(
|
|
|
58
31
|
);
|
|
59
32
|
}
|
|
60
33
|
|
|
61
|
-
/**
|
|
62
|
-
* Fixed `node --test` flags applied to every spawn of every runner.
|
|
63
|
-
*
|
|
64
|
-
* `--test-concurrency` is derived at startup from the host's available
|
|
65
|
-
* parallelism so the value suits the machine running the suite rather than
|
|
66
|
-
* being pinned to the historical constant of 8.
|
|
67
|
-
*
|
|
68
|
-
* This is the **single** declaration. A flag added here reaches both runners;
|
|
69
|
-
* a flag added to one runner's argv builder instead is caught by the
|
|
70
|
-
* flag-set equality assertion in `tests/scripts/run-coverage.test.js`.
|
|
71
|
-
*/
|
|
34
|
+
/** The single `node --test` flag declaration for every runner spawn. */
|
|
72
35
|
export const TEST_RUNNER_FLAGS = Object.freeze([
|
|
73
36
|
'--experimental-test-module-mocks',
|
|
74
37
|
'--test',
|
|
@@ -76,19 +39,9 @@ export const TEST_RUNNER_FLAGS = Object.freeze([
|
|
|
76
39
|
]);
|
|
77
40
|
|
|
78
41
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* `full` carries the skills validator on top of the state-probe wrapper
|
|
83
|
-
* because the full tier is the release-shaped run (and the surface the
|
|
84
|
-
* coverage tier measures); `quick` and `integration` run the state probe
|
|
85
|
-
* only, matching the tiers' historical `pretest:quick` / `pretest:integration`
|
|
86
|
-
* definitions. The coverage runner runs the full tier, so it shares `full`.
|
|
87
|
-
*
|
|
88
|
-
* Deliberately not exported: a second importer would be a second place to
|
|
89
|
-
* read the tier→preflight mapping from, and tests assert the mapping through
|
|
90
|
-
* the spawns `runTierPreflight` actually issues — which is the thing that
|
|
91
|
-
* has to be true.
|
|
42
|
+
* Per-tier preflight scripts; `full` (release-shaped, also the coverage
|
|
43
|
+
* tier) adds the skills validator. Not exported: tests assert the mapping
|
|
44
|
+
* through the spawns `runTierPreflight` issues.
|
|
92
45
|
*/
|
|
93
46
|
const STATE_PROBE_ONLY = Object.freeze(['.agents/scripts/test-wrapper.js']);
|
|
94
47
|
|
|
@@ -99,26 +52,19 @@ const TIER_PREFLIGHT_SCRIPTS = Object.freeze({
|
|
|
99
52
|
]),
|
|
100
53
|
quick: STATE_PROBE_ONLY,
|
|
101
54
|
integration: STATE_PROBE_ONLY,
|
|
102
|
-
//
|
|
103
|
-
// non-full tier. An absent entry is not a neutral default — the lookup
|
|
104
|
-
// below falls through to `[]`, so a tier missing from this map runs *no*
|
|
105
|
-
// preflight at all and the omission is invisible in a green run.
|
|
55
|
+
// A tier missing here silently runs no preflight at all.
|
|
106
56
|
e2e: STATE_PROBE_ONLY,
|
|
107
57
|
});
|
|
108
58
|
|
|
109
59
|
/**
|
|
110
|
-
* Run
|
|
111
|
-
*
|
|
112
|
-
* Mirrors npm's own `pre<script>` semantics — a failed preflight aborts
|
|
113
|
-
* before the test runner is spawned and propagates its exit code (the
|
|
114
|
-
* wrapper reserves 2 for "preflight refused") — except that it actually
|
|
115
|
-
* executes, which the npm hook does not under `ignore-scripts=true`.
|
|
60
|
+
* Run a tier's preflight in order, stopping at (and returning) the first
|
|
61
|
+
* failure's exit code, like npm `pre<script>`.
|
|
116
62
|
*
|
|
117
63
|
* @param {object} [opts]
|
|
118
64
|
* @param {'full' | 'quick' | 'integration' | 'e2e'} [opts.tier]
|
|
119
|
-
* @param {string} [opts.repoRoot]
|
|
120
|
-
* @param {typeof spawnSync} [opts.spawn]
|
|
121
|
-
* @param {string} [opts.execPath]
|
|
65
|
+
* @param {string} [opts.repoRoot]
|
|
66
|
+
* @param {typeof spawnSync} [opts.spawn]
|
|
67
|
+
* @param {string} [opts.execPath]
|
|
122
68
|
* @returns {number} 0 when every preflight script passed, else the first
|
|
123
69
|
* non-zero exit code.
|
|
124
70
|
*/
|
|
@@ -134,8 +80,7 @@ export function runTierPreflight({
|
|
|
134
80
|
stdio: 'inherit',
|
|
135
81
|
});
|
|
136
82
|
if (run.error) throw run.error;
|
|
137
|
-
// A signal-killed child reports `status: null
|
|
138
|
-
// reserved failure code rather than letting it read as "not zero, no code".
|
|
83
|
+
// A signal-killed child reports `status: null`.
|
|
139
84
|
if (run.status !== 0) return run.status ?? 1;
|
|
140
85
|
}
|
|
141
86
|
return 0;
|
|
@@ -1,36 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Managed test temp
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* sites across 25 files that never reaped them, accumulating tens of
|
|
6
|
-
* thousands of entries per run into a temp root shared with self-hosted CI
|
|
7
|
-
* runners. The damaging axis is **entry count**, not bytes: a runner's
|
|
8
|
-
* job-started hook scanning an 841k-entry temp root burned 5m29s inside the
|
|
9
|
-
* job clock and timed jobs out.
|
|
10
|
-
*
|
|
11
|
-
* Per-call-site teardown had already failed 25 times, so this module makes
|
|
12
|
-
* teardown structural instead: a directory cannot be created without its
|
|
13
|
-
* reaping already registered.
|
|
14
|
-
*
|
|
15
|
-
* ## Why one suite root
|
|
16
|
-
*
|
|
17
|
-
* A guard over a *shared* `os.tmpdir()` cannot attribute an entry to this
|
|
18
|
-
* suite. A prefix allowlist rots the moment someone invents a new prefix,
|
|
19
|
-
* and a bare "no new entries" assertion false-positives on any unrelated
|
|
20
|
-
* process that happened to run concurrently. Nesting every managed
|
|
21
|
-
* directory inside a single per-process root
|
|
22
|
-
* (`mandrel-suite-<pid>-<random>`) makes attribution exact: the guard asks
|
|
23
|
-
* only whether a *suite root* survived, which is a question about this
|
|
24
|
-
* suite alone. The suite contributes exactly one shared-root entry per
|
|
25
|
-
* process, and reaps it.
|
|
26
|
-
*
|
|
27
|
-
* ## Why the root is never published to children
|
|
28
|
-
*
|
|
29
|
-
* Deliberately unlike `MANDREL_TEST_TEMP_ROOT` (the scratch seam in
|
|
30
|
-
* `test-env.js` / `config/temp-paths.js`, which children inherit): each
|
|
31
|
-
* process owns its own suite root, so "did I create it?" is always
|
|
32
|
-
* answerable locally and a child can never reap its parent's root
|
|
33
|
-
* mid-run.
|
|
2
|
+
* Managed test temp dirs: none exists without its reaping registered. All
|
|
3
|
+
* nest in one per-process suite root, so the leak guard attributes exactly;
|
|
4
|
+
* the root is never published to children, so none can reap its parent's.
|
|
34
5
|
*/
|
|
35
6
|
|
|
36
7
|
import fs from 'node:fs';
|
|
@@ -38,32 +9,23 @@ import os from 'node:os';
|
|
|
38
9
|
import path from 'node:path';
|
|
39
10
|
import picomatch from 'picomatch';
|
|
40
11
|
|
|
41
|
-
/**
|
|
42
|
-
* Directory-name prefix identifying a per-process suite root. The guard
|
|
43
|
-
* matches on this, so it is the one string both sides must agree on.
|
|
44
|
-
*/
|
|
12
|
+
/** Suite-root name prefix; the guard matches on it. */
|
|
45
13
|
export const SUITE_ROOT_PREFIX = 'mandrel-suite-';
|
|
46
14
|
|
|
47
15
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* entry: those are always `*.ndjson` relative paths.
|
|
16
|
+
* Snapshot-manifest key for suite roots; cannot collide with a stream entry
|
|
17
|
+
* (always a `*.ndjson` relative path).
|
|
51
18
|
*/
|
|
52
19
|
export const SUITE_ROOTS_KEY = '#suiteRoots';
|
|
53
20
|
|
|
54
|
-
/** Default `warn` sink: one line on stderr, shared by every seam below. */
|
|
55
21
|
const stderrWarn = (msg) => process.stderr.write(`${msg}\n`);
|
|
56
22
|
|
|
57
23
|
/**
|
|
58
|
-
* Remove
|
|
59
|
-
*
|
|
60
|
-
* Both reapers need exactly this: a suite that passed must not start
|
|
61
|
-
* failing because a directory could not be unlinked (a Windows file lock, a
|
|
62
|
-
* read-only mount). The leak is the lesser defect, and the guard reports it
|
|
63
|
-
* separately.
|
|
24
|
+
* Remove a directory, reporting rather than throwing: a passing suite must
|
|
25
|
+
* not fail on an unlinkable directory (Windows lock, read-only mount).
|
|
64
26
|
*
|
|
65
27
|
* @param {string} target absolute path to remove
|
|
66
|
-
* @param {string} label
|
|
28
|
+
* @param {string} label
|
|
67
29
|
* @param {typeof fs} fsImpl
|
|
68
30
|
* @param {(msg: string) => void} warn
|
|
69
31
|
* @returns {void}
|
|
@@ -76,36 +38,25 @@ function rmQuietly(target, label, fsImpl, warn) {
|
|
|
76
38
|
}
|
|
77
39
|
}
|
|
78
40
|
|
|
79
|
-
/** Per-process suite root, or `null` before the first `makeTempDir`. */
|
|
80
41
|
let _suiteRoot = null;
|
|
81
42
|
|
|
82
|
-
/** Guards against registering the exit reaper more than once. */
|
|
83
43
|
let _reaperRegistered = false;
|
|
84
44
|
|
|
85
|
-
/** Lead-in of the one warning a root disappearing mid-run produces. */
|
|
86
45
|
const VANISHED =
|
|
87
46
|
'[test-temp] suite temp root disappeared mid-run (removed by something ' +
|
|
88
47
|
'outside this process):';
|
|
89
48
|
|
|
90
49
|
/**
|
|
91
|
-
* Suite roots this process minted and later found gone.
|
|
92
|
-
*
|
|
93
|
-
* Recovery is the right behaviour — see {@link suiteTempRoot} — but a silent
|
|
94
|
-
* recovery is not. Incident #5272 was a required check going red with an
|
|
95
|
-
* unattributable `ENOENT`, and the hardening written to expose it made the
|
|
96
|
-
* run *quieter*: the re-mint succeeded, the suite went green, and the fact
|
|
97
|
-
* that something outside the process is deleting the temp tree left no trace
|
|
98
|
-
* anyone would look at. This list is that trace, and the exit reaper turns it
|
|
99
|
-
* into a verdict.
|
|
50
|
+
* Suite roots this process minted and later found gone. Recovery must not be
|
|
51
|
+
* silent: the exit reaper turns this list into a failing verdict.
|
|
100
52
|
*/
|
|
101
53
|
const _vanishedRoots = [];
|
|
102
54
|
|
|
103
|
-
/** Exit code a run that lost a suite root reports, when nothing worse did. */
|
|
104
55
|
const VANISHED_EXIT_CODE = 1;
|
|
105
56
|
|
|
106
57
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
58
|
+
* Never lowers an exit code already set: a real test failure is the more
|
|
59
|
+
* informative verdict.
|
|
109
60
|
*
|
|
110
61
|
* @param {number} code
|
|
111
62
|
* @returns {void}
|
|
@@ -114,10 +65,7 @@ function raiseExitCode(code) {
|
|
|
114
65
|
if (!process.exitCode) process.exitCode = code;
|
|
115
66
|
}
|
|
116
67
|
|
|
117
|
-
/**
|
|
118
|
-
* Test-only: forget the per-process suite root without removing it, so a
|
|
119
|
-
* test can exercise the creation branch repeatedly in one process.
|
|
120
|
-
*/
|
|
68
|
+
/** Test-only: forget the suite root without removing it. */
|
|
121
69
|
export function _resetSuiteTempRootForTests() {
|
|
122
70
|
_suiteRoot = null;
|
|
123
71
|
_reaperRegistered = false;
|
|
@@ -125,12 +73,7 @@ export function _resetSuiteTempRootForTests() {
|
|
|
125
73
|
}
|
|
126
74
|
|
|
127
75
|
/**
|
|
128
|
-
* Report every root that vanished under this process
|
|
129
|
-
*
|
|
130
|
-
* Called from the exit reaper, so it is the last word on a run that
|
|
131
|
-
* otherwise passed. The exit code is only raised when nothing else already
|
|
132
|
-
* failed: a real test failure is the more informative verdict and must not
|
|
133
|
-
* be overwritten by this one.
|
|
76
|
+
* Report every root that vanished under this process and fail the run.
|
|
134
77
|
*
|
|
135
78
|
* @param {{ warn?: (msg: string) => void, setExitCode?: (code: number) => void }} [deps]
|
|
136
79
|
* @returns {void}
|
|
@@ -149,11 +92,8 @@ function reportVanishedRoots({
|
|
|
149
92
|
}
|
|
150
93
|
|
|
151
94
|
/**
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
* Test-only in spirit, but also the honest way for a failing fixture to say
|
|
155
|
-
* whether the root still exists when it reports a copy failure: asking
|
|
156
|
-
* {@link suiteTempRoot} would *create* one and destroy the evidence.
|
|
95
|
+
* The suite root this process owns, without minting one (asking
|
|
96
|
+
* {@link suiteTempRoot} would create one and destroy the evidence).
|
|
157
97
|
*
|
|
158
98
|
* @returns {string|null}
|
|
159
99
|
*/
|
|
@@ -162,16 +102,8 @@ export function _currentSuiteTempRoot() {
|
|
|
162
102
|
}
|
|
163
103
|
|
|
164
104
|
/**
|
|
165
|
-
* Remove this process's suite root
|
|
166
|
-
*
|
|
167
|
-
* A teardown failure is reported on stderr and swallowed — see
|
|
168
|
-
* {@link rmQuietly}.
|
|
169
|
-
*
|
|
170
|
-
* Only the process that minted the root can reach a non-null `_suiteRoot`,
|
|
171
|
-
* so this is creator-only by construction. It reads that variable *live*
|
|
172
|
-
* rather than a path captured at arming time, which is what keeps a root
|
|
173
|
-
* re-created mid-run (see {@link suiteTempRoot}) reapable and a root it has
|
|
174
|
-
* replaced unreachable — a stale path is never passed to `rmSync`.
|
|
105
|
+
* Remove this process's suite root. Creator-only by construction; reads
|
|
106
|
+
* `_suiteRoot` live so a re-minted root is reaped and a replaced one never is.
|
|
175
107
|
*
|
|
176
108
|
* @param {{ fsImpl?: typeof fs, warn?: (msg: string) => void }} [deps]
|
|
177
109
|
* @returns {string|null} the removed root, or `null` when there was none
|
|
@@ -185,29 +117,8 @@ export function reapSuiteTempRoot({ fsImpl = fs, warn = stderrWarn } = {}) {
|
|
|
185
117
|
}
|
|
186
118
|
|
|
187
119
|
/**
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
* The reaper is registered on `exit` at creation time, so a directory
|
|
191
|
-
* cannot exist without its teardown already armed — including when the
|
|
192
|
-
* suite fails, since a failing `node --test` run still exits normally.
|
|
193
|
-
*
|
|
194
|
-
* ## Why the memoised path is re-checked every call
|
|
195
|
-
*
|
|
196
|
-
* The root lives under a temp tree this process does not own exclusively
|
|
197
|
-
* (see the module docstring: a `/tmp` shared with self-hosted runners, an
|
|
198
|
-
* OS or operator pruner). Memoising the path without re-checking it made a
|
|
199
|
-
* single external removal terminal: every later `makeTempDir` in the
|
|
200
|
-
* process failed with an `ENOENT` naming an interior path, and with 204
|
|
201
|
-
* call sites reaching this helper one deletion cascaded through the rest
|
|
202
|
-
* of the file. Re-creating is strictly better than failing — nothing in
|
|
203
|
-
* the suite holds a handle to the root itself, only to directories minted
|
|
204
|
-
* beneath it, which the removal already took.
|
|
205
|
-
*
|
|
206
|
-
* The reaper armed at first use needs no re-arming: it reads `_suiteRoot`
|
|
207
|
-
* live, so it already covers whatever root this process owns at exit.
|
|
208
|
-
* Re-creation leaves the replaced path unreachable, so the creator-only
|
|
209
|
-
* invariant holds — this process still reaps only a root it minted, and
|
|
210
|
-
* never one it has replaced.
|
|
120
|
+
* Re-checked every call: one external prune must not cascade ENOENT through
|
|
121
|
+
* later `makeTempDir`s, and nothing holds a handle to the root itself.
|
|
211
122
|
*
|
|
212
123
|
* @param {{ fsImpl?: typeof fs, tmpdir?: () => string, onExit?: (fn: () => void) => void, warn?: (msg: string) => void, setExitCode?: (code: number) => void }} [deps]
|
|
213
124
|
* @returns {string} absolute path to the suite root
|
|
@@ -219,13 +130,6 @@ export function suiteTempRoot(deps = {}) {
|
|
|
219
130
|
}
|
|
220
131
|
|
|
221
132
|
/**
|
|
222
|
-
* Mint the process's suite root — the first one, or a replacement for one
|
|
223
|
-
* that disappeared underneath it — and arm the reaper if nothing has.
|
|
224
|
-
*
|
|
225
|
-
* Separate from {@link suiteTempRoot} so the hot path stays the single
|
|
226
|
-
* existence check callers pay on every `makeTempDir`, and the recovery it
|
|
227
|
-
* guards reads as the exceptional branch it is.
|
|
228
|
-
*
|
|
229
133
|
* @param {{ fsImpl?: typeof fs, tmpdir?: () => string, onExit?: (fn: () => void) => void, warn?: (msg: string) => void, setExitCode?: (code: number) => void }} deps
|
|
230
134
|
* @returns {string} absolute path to the new suite root
|
|
231
135
|
*/
|
|
@@ -238,12 +142,8 @@ function mintSuiteRoot({
|
|
|
238
142
|
} = {}) {
|
|
239
143
|
const vanished = _suiteRoot;
|
|
240
144
|
const base = tmpdir();
|
|
241
|
-
//
|
|
242
|
-
//
|
|
243
|
-
// process whose OS temp root had been removed silently re-created `/tmp`
|
|
244
|
-
// — with this process's umask rather than the sticky 1777 the system sets
|
|
245
|
-
// — and carried on. That is a broken machine reported as a passing suite;
|
|
246
|
-
// name it instead.
|
|
145
|
+
// Never re-create the OS temp root itself: it would get this process's
|
|
146
|
+
// umask instead of sticky 1777, hiding a broken machine behind a pass.
|
|
247
147
|
if (!fsImpl.existsSync(base))
|
|
248
148
|
throw new Error(
|
|
249
149
|
`[test-temp] OS temp root ${base} does not exist; refusing to create it. Something removed the system temp directory (or TMPDIR points at a path that was never created) — fix the environment rather than letting the suite mint it.`,
|
|
@@ -251,9 +151,6 @@ function mintSuiteRoot({
|
|
|
251
151
|
_suiteRoot = fsImpl.mkdtempSync(
|
|
252
152
|
path.join(base, `${SUITE_ROOT_PREFIX}${process.pid}-`),
|
|
253
153
|
);
|
|
254
|
-
// Say it once, loudly: this is the only trace that something outside the
|
|
255
|
-
// process touched the temp tree, and the incident it explains (#5272) was
|
|
256
|
-
// filed against the wrong mechanism for want of it.
|
|
257
154
|
if (vanished !== null) {
|
|
258
155
|
_vanishedRoots.push(vanished);
|
|
259
156
|
warn(`${VANISHED} ${vanished}; re-created as ${_suiteRoot}`);
|
|
@@ -269,18 +166,10 @@ function mintSuiteRoot({
|
|
|
269
166
|
}
|
|
270
167
|
|
|
271
168
|
/**
|
|
272
|
-
*
|
|
169
|
+
* Drop-in for `mkdtempSync(path.join(os.tmpdir(), prefix))`, nested in the
|
|
273
170
|
* suite root and reaped with it.
|
|
274
171
|
*
|
|
275
|
-
*
|
|
276
|
-
* path is absolute and unique, so call sites change only where the
|
|
277
|
-
* directory comes from, never how it is used.
|
|
278
|
-
*
|
|
279
|
-
* A vanished suite root is re-created by {@link suiteTempRoot} first, so
|
|
280
|
-
* this never fails with an `ENOENT` naming a directory the caller did not
|
|
281
|
-
* ask for.
|
|
282
|
-
*
|
|
283
|
-
* @param {string} [prefix='t-'] label kept for readability in a stack trace
|
|
172
|
+
* @param {string} [prefix='t-']
|
|
284
173
|
* @param {{ fsImpl?: typeof fs, tmpdir?: () => string, onExit?: (fn: () => void) => void, warn?: (msg: string) => void }} [deps]
|
|
285
174
|
* @returns {string} absolute path to the new directory
|
|
286
175
|
*/
|
|
@@ -291,16 +180,9 @@ export function makeTempDir(prefix = 't-', deps = {}) {
|
|
|
291
180
|
}
|
|
292
181
|
|
|
293
182
|
/**
|
|
294
|
-
* Register removal of
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
* mint a root *outside* the suite tree because children inherit its path
|
|
298
|
-
* through `MANDREL_TEST_TEMP_ROOT`. Call this only from the branch that
|
|
299
|
-
* actually minted the directory — a process that inherited the path must
|
|
300
|
-
* never reap it, or it deletes its parent's scratch mid-run.
|
|
301
|
-
*
|
|
302
|
-
* Teardown failures are swallowed for the same reason as
|
|
303
|
-
* {@link reapSuiteTempRoot} — see {@link rmQuietly}.
|
|
183
|
+
* Register removal of a scratch directory at exit, for seams that mint
|
|
184
|
+
* outside the suite tree. Call only from the branch that minted it — an
|
|
185
|
+
* inheriting process would delete its parent's scratch mid-run.
|
|
304
186
|
*
|
|
305
187
|
* @param {string} dirPath absolute path this process minted
|
|
306
188
|
* @param {{ fsImpl?: typeof fs, onExit?: (fn: () => void) => void, warn?: (msg: string) => void }} [deps]
|
|
@@ -318,11 +200,6 @@ export function reapOnExit(
|
|
|
318
200
|
}
|
|
319
201
|
|
|
320
202
|
/**
|
|
321
|
-
* List the suite roots currently present in `tmpDir`, sorted.
|
|
322
|
-
*
|
|
323
|
-
* Names only (not absolute paths) so the guard can diff them against a
|
|
324
|
-
* recorded snapshot without embedding the temp root's absolute location.
|
|
325
|
-
*
|
|
326
203
|
* @param {string} tmpDir
|
|
327
204
|
* @param {{ fsImpl?: typeof fs }} [deps]
|
|
328
205
|
* @returns {string[]}
|
|
@@ -339,12 +216,8 @@ export function listSuiteTempRoots(tmpDir, { fsImpl = fs } = {}) {
|
|
|
339
216
|
}
|
|
340
217
|
|
|
341
218
|
/**
|
|
342
|
-
* Suite roots
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
* Diffing against the snapshot rather than asserting an empty set is what
|
|
346
|
-
* keeps a concurrently-running suite (another checkout, another worktree)
|
|
347
|
-
* from failing this one.
|
|
219
|
+
* Suite roots created since the snapshot and still on disk. Diffing against
|
|
220
|
+
* the snapshot keeps a concurrent suite from failing this one.
|
|
348
221
|
*
|
|
349
222
|
* @param {string} tmpDir
|
|
350
223
|
* @param {string[]} snapshotRoots
|
|
@@ -357,31 +230,17 @@ export function survivingSuiteTempRoots(tmpDir, snapshotRoots, deps = {}) {
|
|
|
357
230
|
}
|
|
358
231
|
|
|
359
232
|
/**
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
* trying to balance parentheses, so it catches every shape in use:
|
|
363
|
-
* `mkdtempSync(path.join(os.tmpdir(), 'x-'))`, `mkdtempSync(join(tmpdir(),
|
|
364
|
-
* 'x-'))`, and `fs.mkdtempSync(...)`.
|
|
233
|
+
* A `mkdtemp`/`mkdtempSync` call whose argument reaches `tmpdir()`; spans the
|
|
234
|
+
* argument text instead of balancing parentheses.
|
|
365
235
|
*/
|
|
366
236
|
const RAW_TMPDIR_MKDTEMP =
|
|
367
237
|
/mkdtemp(?:Sync)?\s*\([^;\n]{0,200}?tmpdir\s*\(\s*\)/;
|
|
368
238
|
|
|
369
|
-
/**
|
|
370
|
-
* Opt-out marker for a line that must call `mkdtemp` against the real OS
|
|
371
|
-
* temp root — the guard's own tests, and the scratch seams that
|
|
372
|
-
* deliberately mint a root outside the suite tree.
|
|
373
|
-
*/
|
|
239
|
+
/** Opt-out marker for a line that must mint against the real OS temp root. */
|
|
374
240
|
const LINT_ESCAPE = 'test-temp-allow';
|
|
375
241
|
|
|
376
242
|
/**
|
|
377
|
-
*
|
|
378
|
-
* through {@link makeTempDir}.
|
|
379
|
-
*
|
|
380
|
-
* This is the half of the backstop that catches the *next* leaking file at
|
|
381
|
-
* authoring time rather than after it has already leaked, so it is scoped
|
|
382
|
-
* to explicitly-passed globs: `check-test-temp-hygiene.js` ships in the
|
|
383
|
-
* materialized `.agents/` payload, and a consumer's tests are none of this
|
|
384
|
-
* rule's business.
|
|
243
|
+
* Raw OS-temp mints outside {@link makeTempDir}, in explicit globs only.
|
|
385
244
|
*
|
|
386
245
|
* @param {string} repoRoot
|
|
387
246
|
* @param {string[]} globs repo-relative picomatch patterns
|
|
@@ -390,10 +249,8 @@ const LINT_ESCAPE = 'test-temp-allow';
|
|
|
390
249
|
*/
|
|
391
250
|
export function findRawTmpdirMkdtemp(repoRoot, globs, { fsImpl = fs } = {}) {
|
|
392
251
|
const patterns = (globs ?? []).filter(Boolean);
|
|
393
|
-
//
|
|
394
|
-
//
|
|
395
|
-
// positive "everything but a/b" matcher, which silently *widens* the
|
|
396
|
-
// scan instead of narrowing it.
|
|
252
|
+
// Split negations out: in a mixed picomatch array a `!` entry is its own
|
|
253
|
+
// positive matcher, which widens the scan instead of narrowing it.
|
|
397
254
|
const include = patterns.filter((p) => !p.startsWith('!'));
|
|
398
255
|
const exclude = patterns
|
|
399
256
|
.filter((p) => p.startsWith('!'))
|
|
@@ -418,11 +275,8 @@ export function findRawTmpdirMkdtemp(repoRoot, globs, { fsImpl = fs } = {}) {
|
|
|
418
275
|
}
|
|
419
276
|
|
|
420
277
|
/**
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
* directories (the `.agents/` payload carries `__tests__` trees) while
|
|
424
|
-
* still skipping the trees that are never source: `node_modules`,
|
|
425
|
-
* `.worktrees`, and `.git`.
|
|
278
|
+
* POSIX-relative JS sources under `root`; descends dot-directories (the
|
|
279
|
+
* `.agents/` payload has `__tests__`) but skips non-source trees.
|
|
426
280
|
*
|
|
427
281
|
* @param {string} root
|
|
428
282
|
* @param {typeof fs} fsImpl
|