mandrel 2.59.0 → 2.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/README.md +21 -19
- package/.agents/agents/acceptance-critic.md +24 -43
- package/.agents/agents/story-worker.md +20 -21
- package/.agents/docs/agentrc-reference.json +5 -84
- package/.agents/docs/configuration.md +48 -132
- package/.agents/docs/workflows.md +2 -2
- package/.agents/instructions.md +5 -8
- package/.agents/rules/ci-remediation.md +41 -8
- package/.agents/rules/gherkin-standards.md +4 -0
- package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
- package/.agents/schemas/agentrc.schema.json +16 -496
- package/.agents/schemas/story-deliver-terminal.schema.json +13 -3
- package/.agents/schemas/validation-evidence.schema.json +2 -1
- package/.agents/scripts/README.md +23 -13
- package/.agents/scripts/acceptance-eval.js +35 -169
- package/.agents/scripts/agents-bootstrap-github.js +27 -129
- package/.agents/scripts/apply-quality-bootstrap.js +4 -40
- package/.agents/scripts/audit-baselines.js +6 -27
- package/.agents/scripts/audit-labels-bootstrap.js +5 -29
- package/.agents/scripts/audit-to-stories.js +91 -361
- package/.agents/scripts/boot-sweep.js +19 -72
- package/.agents/scripts/bootstrap.js +74 -395
- package/.agents/scripts/ceremony-derive.js +10 -41
- package/.agents/scripts/check-arch-cycles.js +14 -64
- package/.agents/scripts/check-baselines.js +8 -48
- package/.agents/scripts/check-context-budget.js +105 -311
- package/.agents/scripts/check-cyclomatic.js +12 -44
- package/.agents/scripts/check-dead-exports.js +13 -64
- package/.agents/scripts/check-doc-links.js +38 -186
- package/.agents/scripts/check-gherkin-corpus.js +24 -127
- package/.agents/scripts/check-test-temp-hygiene.js +28 -169
- package/.agents/scripts/coverage-capture.js +34 -98
- package/.agents/scripts/deliver-light.js +25 -171
- package/.agents/scripts/deliver-recover.js +6 -42
- package/.agents/scripts/deliver-run.js +534 -0
- package/.agents/scripts/diagnose-friction.js +24 -116
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +23 -85
- package/.agents/scripts/file-ci-gap.js +57 -49
- package/.agents/scripts/generate-config-docs.js +30 -170
- package/.agents/scripts/generate-lens-checklists.js +8 -52
- package/.agents/scripts/generate-skills-index.js +14 -112
- package/.agents/scripts/generate-workflows-doc.js +10 -70
- package/.agents/scripts/git-cleanup.js +2 -34
- package/.agents/scripts/lib/Graph.js +24 -81
- package/.agents/scripts/lib/ITicketingProvider.js +47 -143
- package/.agents/scripts/lib/Logger.js +14 -76
- package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
- package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
- package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
- package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
- package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
- package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
- package/.agents/scripts/lib/audit-baselines/read.js +3 -16
- package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
- package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
- package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
- package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
- package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
- package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
- package/.agents/scripts/lib/audit-suite/findings.js +12 -52
- package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
- package/.agents/scripts/lib/audit-suite/index.js +1 -15
- package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
- package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
- package/.agents/scripts/lib/audit-suite/runner.js +13 -43
- package/.agents/scripts/lib/audit-suite/selector.js +49 -349
- package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
- package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
- package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
- package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
- package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
- package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
- package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
- package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
- package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
- package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
- package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
- package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
- package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
- package/.agents/scripts/lib/baseline-loader.js +12 -51
- package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
- package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
- package/.agents/scripts/lib/baselines/components.js +10 -61
- package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
- package/.agents/scripts/lib/baselines/crap-preview-incremental.js +7 -19
- package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
- package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
- package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
- package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
- package/.agents/scripts/lib/baselines/envelope.js +13 -129
- package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
- package/.agents/scripts/lib/baselines/git-base.js +23 -142
- package/.agents/scripts/lib/baselines/kernel.js +11 -111
- package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
- package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
- package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
- package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
- package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
- package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
- package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
- package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
- package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
- package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
- package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
- package/.agents/scripts/lib/baselines/path-canon.js +19 -128
- package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
- package/.agents/scripts/lib/baselines/reader.js +14 -107
- package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
- package/.agents/scripts/lib/baselines/scope.js +11 -135
- package/.agents/scripts/lib/baselines/writer.js +16 -149
- package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
- package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
- package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
- package/.agents/scripts/lib/bdd-step-index.js +26 -100
- package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
- package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
- package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
- package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
- package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
- package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
- package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
- package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
- package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
- package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
- package/.agents/scripts/lib/bootstrap/summary.js +1 -8
- package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
- package/.agents/scripts/lib/branch-name-guard.js +4 -23
- package/.agents/scripts/lib/changed-files.js +39 -121
- package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
- package/.agents/scripts/lib/checks/index.js +18 -101
- package/.agents/scripts/lib/checks/loop-health.js +11 -53
- package/.agents/scripts/lib/checks/state.js +16 -91
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
- package/.agents/scripts/lib/child-exec.js +39 -108
- package/.agents/scripts/lib/cli/standard-args.js +9 -116
- package/.agents/scripts/lib/cli-args.js +31 -146
- package/.agents/scripts/lib/cli-usage.js +5 -27
- package/.agents/scripts/lib/cli-utils.js +2 -12
- package/.agents/scripts/lib/close-validation/commands.js +13 -76
- package/.agents/scripts/lib/close-validation/gates.js +92 -331
- package/.agents/scripts/lib/close-validation/process.js +121 -151
- package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
- package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
- package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
- package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
- package/.agents/scripts/lib/close-validation/runner.js +53 -110
- package/.agents/scripts/lib/command-header.js +6 -28
- package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
- package/.agents/scripts/lib/config/baselines.js +3 -14
- package/.agents/scripts/lib/config/ci.js +8 -38
- package/.agents/scripts/lib/config/commands.js +1 -15
- package/.agents/scripts/lib/config/defaults.js +4 -33
- package/.agents/scripts/lib/config/delivery-routing.js +6 -34
- package/.agents/scripts/lib/config/explain.js +10 -83
- package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +3 -31
- package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
- package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
- package/.agents/scripts/lib/config/gates/index.js +2 -17
- package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
- package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
- package/.agents/scripts/lib/config/gates/shared.js +4 -64
- package/.agents/scripts/lib/config/github.js +4 -22
- package/.agents/scripts/lib/config/limits.js +4 -57
- package/.agents/scripts/lib/config/paths.js +2 -21
- package/.agents/scripts/lib/config/qa.js +4 -38
- package/.agents/scripts/lib/config/quality.js +76 -432
- package/.agents/scripts/lib/config/runners.js +12 -56
- package/.agents/scripts/lib/config/runtime.js +13 -57
- package/.agents/scripts/lib/config/shared.js +2 -16
- package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
- package/.agents/scripts/lib/config/temp-paths.js +40 -280
- package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
- package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
- package/.agents/scripts/lib/config-resolver.js +11 -52
- package/.agents/scripts/lib/config-schema-shared.js +1 -4
- package/.agents/scripts/lib/config-settings-schema-delivery.js +16 -291
- package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
- package/.agents/scripts/lib/config-settings-schema.js +37 -274
- package/.agents/scripts/lib/coverage-baseline.js +20 -110
- package/.agents/scripts/lib/coverage-capture-fullscope.js +18 -35
- package/.agents/scripts/lib/coverage-capture-incremental.js +15 -45
- package/.agents/scripts/lib/coverage-capture-usage.js +8 -25
- package/.agents/scripts/lib/coverage-capture.js +99 -224
- package/.agents/scripts/lib/coverage-utils.js +14 -79
- package/.agents/scripts/lib/cpu-pool.js +17 -123
- package/.agents/scripts/lib/crap-baseline-join.js +16 -88
- package/.agents/scripts/lib/crap-coordinates.js +6 -25
- package/.agents/scripts/lib/crap-engine.js +40 -153
- package/.agents/scripts/lib/crap-method-identity.js +16 -78
- package/.agents/scripts/lib/crap-utils.js +31 -155
- package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
- package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
- package/.agents/scripts/lib/dead-exports-knip.js +18 -56
- package/.agents/scripts/lib/dead-exports-mode.js +5 -24
- package/.agents/scripts/lib/degraded-mode.js +3 -26
- package/.agents/scripts/lib/dependency-parser.js +8 -40
- package/.agents/scripts/lib/dependency-version.js +13 -35
- package/.agents/scripts/lib/detect-package-manager.js +6 -36
- package/.agents/scripts/lib/doc-tiers.js +22 -124
- package/.agents/scripts/lib/duplicate-search.js +8 -72
- package/.agents/scripts/lib/env-loader.js +5 -27
- package/.agents/scripts/lib/error-redactor.js +6 -31
- package/.agents/scripts/lib/errors/index.js +2 -22
- package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
- package/.agents/scripts/lib/escomplex-kernel.js +21 -123
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +94 -419
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -149
- package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
- package/.agents/scripts/lib/findings/classify-finding.js +14 -69
- package/.agents/scripts/lib/findings/promote-finding.js +14 -112
- package/.agents/scripts/lib/findings/provenance-field.js +11 -52
- package/.agents/scripts/lib/findings/route-finding.js +37 -255
- package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
- package/.agents/scripts/lib/findings/severity.js +18 -104
- package/.agents/scripts/lib/format-generated-json.js +12 -44
- package/.agents/scripts/lib/full-suite-lock.js +160 -429
- package/.agents/scripts/lib/full-suite-queue.js +213 -0
- package/.agents/scripts/lib/gates/baseline-store.js +5 -9
- package/.agents/scripts/lib/gates/friction.js +1 -3
- package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
- package/.agents/scripts/lib/gh-exec.js +123 -191
- package/.agents/scripts/lib/git/cached-fetch.js +9 -52
- package/.agents/scripts/lib/git/sync-from-base.js +15 -107
- package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
- package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
- package/.agents/scripts/lib/git-utils.js +37 -161
- package/.agents/scripts/lib/github/framework-repo.js +8 -71
- package/.agents/scripts/lib/github-url.js +2 -17
- package/.agents/scripts/lib/import-graph.js +11 -38
- package/.agents/scripts/lib/install-cmd-parser.js +4 -13
- package/.agents/scripts/lib/json-utils.js +3 -18
- package/.agents/scripts/lib/label-constants.js +16 -111
- package/.agents/scripts/lib/label-taxonomy.js +4 -30
- package/.agents/scripts/lib/maintainability-engine.js +12 -80
- package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
- package/.agents/scripts/lib/maintainability-utils.js +16 -92
- package/.agents/scripts/lib/mandrel-catalog.js +12 -70
- package/.agents/scripts/lib/notifications/notifier.js +13 -38
- package/.agents/scripts/lib/npm-scripts.js +4 -23
- package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
- package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
- package/.agents/scripts/lib/observability/signal-validator.js +5 -37
- package/.agents/scripts/lib/observability/signals-writer.js +11 -121
- package/.agents/scripts/lib/observability/source-classifier.js +22 -203
- package/.agents/scripts/lib/observability/terse-result.js +14 -47
- package/.agents/scripts/lib/onboard/init-tail.js +13 -74
- package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
- package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
- package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +28 -156
- package/.agents/scripts/lib/orchestration/change-set.js +7 -36
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
- package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
- package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
- package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
- package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
- package/.agents/scripts/lib/orchestration/check-state.js +92 -0
- package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +121 -157
- package/.agents/scripts/lib/orchestration/code-review.js +24 -128
- package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
- package/.agents/scripts/lib/orchestration/complexity-gate.js +118 -462
- package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
- package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
- package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
- package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
- package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
- package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
- package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
- package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
- package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
- package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
- package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
- package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
- package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
- package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
- package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
- package/.agents/scripts/lib/orchestration/light-suitability.js +37 -307
- package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
- package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
- package/.agents/scripts/lib/orchestration/plan-context.js +55 -318
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
- package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
- package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
- package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
- package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
- package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +16 -78
- package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
- package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
- package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
- package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +71 -289
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +96 -362
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +9 -39
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +60 -186
- package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
- package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
- package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
- package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
- package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
- package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
- package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
- package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
- package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
- package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
- package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
- package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
- package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
- package/.agents/scripts/lib/orchestration/review-depth.js +12 -91
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
- package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
- package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
- package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
- package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
- package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
- package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
- package/.agents/scripts/lib/orchestration/run-epilogue.js +245 -326
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +55 -159
- package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
- package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
- package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +20 -82
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +136 -486
- package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
- package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +96 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +180 -273
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
- package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
- package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
- package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
- package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -200
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +167 -252
- package/.agents/scripts/lib/orchestration/story-init-envelope.js +52 -0
- package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
- package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
- package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -135
- package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
- package/.agents/scripts/lib/orchestration/ticket-validator.js +63 -344
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -261
- package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
- package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
- package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
- package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
- package/.agents/scripts/lib/path-security.js +3 -6
- package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
- package/.agents/scripts/lib/preflight-runner.js +13 -69
- package/.agents/scripts/lib/process-group.js +143 -0
- package/.agents/scripts/lib/project-root.js +2 -8
- package/.agents/scripts/lib/provider-factory.js +2 -25
- package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
- package/.agents/scripts/lib/qa/qa-session.js +15 -69
- package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
- package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
- package/.agents/scripts/lib/reserved-test-ids.js +9 -47
- package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
- package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
- package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
- package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
- package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
- package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
- package/.agents/scripts/lib/signals/detectors/common.js +12 -38
- package/.agents/scripts/lib/signals/index.js +2 -19
- package/.agents/scripts/lib/signals/schema.js +14 -109
- package/.agents/scripts/lib/signals/write.js +2 -11
- package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
- package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
- package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
- package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
- package/.agents/scripts/lib/single-story-sweep.js +14 -97
- package/.agents/scripts/lib/skills/parse-skill.js +13 -59
- package/.agents/scripts/lib/skills/skills-index.js +8 -29
- package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
- package/.agents/scripts/lib/source-extensions.js +11 -42
- package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
- package/.agents/scripts/lib/stdio-flush.js +9 -36
- package/.agents/scripts/lib/story-adjacency.js +8 -40
- package/.agents/scripts/lib/story-body/body-format-lints.js +51 -66
- package/.agents/scripts/lib/story-body/footer-block.js +11 -44
- package/.agents/scripts/lib/story-body/story-body.js +123 -344
- package/.agents/scripts/lib/temp-retention.js +42 -143
- package/.agents/scripts/lib/templates/decomposer-prompts.js +18 -80
- package/.agents/scripts/lib/test-env.js +12 -65
- package/.agents/scripts/lib/test-run-credit.js +10 -65
- package/.agents/scripts/lib/test-runner-contract.js +19 -74
- package/.agents/scripts/lib/test-temp.js +38 -184
- package/.agents/scripts/lib/test-tiers.js +12 -96
- package/.agents/scripts/lib/ticket-body-sections.js +21 -96
- package/.agents/scripts/lib/transpile.js +15 -74
- package/.agents/scripts/lib/util/concurrent-map.js +6 -25
- package/.agents/scripts/lib/util/parse-id-list.js +8 -34
- package/.agents/scripts/lib/util/poll-loop.js +8 -28
- package/.agents/scripts/lib/util/with-timeout.js +2 -11
- package/.agents/scripts/lib/validation-evidence.js +21 -96
- package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
- package/.agents/scripts/lib/wave-runner/live-probe.js +67 -209
- package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
- package/.agents/scripts/lib/workers/crap-worker.js +11 -64
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
- package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
- package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
- package/.agents/scripts/lib/workflow-closure.js +22 -105
- package/.agents/scripts/lib/workspace-provisioner.js +16 -54
- package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
- package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
- package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
- package/.agents/scripts/lib/worktree-manager.js +15 -40
- package/.agents/scripts/lint-issue-body.js +12 -68
- package/.agents/scripts/mandrel-update-preflight.js +10 -70
- package/.agents/scripts/merge-baseline.js +30 -105
- package/.agents/scripts/nav-registry-diff.js +22 -108
- package/.agents/scripts/notify.js +12 -69
- package/.agents/scripts/plan-context.js +97 -92
- package/.agents/scripts/plan-critics.js +12 -66
- package/.agents/scripts/plan-persist.js +71 -137
- package/.agents/scripts/plan-run-epilogue.js +20 -43
- package/.agents/scripts/pr-watch-with-update.js +79 -263
- package/.agents/scripts/providers/github/auth.js +3 -8
- package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
- package/.agents/scripts/providers/github/board-add.js +5 -21
- package/.agents/scripts/providers/github/branch-protection.js +11 -43
- package/.agents/scripts/providers/github/cache.js +2 -14
- package/.agents/scripts/providers/github/comments.js +7 -40
- package/.agents/scripts/providers/github/compose.js +3 -19
- package/.agents/scripts/providers/github/errors.js +22 -125
- package/.agents/scripts/providers/github/issues.js +31 -123
- package/.agents/scripts/providers/github/labels.js +24 -124
- package/.agents/scripts/providers/github/mappers.js +5 -27
- package/.agents/scripts/providers/github/merge-methods.js +3 -22
- package/.agents/scripts/providers/github/project-board.js +2 -17
- package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
- package/.agents/scripts/providers/github/request-helpers.js +5 -32
- package/.agents/scripts/providers/github/search-budget.js +9 -39
- package/.agents/scripts/providers/github/search-query.js +5 -26
- package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
- package/.agents/scripts/providers/github/sub-issues.js +7 -36
- package/.agents/scripts/providers/github/tickets.js +32 -134
- package/.agents/scripts/providers/github.js +18 -59
- package/.agents/scripts/prune-plan-run-labels.js +12 -46
- package/.agents/scripts/quality-preview.js +35 -220
- package/.agents/scripts/resolve-doc-tiers.js +3 -26
- package/.agents/scripts/resolve-stories.js +16 -67
- package/.agents/scripts/resync-status-column.js +6 -25
- package/.agents/scripts/run-tests.js +29 -104
- package/.agents/scripts/single-story-close.js +23 -135
- package/.agents/scripts/single-story-confirm-merge.js +32 -139
- package/.agents/scripts/single-story-init.js +47 -259
- package/.agents/scripts/stories-wave-tick.js +179 -415
- package/.agents/scripts/sync-agentrc.js +3 -21
- package/.agents/scripts/sync-claude-agents.js +9 -55
- package/.agents/scripts/sync-claude-commands.js +20 -110
- package/.agents/scripts/test-wrapper.js +6 -43
- package/.agents/scripts/update-coverage-baseline.js +5 -22
- package/.agents/scripts/update-crap-baseline.js +7 -30
- package/.agents/scripts/update-duplication-baseline.js +16 -92
- package/.agents/scripts/update-maintainability-baseline.js +8 -62
- package/.agents/scripts/update-ticket-state.js +1 -7
- package/.agents/scripts/validate-skills.js +6 -26
- package/.agents/skills/core/gates-and-baselines/reference.md +0 -1
- package/.agents/skills/skills.index.json +2 -2
- package/.agents/skills/stack/qa/playwright/SKILL.md +26 -0
- package/.agents/templates/agent-protocol.md +2 -2
- package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
- package/.agents/workflows/audit-accessibility.md +4 -7
- package/.agents/workflows/audit-adrs.md +3 -6
- package/.agents/workflows/audit-architecture.md +3 -11
- package/.agents/workflows/audit-baselines.md +6 -9
- package/.agents/workflows/audit-clean-code.md +8 -12
- package/.agents/workflows/audit-data-model.md +3 -7
- package/.agents/workflows/audit-dependencies.md +4 -7
- package/.agents/workflows/audit-devops.md +4 -8
- package/.agents/workflows/audit-documentation.md +1 -4
- package/.agents/workflows/audit-mobile.md +4 -7
- package/.agents/workflows/audit-navigability.md +3 -6
- package/.agents/workflows/audit-performance.md +2 -4
- package/.agents/workflows/audit-privacy.md +4 -7
- package/.agents/workflows/audit-quality.md +4 -7
- package/.agents/workflows/audit-security.md +4 -7
- package/.agents/workflows/audit-seo.md +4 -7
- package/.agents/workflows/audit-sre.md +4 -7
- package/.agents/workflows/audit-to-stories.md +17 -30
- package/.agents/workflows/audit-ux-ui.md +4 -7
- package/.agents/workflows/helpers/acceptance-self-eval.md +84 -157
- package/.agents/workflows/helpers/audit-lens-core.md +1 -1
- package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
- package/.agents/workflows/helpers/code-review.md +4 -2
- package/.agents/workflows/helpers/deliver-digest.md +37 -28
- package/.agents/workflows/helpers/deliver-light.md +92 -101
- package/.agents/workflows/helpers/deliver-reference.md +162 -220
- package/.agents/workflows/helpers/deliver-story-reference.md +197 -607
- package/.agents/workflows/helpers/deliver-story.md +17 -18
- package/.agents/workflows/helpers/plan-reference.md +125 -167
- package/.agents/workflows/helpers/qa-core.md +12 -0
- package/.agents/workflows/mandrel-deliver.md +47 -31
- package/.agents/workflows/mandrel-plan.md +22 -21
- package/.agents/workflows/mandrel-update.md +36 -21
- package/.agents/workflows/memory-consolidate.md +1 -1
- package/.agents/workflows/qa-assist.md +27 -71
- package/.agents/workflows/qa-explore.md +19 -59
- package/.agents/workflows/qa-run.md +11 -33
- package/README.md +1 -1
- package/bin/mandrel.js +5 -46
- package/bin/postinstall.js +18 -107
- package/docs/CHANGELOG.md +60 -0
- package/lib/cli/doctor.js +11 -71
- package/lib/cli/init.js +26 -165
- package/lib/cli/migrate.js +5 -64
- package/lib/cli/registry.js +84 -467
- package/lib/cli/sync-agents.js +4 -64
- package/lib/cli/sync-commands.js +11 -64
- package/lib/cli/sync.js +34 -213
- package/lib/cli/uninstall.js +40 -219
- package/lib/cli/update.js +326 -523
- package/lib/cli/version-check.js +8 -72
- package/lib/cli/version-helpers.js +14 -87
- package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
- package/lib/migrations/index.js +17 -92
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
- package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
- package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
- package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
- package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
- package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
- package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
- package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +21 -0
- package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
- package/package.json +17 -14
- package/.agents/docs/SDLC.md +0 -590
- package/.agents/docs/quality-gates.md +0 -1179
- package/.agents/rules/known-tooling-behavior.md +0 -150
- package/.agents/rules/orchestration-error-handling.md +0 -61
- package/.agents/rules/test-seams.md +0 -59
- package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
- package/.agents/schemas/baselines/lint.schema.json +0 -47
- package/.agents/schemas/model-attribution.schema.json +0 -53
- package/.agents/scripts/check-action-pinning.js +0 -260
- package/.agents/scripts/check-audit-attribution.js +0 -302
- package/.agents/scripts/check-baseline-drift.js +0 -211
- package/.agents/scripts/check-baseline-scope.js +0 -362
- package/.agents/scripts/check-generated-validator.js +0 -202
- package/.agents/scripts/check-knip-entries.js +0 -159
- package/.agents/scripts/check-lifecycle-lint.js +0 -294
- package/.agents/scripts/check-pinned-override-notes.js +0 -102
- package/.agents/scripts/check-schema-references.js +0 -366
- package/.agents/scripts/check-test-portability.js +0 -512
- package/.agents/scripts/check-workflow-citations.js +0 -332
- package/.agents/scripts/check-workflow-cli-lint.js +0 -299
- package/.agents/scripts/check-workflow-timeouts.js +0 -291
- package/.agents/scripts/install-matrix-assert.js +0 -326
- package/.agents/scripts/lib/audit-advisories.js +0 -195
- package/.agents/scripts/lib/audit-attribution.js +0 -134
- package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
- package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
- package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
- package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
- package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
- package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
- package/.agents/scripts/lib/c8-cli-path.js +0 -21
- package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
- package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
- package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
- package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
- package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
- package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
- package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
- package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
- package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
- package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
- package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
- package/.agents/scripts/lib/fs-walk.js +0 -52
- package/.agents/scripts/lib/knip-config-resolver.js +0 -181
- package/.agents/scripts/lib/knip-entry-sync.js +0 -452
- package/.agents/scripts/lib/orchestration/model-attribution.js +0 -418
- package/.agents/scripts/lib/orchestration/story-plan-state.js +0 -33
- package/.agents/scripts/lib/orchestration/structured-comment-parser.js +0 -67
- package/.agents/scripts/lib/pinned-override-notes.js +0 -88
- package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
- package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
- package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
- package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
- package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
- package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
- package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
- package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
- package/.agents/scripts/lib/test-isolate/runner.js +0 -483
- package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
- package/.agents/scripts/lib/test-profile/render-report.js +0 -45
- package/.agents/scripts/lint-label-vocabulary.js +0 -214
- package/.agents/scripts/post-structured-comment.js +0 -127
- package/.agents/scripts/provision-git-hooks.js +0 -85
- package/.agents/scripts/prune-baseline-orphans.js +0 -181
- package/.agents/scripts/run-coverage.js +0 -197
- package/.agents/scripts/run-lint.js +0 -133
- package/.agents/scripts/run-test-profile.js +0 -129
- package/.agents/scripts/run-verify.js +0 -118
- package/.agents/scripts/test-isolate.js +0 -55
- package/.agents/scripts/update-dead-exports-baseline.js +0 -321
|
@@ -1,24 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* full-suite run the worker makes just before the hand-off push
|
|
7
|
-
* (`helpers/deliver-digest.md` § 5). When a `verify[]` entry is itself a
|
|
8
|
-
* full-suite command, running it spends a second whole-suite spawn for a
|
|
9
|
-
* result the credited run already established — and the close gate chain then
|
|
10
|
-
* makes a third. This module is the read side of that credit: given the
|
|
11
|
-
* entry's command it consults **the same stamp close consults** and reports
|
|
12
|
-
* the entry as credited instead of telling the caller to spawn it.
|
|
13
|
-
*
|
|
14
|
-
* It only ever *reads*. Nothing here writes a capture stamp or an evidence
|
|
15
|
-
* record — an entry that is not covered by a fresh stamp or a credited
|
|
16
|
-
* `test` evidence record (Story #5313: a green bare `npm test` deposits one)
|
|
17
|
-
* is reported `spawn: true` and runs for real, so the credit can never
|
|
18
|
-
* manufacture a pass.
|
|
19
|
-
*
|
|
20
|
-
* @see .agents/scripts/lib/coverage-capture.js (`isCoverageFresh`)
|
|
21
|
-
* @see .agents/scripts/lib/validation-evidence.js (`shouldSkip`)
|
|
2
|
+
* Report a full-suite `verify[]` entry as credited when the stamp or `test`
|
|
3
|
+
* evidence close consults already covers it, instead of respawning the suite.
|
|
4
|
+
* Read-only: an uncovered entry is `spawn: true`, so credit never
|
|
5
|
+
* manufactures a pass.
|
|
22
6
|
*/
|
|
23
7
|
|
|
24
8
|
import { getQuality, resolveConfig } from '../config-resolver.js';
|
|
@@ -31,34 +15,17 @@ import {
|
|
|
31
15
|
treeFingerprint,
|
|
32
16
|
} from '../validation-evidence.js';
|
|
33
17
|
|
|
34
|
-
/**
|
|
35
|
-
* The shape a `verify[]` array is supposed to have, stated once so the
|
|
36
|
-
* warning a caller surfaces and the prose in `deliver-digest.md` § 5 say the
|
|
37
|
-
* same thing.
|
|
38
|
-
* @type {string}
|
|
39
|
-
*/
|
|
18
|
+
/** @type {string} */
|
|
40
19
|
export const FULL_SUITE_SHAPE_WARNING =
|
|
41
20
|
'verify[] should be scoped entries plus the single credited full-suite run ' +
|
|
42
21
|
'(deliver-digest.md § 5) — a full-suite command listed in verify[] is ' +
|
|
43
22
|
'reported credited against that run, never respawned.';
|
|
44
23
|
|
|
45
|
-
/** Package managers whose `test` script means "the whole suite". */
|
|
46
24
|
const PACKAGE_MANAGERS = new Set(['npm', 'pnpm', 'yarn', 'bun']);
|
|
47
25
|
|
|
48
|
-
/** Script names that mean "the whole suite" rather than a scoped subset. */
|
|
49
26
|
const FULL_SUITE_SCRIPTS = new Set(['test', 'test:coverage']);
|
|
50
27
|
|
|
51
|
-
/**
|
|
52
|
-
* Flags that narrow a runner's work to a subset of the suite (Story #5278).
|
|
53
|
-
*
|
|
54
|
-
* A positional path is not the only way to scope a run: Node's test runner
|
|
55
|
-
* takes filter flags that select a fraction of the tests while the argv still
|
|
56
|
-
* reads as a bare `node --test`. Crediting one of those against the full-suite
|
|
57
|
-
* stamp reports a filtered run as the whole suite — the exact false positive
|
|
58
|
-
* {@link isFullSuiteCommand} exists to refuse. Matched by prefix so both
|
|
59
|
-
* spellings (`--test-only`, `--test-name-pattern=x`, `--test-name-pattern x`)
|
|
60
|
-
* are caught.
|
|
61
|
-
*/
|
|
28
|
+
/** Filter flags that scope a bare-looking `node --test`; `=value` form too. */
|
|
62
29
|
const NARROWING_FLAGS = Object.freeze([
|
|
63
30
|
'--test-name-pattern',
|
|
64
31
|
'--test-skip-pattern',
|
|
@@ -66,10 +33,6 @@ const NARROWING_FLAGS = Object.freeze([
|
|
|
66
33
|
]);
|
|
67
34
|
|
|
68
35
|
/**
|
|
69
|
-
* Does any token narrow the run to a subset of the suite? Pure helper for
|
|
70
|
-
* {@link isFullSuiteCommand}, split out so that function's own branching stays
|
|
71
|
-
* inside its committed cyclomatic budget.
|
|
72
|
-
*
|
|
73
36
|
* @param {string[]} tokens
|
|
74
37
|
* @returns {boolean}
|
|
75
38
|
*/
|
|
@@ -82,11 +45,8 @@ function hasNarrowingFlag(tokens) {
|
|
|
82
45
|
}
|
|
83
46
|
|
|
84
47
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* Story bodies write entries as `` `<command>` (<tier>) `` — the tier is
|
|
88
|
-
* planning metadata, not part of the command, and leaving it attached would
|
|
89
|
-
* make every entry look scoped.
|
|
48
|
+
* Strip a trailing `(<tier>)` tag, which would otherwise make every entry
|
|
49
|
+
* look scoped.
|
|
90
50
|
*
|
|
91
51
|
* @param {string} entry
|
|
92
52
|
* @returns {{ command: string, tier: string|null }}
|
|
@@ -99,12 +59,8 @@ export function parseVerifyEntry(entry) {
|
|
|
99
59
|
}
|
|
100
60
|
|
|
101
61
|
/**
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* Deliberately narrow. A false positive here would report a *scoped* command
|
|
105
|
-
* as credited without ever running it, which is how a gate stops gating — so
|
|
106
|
-
* anything carrying its own positional argument (`npm test -- tests/x.js`,
|
|
107
|
-
* `node --test tests/x.js`) is scoped by construction.
|
|
62
|
+
* Deliberately narrow: a false positive credits a scoped command without
|
|
63
|
+
* running it. Any positional argument or narrowing flag means scoped.
|
|
108
64
|
*
|
|
109
65
|
* @param {string} command
|
|
110
66
|
* @returns {boolean}
|
|
@@ -115,13 +71,9 @@ export function isFullSuiteCommand(command) {
|
|
|
115
71
|
.split(/\s+/)
|
|
116
72
|
.filter(Boolean);
|
|
117
73
|
if (tokens.length === 0) return false;
|
|
118
|
-
// A narrowing flag scopes the run wherever it appears — before the package
|
|
119
|
-
// manager's `--` as much as after it — so the probe runs over the whole
|
|
120
|
-
// token list rather than per-branch below.
|
|
121
74
|
if (hasNarrowingFlag(tokens)) return false;
|
|
122
75
|
|
|
123
76
|
if (tokens[0] === 'node') {
|
|
124
|
-
// `node --test` with no path argument walks the default test globs.
|
|
125
77
|
const rest = tokens.slice(1);
|
|
126
78
|
return rest.length > 0 && rest.every((t) => t.startsWith('-'));
|
|
127
79
|
}
|
|
@@ -129,14 +81,10 @@ export function isFullSuiteCommand(command) {
|
|
|
129
81
|
if (!PACKAGE_MANAGERS.has(tokens[0])) return false;
|
|
130
82
|
const rest = tokens[1] === 'run' ? tokens.slice(2) : tokens.slice(1);
|
|
131
83
|
if (rest.length === 0 || !FULL_SUITE_SCRIPTS.has(rest[0])) return false;
|
|
132
|
-
// `npm test -- <path>` narrows the run; only a bare invocation is the suite.
|
|
133
84
|
return rest.length === 1;
|
|
134
85
|
}
|
|
135
86
|
|
|
136
87
|
/**
|
|
137
|
-
* Read HEAD from a worktree. `null` when the tree cannot be read — which
|
|
138
|
-
* routes to `spawn`, never to a credit.
|
|
139
|
-
*
|
|
140
88
|
* @param {string} cwd
|
|
141
89
|
* @param {Function} gitSpawnFn
|
|
142
90
|
* @returns {string|null}
|
|
@@ -149,15 +97,12 @@ function readHeadSha(cwd, gitSpawnFn) {
|
|
|
149
97
|
}
|
|
150
98
|
|
|
151
99
|
/**
|
|
152
|
-
* Decide how a single `verify[]` entry should be executed.
|
|
153
|
-
*
|
|
154
100
|
* @param {object} input
|
|
155
|
-
* @param {string} input.command —
|
|
101
|
+
* @param {string} input.command — tier tag already off.
|
|
156
102
|
* @param {number|string} input.storyId
|
|
157
|
-
* @param {string} input.worktree — ABSOLUTE path
|
|
158
|
-
* @param {string} [input.cwd] —
|
|
159
|
-
*
|
|
160
|
-
* @param {object} [deps] — test seams; every one defaults to the real impl.
|
|
103
|
+
* @param {string} input.worktree — ABSOLUTE path.
|
|
104
|
+
* @param {string} [input.cwd] — evidence keyspace root; defaults to `worktree`.
|
|
105
|
+
* @param {object} [deps] — test seams.
|
|
161
106
|
* @returns {{
|
|
162
107
|
* command: string, fullSuite: boolean, credited: boolean, spawn: boolean,
|
|
163
108
|
* mode: 'capture'|'evidence'|null, reason: string, warning: string|null
|
|
@@ -215,10 +160,8 @@ export function resolveVerifyCredit(
|
|
|
215
160
|
stampReason = freshness?.reason ?? 'unknown';
|
|
216
161
|
}
|
|
217
162
|
|
|
218
|
-
//
|
|
219
|
-
//
|
|
220
|
-
// the evidence keyspace is consulted in both modes before spawning. When it
|
|
221
|
-
// credits nothing either, capture mode reports the stamp's own reason.
|
|
163
|
+
// A stale stamp is not the last word: a green `npm test` deposits `test`
|
|
164
|
+
// evidence, consulted in both modes before spawning.
|
|
222
165
|
const verdict = readTestEvidence({
|
|
223
166
|
storyId,
|
|
224
167
|
worktree,
|
|
@@ -239,9 +182,7 @@ export function resolveVerifyCredit(
|
|
|
239
182
|
}
|
|
240
183
|
|
|
241
184
|
/**
|
|
242
|
-
*
|
|
243
|
-
* green bare `npm test` deposits (Story #5313) and `evidence-gate.js` wrote
|
|
244
|
-
* before it. Total: an unreadable HEAD is `no-head`, never a credit.
|
|
185
|
+
* An unreadable HEAD is `no-head`, never a credit.
|
|
245
186
|
*
|
|
246
187
|
* @param {{ storyId: number|string, worktree: string, cwd: string, gitSpawnFn: Function, shouldSkipImpl: Function, hashCommandConfigImpl: Function, treeFingerprintImpl: Function }} args
|
|
247
188
|
* @returns {{ skip: boolean, reason: string }}
|
|
@@ -274,9 +215,7 @@ function readTestEvidence({
|
|
|
274
215
|
}
|
|
275
216
|
|
|
276
217
|
/**
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
* @param {string[]} entries — raw `verify[]` lines, tier tags included.
|
|
218
|
+
* @param {string[]} entries — raw lines, tier tags included.
|
|
280
219
|
* @param {{ storyId: number|string, worktree: string, cwd?: string }} context
|
|
281
220
|
* @param {object} [deps]
|
|
282
221
|
* @returns {Array<ReturnType<typeof resolveVerifyCredit> & { tier: string|null }>}
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* uncommitted changes?" (Story #5238).
|
|
4
|
-
*
|
|
5
|
-
* Its own module because the light path's diff backstop is otherwise a pure
|
|
6
|
-
* join over two committed-state git reads, and this is the one question there
|
|
7
|
-
* that needs a third read of a *working tree*. Keeping it here leaves
|
|
8
|
-
* {@link module:lib/orchestration/light-backstop} the thin join it claims to
|
|
9
|
-
* be, and gives the probe its own place to be tested against every way a git
|
|
10
|
-
* read can fail.
|
|
2
|
+
* Does a branch's checkout carry uncommitted changes?
|
|
11
3
|
*
|
|
12
4
|
* @module lib/orchestration/worktree-dirty
|
|
13
5
|
*/
|
|
@@ -16,8 +8,6 @@ import { gitSpawn } from '../git-utils.js';
|
|
|
16
8
|
import { parseWorktreePorcelain } from '../worktree/inspector.js';
|
|
17
9
|
|
|
18
10
|
/**
|
|
19
|
-
* The stdout of a successful git read, or `null` when it cannot be trusted.
|
|
20
|
-
*
|
|
21
11
|
* @param {{ status?: number, stdout?: unknown }|null|undefined} result
|
|
22
12
|
* @returns {string|null}
|
|
23
13
|
*/
|
|
@@ -27,12 +17,7 @@ function readableStdout(result) {
|
|
|
27
17
|
}
|
|
28
18
|
|
|
29
19
|
/**
|
|
30
|
-
*
|
|
31
|
-
* checkout does.
|
|
32
|
-
*
|
|
33
|
-
* `git worktree list --porcelain` enumerates **every** checkout including the
|
|
34
|
-
* main one, so a repository working on the branch directly (no separate
|
|
35
|
-
* worktree) is found by this same lookup rather than by a second fallback path.
|
|
20
|
+
* `worktree list` includes the main checkout, so no second fallback is needed.
|
|
36
21
|
*
|
|
37
22
|
* @param {{ branch: string, cwd: string, gitFn: typeof gitSpawn }} args
|
|
38
23
|
* @returns {string|null}
|
|
@@ -47,19 +32,9 @@ function resolveBranchCheckout({ branch, cwd, gitFn }) {
|
|
|
47
32
|
}
|
|
48
33
|
|
|
49
34
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* is committed state, so a run that implemented and did not commit measures an
|
|
54
|
-
* empty change set — and the refusal then told the agent its scope was
|
|
55
|
-
* unverifiable and to escalate, when the actual fix was `git commit`. Measured
|
|
56
|
-
* in the consumer: the refusal signal is stamped 12:14:06Z and the branch's
|
|
57
|
-
* only commit 12:15:19Z (issue #5237).
|
|
58
|
-
*
|
|
59
|
-
* Total, and deliberately asymmetric: every unreadable surface — a failed
|
|
60
|
-
* `worktree list`, a branch no checkout holds, a failed `status`, a throwing
|
|
61
|
-
* git — answers `false`. A probe that cannot see the tree must not be able to
|
|
62
|
-
* talk a refusal into friendlier guidance than the evidence supports.
|
|
35
|
+
* The light backstop diffs committed state, so uncommitted work reads as an
|
|
36
|
+
* empty change set; this lets the refusal say "commit" instead. Every
|
|
37
|
+
* unreadable surface answers `false` — a blind probe must not soften a refusal.
|
|
63
38
|
*
|
|
64
39
|
* @param {{ branch: string, cwd?: string, gitFn?: typeof gitSpawn }} args
|
|
65
40
|
* @returns {boolean}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* absolute-path escapes in configuration-supplied paths.
|
|
4
|
+
* Reject `..` traversal and absolute escapes in config-supplied paths.
|
|
6
5
|
*
|
|
7
6
|
* @param {string} root absolute path of the containing directory
|
|
8
7
|
* @param {string} target absolute path to validate
|
|
9
|
-
* @param {string} label
|
|
10
|
-
* @param {{ allowEmpty?: boolean }} [opts]
|
|
11
|
-
* - `allowEmpty`: when false, `path.relative(root, target) === ''` is also
|
|
12
|
-
* rejected (target equals root). Default: true.
|
|
8
|
+
* @param {string} label identifier for the error message
|
|
9
|
+
* @param {{ allowEmpty?: boolean }} [opts] false also rejects target === root.
|
|
13
10
|
* @returns {string} the path relative to `root`
|
|
14
11
|
* @throws {Error} when target escapes root
|
|
15
12
|
*/
|
|
@@ -1,28 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* plan-phase-cleanup.js —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* `temp/run-<id>/techspec.md`, etc. — see `lib/config/temp-paths.js`). The
|
|
7
|
-
* workflow .md previously told the operator to `Remove-Item` those files by
|
|
8
|
-
* name at the end of each phase, which rots: adding a new temp file in the
|
|
9
|
-
* script required a synchronized markdown edit, and missed edits left
|
|
10
|
-
* orphaned files accumulating in `temp/`.
|
|
11
|
-
*
|
|
12
|
-
* The wrapper scripts now call `cleanupPhaseTempFiles()` directly. The set
|
|
13
|
-
* of artifact basenames a phase creates is the contract of this module —
|
|
14
|
-
* when a new temp file is introduced, extend `PHASE_TEMP_BASENAMES` here
|
|
15
|
-
* and both the spec and decompose wrappers delete it automatically.
|
|
16
|
-
*
|
|
17
|
-
* Cleanup is best-effort: missing files are fine (`ENOENT` is ignored),
|
|
18
|
-
* unexpected errors are swallowed with a console warning so a failed rm
|
|
19
|
-
* never sinks a successful phase.
|
|
20
|
-
*
|
|
21
|
-
* Migration note (Epic #1030 Story #1040): the legacy flat layout
|
|
22
|
-
* (`temp/planner-context-for-<id>.json` etc.) has been retired. The
|
|
23
|
-
* resolver now delegates to `runArtifactPath` from
|
|
24
|
-
* `lib/config/temp-paths.js`, which yields `temp/run-<id>/<basename>`
|
|
25
|
-
* under the configured `tempRoot`.
|
|
2
|
+
* plan-phase-cleanup.js — delete a `/mandrel-plan` phase's run-scoped temp
|
|
3
|
+
* files. `PHASE_TEMP_BASENAMES` is the contract: extend it when a phase adds
|
|
4
|
+
* a temp file. Best-effort — ENOENT is ignored and other errors only warn,
|
|
5
|
+
* so a failed rm never sinks a successful phase.
|
|
26
6
|
*/
|
|
27
7
|
|
|
28
8
|
import fs from 'node:fs/promises';
|
|
@@ -30,10 +10,7 @@ import path from 'node:path';
|
|
|
30
10
|
import { runArtifactPath } from './config/temp-paths.js';
|
|
31
11
|
import { PROJECT_ROOT, resolveConfig } from './config-resolver.js';
|
|
32
12
|
|
|
33
|
-
/**
|
|
34
|
-
* Map of phase → artifact basenames (no path components). The per-run
|
|
35
|
-
* directory prefix is supplied by `runArtifactPath` at resolution time.
|
|
36
|
-
*/
|
|
13
|
+
/** Phase → artifact basenames; `runArtifactPath` supplies the run dir. */
|
|
37
14
|
export const PHASE_TEMP_BASENAMES = Object.freeze({
|
|
38
15
|
spec: Object.freeze([
|
|
39
16
|
'planner-context.json',
|
|
@@ -41,13 +18,9 @@ export const PHASE_TEMP_BASENAMES = Object.freeze({
|
|
|
41
18
|
'acceptance-spec.md',
|
|
42
19
|
]),
|
|
43
20
|
decompose: Object.freeze(['decomposer-context.json', 'tickets.json']),
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
// the
|
|
47
|
-
// per-phase cleanup removed artifacts a `--force`/`--resume` re-persist
|
|
48
|
-
// was still entitled to reuse.
|
|
49
|
-
// `plan-metrics.json` stays deliberately excluded (PR1) — the ledger
|
|
50
|
-
// must survive cleanup so the whole plan run is visible in one stream.
|
|
21
|
+
// Deleted only at terminal persist success, so a `--force`/`--resume`
|
|
22
|
+
// re-persist can still reuse them. `plan-metrics.json` is deliberately
|
|
23
|
+
// excluded: the ledger must survive to show the whole run.
|
|
51
24
|
persist: Object.freeze([
|
|
52
25
|
'planner-context.json',
|
|
53
26
|
'techspec.md',
|
|
@@ -58,8 +31,6 @@ export const PHASE_TEMP_BASENAMES = Object.freeze({
|
|
|
58
31
|
});
|
|
59
32
|
|
|
60
33
|
/**
|
|
61
|
-
* Resolve the concrete paths a phase owns for a given Epic.
|
|
62
|
-
*
|
|
63
34
|
* @param {'spec'|'decompose'} phase
|
|
64
35
|
* @param {number} epicId
|
|
65
36
|
* @param {string} [repoRoot]
|
|
@@ -72,9 +43,7 @@ export function resolvePhaseTempPaths(phase, epicId, repoRoot = PROJECT_ROOT) {
|
|
|
72
43
|
`[plan-phase-cleanup] Unknown phase "${phase}". Expected one of: ${Object.keys(PHASE_TEMP_BASENAMES).join(', ')}.`,
|
|
73
44
|
);
|
|
74
45
|
}
|
|
75
|
-
//
|
|
76
|
-
// overrides; fall back to the helper's default when the resolver itself
|
|
77
|
-
// throws (zero-config callers — unit tests).
|
|
46
|
+
// Honour `tempRoot` overrides; zero-config callers fall back to defaults.
|
|
78
47
|
let config;
|
|
79
48
|
try {
|
|
80
49
|
config = resolveConfig({ cwd: repoRoot });
|
|
@@ -83,20 +52,11 @@ export function resolvePhaseTempPaths(phase, epicId, repoRoot = PROJECT_ROOT) {
|
|
|
83
52
|
}
|
|
84
53
|
return basenames.map((basename) => {
|
|
85
54
|
const rel = runArtifactPath(epicId, basename, config);
|
|
86
|
-
// `runArtifactPath` yields a path under `tempRoot` (relative when
|
|
87
|
-
// tempRoot is itself relative — the framework default). Rebase
|
|
88
|
-
// relative paths against `repoRoot` so callers always receive an
|
|
89
|
-
// absolute path — matches the pre-migration contract that
|
|
90
|
-
// downstream `fs.unlink` relies on. Already-absolute results pass
|
|
91
|
-
// through untouched.
|
|
92
55
|
return path.isAbsolute(rel) ? rel : path.join(repoRoot, rel);
|
|
93
56
|
});
|
|
94
57
|
}
|
|
95
58
|
|
|
96
59
|
/**
|
|
97
|
-
* Delete the temp files a phase owns for the given Epic. Idempotent:
|
|
98
|
-
* missing files are ignored; other errors are logged but do not throw.
|
|
99
|
-
*
|
|
100
60
|
* @param {{
|
|
101
61
|
* phase: 'spec'|'decompose',
|
|
102
62
|
* epicId: number,
|
|
@@ -1,23 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* preflight-runner.js —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* fast on blockers, log auto-fixes" pattern. The consumer entry points
|
|
6
|
-
* (`single-story-close.js`, `mandrel-update-preflight.js`, the npm test wrapper, and
|
|
7
|
-
* the bootstrap scripts) call `runPreflight({ scope })` instead of
|
|
8
|
-
* re-implementing the same assemble+run+format+exit-2 dance.
|
|
9
|
-
*
|
|
10
|
-
* Exit-code contract (shared by every consumer):
|
|
11
|
-
* - 0 → no blocker findings (warnings/info may have been printed).
|
|
12
|
-
* - 2 → at least one `severity: 'blocker'` finding survived after
|
|
13
|
-
* auto-fixes. The wrapper prints a human-readable blocker table
|
|
14
|
-
* (`id · summary · fixCommand`) before returning. Code 2 is the
|
|
15
|
-
* project-wide "preflight refused" reservation — see
|
|
16
|
-
* `.agents/workflows/helpers/deliver-story.md` for the rationale.
|
|
17
|
-
*
|
|
18
|
-
* Auto-fixes are logged via `logFixes` before the blocker check so the
|
|
19
|
-
* operator sees the "we corrected X" line even when a separate blocker
|
|
20
|
-
* later trips the exit. Auto-fixes never themselves block.
|
|
2
|
+
* preflight-runner.js — run the checks registry, log auto-fixes (which never
|
|
3
|
+
* block) before the blocker table, and report `blocked` so the consumer
|
|
4
|
+
* exits {@link PREFLIGHT_REFUSED_EXIT_CODE}.
|
|
21
5
|
*/
|
|
22
6
|
|
|
23
7
|
import { runChecks } from './checks/index.js';
|
|
@@ -29,15 +13,9 @@ import { Logger } from './Logger.js';
|
|
|
29
13
|
* @property {Array<object>} findings Unfixed findings (any severity).
|
|
30
14
|
* @property {Array<object>} fixed Findings that were auto-corrected.
|
|
31
15
|
* @property {boolean} blocked True iff `findings` contains a
|
|
32
|
-
* `severity: 'blocker'
|
|
16
|
+
* `severity: 'blocker'`; the consumer must then exit 2.
|
|
33
17
|
*/
|
|
34
18
|
|
|
35
|
-
/**
|
|
36
|
-
* Default logger adapter — routes info/warn/error through the project
|
|
37
|
-
* Logger. Kept as a module-local constant so the runner has a single seam
|
|
38
|
-
* tests can swap with a spy that captures lines without going through
|
|
39
|
-
* Logger's stdout/stderr.
|
|
40
|
-
*/
|
|
41
19
|
const DEFAULT_LOGGER = {
|
|
42
20
|
info: (msg) => Logger.info(msg),
|
|
43
21
|
warn: (msg) => Logger.warn(msg),
|
|
@@ -45,26 +23,14 @@ const DEFAULT_LOGGER = {
|
|
|
45
23
|
};
|
|
46
24
|
|
|
47
25
|
/**
|
|
48
|
-
* Run preflight checks for `scope` against an assembled state probe.
|
|
49
|
-
*
|
|
50
|
-
* The consumer surface is intentionally tiny: pass a `scope` string and
|
|
51
|
-
* (optionally) a `cwd`. The runner handles state assembly, the autoFix
|
|
52
|
-
* flag, finding/fix routing, and pretty-print of the blocker table.
|
|
53
|
-
*
|
|
54
26
|
* @param {object} opts
|
|
55
|
-
* @param {string} opts.scope
|
|
56
|
-
*
|
|
57
|
-
* @param {boolean} [opts.autoFix=true] Forwarded to `runChecks`. Defaults
|
|
58
|
-
* to `true` because every wiring call site at this Story's level wants
|
|
59
|
-
* auto-correction (the `retro` consumer that needs `autoFix:false` does
|
|
60
|
-
* NOT use this helper — it calls `runChecks` directly).
|
|
27
|
+
* @param {string} opts.scope e.g. `'story-close'`, `'npm-test'`.
|
|
28
|
+
* @param {boolean} [opts.autoFix=true]
|
|
61
29
|
* @param {string} [opts.cwd=process.cwd()]
|
|
62
|
-
* @param {object} [opts.probes] Test-only
|
|
63
|
-
*
|
|
64
|
-
* @param {
|
|
65
|
-
* @param {string} [opts.dir] Test-only fixture directory.
|
|
30
|
+
* @param {object} [opts.probes] Test-only.
|
|
31
|
+
* @param {object} [opts.registry] Test-only.
|
|
32
|
+
* @param {string} [opts.dir] Test-only.
|
|
66
33
|
* @param {{ info?: Function, warn?: Function, error?: Function }} [opts.logger]
|
|
67
|
-
* Defaults to the project Logger. Tests pass a spy that captures lines.
|
|
68
34
|
* @returns {Promise<PreflightResult>}
|
|
69
35
|
*/
|
|
70
36
|
export async function runPreflight({
|
|
@@ -79,9 +45,7 @@ export async function runPreflight({
|
|
|
79
45
|
if (!scope || typeof scope !== 'string') {
|
|
80
46
|
throw new Error('runPreflight: scope is required');
|
|
81
47
|
}
|
|
82
|
-
// `retro` is
|
|
83
|
-
// Catch it here so the failure mode is obvious instead of routing into
|
|
84
|
-
// the runner's autoFix throw.
|
|
48
|
+
// `retro` is read-only; fail here rather than in runChecks' autoFix throw.
|
|
85
49
|
if (scope === 'retro') {
|
|
86
50
|
throw new Error(
|
|
87
51
|
'runPreflight: retro scope is read-only — call runChecks directly',
|
|
@@ -99,18 +63,12 @@ export async function runPreflight({
|
|
|
99
63
|
const blockers = findings.filter((f) => f.severity === 'blocker');
|
|
100
64
|
const blocked = blockers.length > 0;
|
|
101
65
|
if (blocked) logBlockers(scope, blockers, logger);
|
|
102
|
-
// Surface non-blocker findings as well so operators see warnings/info.
|
|
103
66
|
const nonBlockerFindings = findings.filter((f) => f.severity !== 'blocker');
|
|
104
67
|
if (nonBlockerFindings.length > 0) logNonBlockers(nonBlockerFindings, logger);
|
|
105
68
|
return { findings, fixed, blocked };
|
|
106
69
|
}
|
|
107
70
|
|
|
108
|
-
/**
|
|
109
|
-
* Pick the logger method for `level` — falls back through the project
|
|
110
|
-
* Logger if the supplied logger is missing the level. Keeps the
|
|
111
|
-
* console-allowlist test happy (no direct console.* fallback here) and
|
|
112
|
-
* still lets tests swap the entire logger out.
|
|
113
|
-
*/
|
|
71
|
+
/** Falls back to the project Logger — never to `console.*` directly. */
|
|
114
72
|
function pick(logger, level) {
|
|
115
73
|
if (logger && typeof logger[level] === 'function') {
|
|
116
74
|
return (msg) => logger[level](msg);
|
|
@@ -119,8 +77,6 @@ function pick(logger, level) {
|
|
|
119
77
|
}
|
|
120
78
|
|
|
121
79
|
/**
|
|
122
|
-
* Print the auto-fixed findings as a one-line-per-fix summary.
|
|
123
|
-
*
|
|
124
80
|
* @param {Array<object>} fixed
|
|
125
81
|
* @param {object} [logger]
|
|
126
82
|
*/
|
|
@@ -134,9 +90,6 @@ function logFixes(fixed, logger = DEFAULT_LOGGER) {
|
|
|
134
90
|
}
|
|
135
91
|
|
|
136
92
|
/**
|
|
137
|
-
* Print the blocker table the operator sees on `exit 2`. Each row carries
|
|
138
|
-
* `id · summary · fixCommand`; details (if present) wrap underneath.
|
|
139
|
-
*
|
|
140
93
|
* @param {string} scope
|
|
141
94
|
* @param {Array<object>} blockers
|
|
142
95
|
* @param {object} [logger]
|
|
@@ -152,10 +105,7 @@ function logBlockers(scope, blockers, logger = DEFAULT_LOGGER) {
|
|
|
152
105
|
' -------------------------- -------- ----------------------------------------',
|
|
153
106
|
);
|
|
154
107
|
for (const b of blockers) {
|
|
155
|
-
// Pad
|
|
156
|
-
// needs the full id to find the check module on disk and to grep the
|
|
157
|
-
// codebase for the failure mode. Long ids just push the severity
|
|
158
|
-
// column right, which is fine for terminal output.
|
|
108
|
+
// Pad, never truncate — the operator needs the full id to find the check.
|
|
159
109
|
const id = String(b.id).padEnd(26);
|
|
160
110
|
const sev = String(b.severity).padEnd(8);
|
|
161
111
|
error(` ${id} ${sev} ${b.summary ?? ''}`);
|
|
@@ -175,8 +125,6 @@ function logBlockers(scope, blockers, logger = DEFAULT_LOGGER) {
|
|
|
175
125
|
}
|
|
176
126
|
|
|
177
127
|
/**
|
|
178
|
-
* Print warning/info findings as one line each. These never block.
|
|
179
|
-
*
|
|
180
128
|
* @param {Array<object>} findings
|
|
181
129
|
* @param {object} [logger]
|
|
182
130
|
*/
|
|
@@ -188,9 +136,5 @@ function logNonBlockers(findings, logger = DEFAULT_LOGGER) {
|
|
|
188
136
|
}
|
|
189
137
|
}
|
|
190
138
|
|
|
191
|
-
/**
|
|
192
|
-
* The reserved exit code for "preflight refused". Re-exported so consumer
|
|
193
|
-
* scripts can `process.exit(PREFLIGHT_REFUSED_EXIT_CODE)` instead of
|
|
194
|
-
* hard-coding the magic number.
|
|
195
|
-
*/
|
|
139
|
+
/** Project-wide "preflight refused" exit code. */
|
|
196
140
|
export const PREFLIGHT_REFUSED_EXIT_CODE = 2;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* process-group.js — kill spawned children as whole process groups:
|
|
3
|
+
* `child.kill()` on `npm` misses the `node --test` workers it forks.
|
|
4
|
+
* Parent SIGINT/SIGTERM is forwarded by a prepended handler, so the suite
|
|
5
|
+
* dies before the lock's release handler runs (a `setsid` leader never gets
|
|
6
|
+
* the terminal's Ctrl-C). win32 has no groups and degrades to the child.
|
|
7
|
+
* The kill path never throws.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export const TIMEOUT_EXIT_CODE = 124;
|
|
11
|
+
|
|
12
|
+
const FORWARDED_SIGNALS = Object.freeze(['SIGINT', 'SIGTERM']);
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* `detached` on win32 opens a new console instead.
|
|
16
|
+
*
|
|
17
|
+
* @param {string} [platform]
|
|
18
|
+
* @returns {{ detached?: boolean }}
|
|
19
|
+
*/
|
|
20
|
+
export function groupSpawnOptions(platform = process.platform) {
|
|
21
|
+
return platform === 'win32' ? {} : { detached: true };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {{ pid?: number, kill?: (signal?: string) => void }} child
|
|
26
|
+
* @param {string} [signal]
|
|
27
|
+
* @param {{ platform?: string, killFn?: (pid: number, signal: string) => void }} [opts]
|
|
28
|
+
* @returns {boolean}
|
|
29
|
+
*/
|
|
30
|
+
function killProcessGroup(
|
|
31
|
+
child,
|
|
32
|
+
signal = 'SIGKILL',
|
|
33
|
+
{ platform = process.platform, killFn = process.kill.bind(process) } = {},
|
|
34
|
+
) {
|
|
35
|
+
const pid = child?.pid;
|
|
36
|
+
if (platform !== 'win32' && Number.isInteger(pid) && pid > 0) {
|
|
37
|
+
try {
|
|
38
|
+
killFn(-pid, signal);
|
|
39
|
+
return true;
|
|
40
|
+
} catch {
|
|
41
|
+
// The group is gone (or was never ours) — try the child itself.
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
child?.kill?.(signal);
|
|
46
|
+
return true;
|
|
47
|
+
} catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** child → the signal its group receives when this process is signalled. */
|
|
53
|
+
const supervised = new Map();
|
|
54
|
+
let detachForwarding = null;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* A remaining listener (the lock's release handler) re-raises; with none,
|
|
58
|
+
* re-raise here so the process still dies as asked.
|
|
59
|
+
*
|
|
60
|
+
* @param {NodeJS.Process} processImpl
|
|
61
|
+
* @param {string} signal
|
|
62
|
+
*/
|
|
63
|
+
function forwardSignal(processImpl, signal) {
|
|
64
|
+
for (const [child, childSignal] of supervised) {
|
|
65
|
+
killProcessGroup(child, childSignal);
|
|
66
|
+
}
|
|
67
|
+
supervised.clear();
|
|
68
|
+
stopForwarding();
|
|
69
|
+
if (processImpl.listenerCount(signal) > 0) return;
|
|
70
|
+
try {
|
|
71
|
+
processImpl.kill(processImpl.pid, signal);
|
|
72
|
+
} catch {
|
|
73
|
+
// A process that cannot signal itself is already on its way out.
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function startForwarding(processImpl) {
|
|
78
|
+
if (detachForwarding) return;
|
|
79
|
+
const handlers = FORWARDED_SIGNALS.map((signal) => {
|
|
80
|
+
const handler = () => forwardSignal(processImpl, signal);
|
|
81
|
+
processImpl.prependListener(signal, handler);
|
|
82
|
+
return [signal, handler];
|
|
83
|
+
});
|
|
84
|
+
detachForwarding = () => {
|
|
85
|
+
for (const [signal, handler] of handlers) processImpl.off(signal, handler);
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function stopForwarding() {
|
|
90
|
+
const detach = detachForwarding;
|
|
91
|
+
detachForwarding = null;
|
|
92
|
+
detach?.();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Kill the group on timeout, abort or parent signal; `release()` on exit.
|
|
97
|
+
*
|
|
98
|
+
* @param {{ pid?: number, kill?: (signal?: string) => void }} child
|
|
99
|
+
* @param {{
|
|
100
|
+
* timeoutMs?: number,
|
|
101
|
+
* abortSignal?: AbortSignal,
|
|
102
|
+
* signalOnParentSignal?: string,
|
|
103
|
+
* processImpl?: NodeJS.Process,
|
|
104
|
+
* killOptions?: { platform?: string, killFn?: Function },
|
|
105
|
+
* }} [opts] `signalOnParentSignal`: SIGKILL for a bare suite, SIGTERM for a
|
|
106
|
+
* child with its own cleanup (a capture holding the lock).
|
|
107
|
+
* @returns {{ readonly timedOut: boolean, release: () => void }}
|
|
108
|
+
*/
|
|
109
|
+
export function superviseGroup(
|
|
110
|
+
child,
|
|
111
|
+
{
|
|
112
|
+
timeoutMs,
|
|
113
|
+
abortSignal,
|
|
114
|
+
signalOnParentSignal = 'SIGKILL',
|
|
115
|
+
processImpl = process,
|
|
116
|
+
killOptions,
|
|
117
|
+
} = {},
|
|
118
|
+
) {
|
|
119
|
+
let timedOut = false;
|
|
120
|
+
supervised.set(child, signalOnParentSignal);
|
|
121
|
+
startForwarding(processImpl);
|
|
122
|
+
const timer =
|
|
123
|
+
Number.isFinite(timeoutMs) && timeoutMs > 0
|
|
124
|
+
? setTimeout(() => {
|
|
125
|
+
timedOut = true;
|
|
126
|
+
killProcessGroup(child, 'SIGKILL', killOptions);
|
|
127
|
+
}, timeoutMs)
|
|
128
|
+
: null;
|
|
129
|
+
const onAbort = () => killProcessGroup(child, 'SIGTERM', killOptions);
|
|
130
|
+
abortSignal?.addEventListener('abort', onAbort, { once: true });
|
|
131
|
+
if (abortSignal?.aborted) onAbort();
|
|
132
|
+
return {
|
|
133
|
+
get timedOut() {
|
|
134
|
+
return timedOut;
|
|
135
|
+
},
|
|
136
|
+
release() {
|
|
137
|
+
if (timer) clearTimeout(timer);
|
|
138
|
+
abortSignal?.removeEventListener('abort', onAbort);
|
|
139
|
+
supervised.delete(child);
|
|
140
|
+
if (supervised.size === 0) stopForwarding();
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
}
|