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
package/lib/cli/registry.js
CHANGED
|
@@ -1,26 +1,11 @@
|
|
|
1
1
|
// lib/cli/registry.js
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* repeats it in `detail` because that is the field the doctor prints for a
|
|
10
|
-
* passing check. The registry is the single source of truth for which checks
|
|
11
|
-
* the doctor command runs and in what order.
|
|
12
|
-
*
|
|
13
|
-
* Checks run sequentially in the doctor runner (not in parallel) because
|
|
14
|
-
* some checks are meaningless without a prerequisite having passed first
|
|
15
|
-
* (e.g. `gh-auth` requires `gh-available`).
|
|
16
|
-
*
|
|
17
|
-
* Design goals
|
|
18
|
-
* - Every check is injectable via optional seam parameters so tests can
|
|
19
|
-
* drive every branch without spawning real child processes.
|
|
20
|
-
* - The `github-token` check never echoes the token value in `detail` or
|
|
21
|
-
* `remedy` (security baseline §5 — Secrets Management).
|
|
22
|
-
* - Node built-ins only; no third-party imports so the module loads inside
|
|
23
|
-
* the preflight guard before any third-party package is present.
|
|
3
|
+
* Ordered `mandrel doctor` check registry: each entry is `{ name, run() }`,
|
|
4
|
+
* `run()` returning `{ ok, detail, remedy? }` (`remedy` present whenever
|
|
5
|
+
* `ok` is false). Checks run sequentially because some presuppose an earlier
|
|
6
|
+
* one (`gh-auth` needs `gh-available`). Node built-ins only, so the module
|
|
7
|
+
* loads inside the preflight guard before third-party packages exist; no
|
|
8
|
+
* check ever echoes a token value.
|
|
24
9
|
*/
|
|
25
10
|
|
|
26
11
|
import { spawnSync } from 'node:child_process';
|
|
@@ -54,13 +39,7 @@ import {
|
|
|
54
39
|
satisfiesPinSpec,
|
|
55
40
|
} from './version-helpers.js';
|
|
56
41
|
|
|
57
|
-
// ---------------------------------------------------------------------------
|
|
58
|
-
// Internal helpers
|
|
59
|
-
// ---------------------------------------------------------------------------
|
|
60
|
-
|
|
61
42
|
/**
|
|
62
|
-
* Synchronously spawn a binary and return `{ status, stdout, stderr, error }`.
|
|
63
|
-
*
|
|
64
43
|
* @param {string} cmd
|
|
65
44
|
* @param {string[]} args
|
|
66
45
|
* @returns {{ status: number|null, stdout: string, stderr: string, error?: NodeJS.ErrnoException }}
|
|
@@ -75,9 +54,7 @@ function spawn(cmd, args, opts = {}) {
|
|
|
75
54
|
};
|
|
76
55
|
}
|
|
77
56
|
|
|
78
|
-
// ---------------------------------------------------------------------------
|
|
79
57
|
// check: node-version
|
|
80
|
-
// ---------------------------------------------------------------------------
|
|
81
58
|
|
|
82
59
|
/**
|
|
83
60
|
* @param {{ nodeVersion?: string }} [opts]
|
|
@@ -94,9 +71,7 @@ function runNodeVersion({ nodeVersion = process.versions.node } = {}) {
|
|
|
94
71
|
};
|
|
95
72
|
}
|
|
96
73
|
|
|
97
|
-
// ---------------------------------------------------------------------------
|
|
98
74
|
// check: git-available
|
|
99
|
-
// ---------------------------------------------------------------------------
|
|
100
75
|
|
|
101
76
|
/**
|
|
102
77
|
* @param {{ runner?: (cmd: string, args: string[]) => { status: number|null, stdout: string, stderr: string, error?: NodeJS.ErrnoException } }} [opts]
|
|
@@ -115,9 +90,7 @@ function runGitAvailable({ runner = spawn } = {}) {
|
|
|
115
90
|
return { ok: true, detail: r.stdout.trim().split('\n')[0] };
|
|
116
91
|
}
|
|
117
92
|
|
|
118
|
-
// ---------------------------------------------------------------------------
|
|
119
93
|
// check: gh-available
|
|
120
|
-
// ---------------------------------------------------------------------------
|
|
121
94
|
|
|
122
95
|
/**
|
|
123
96
|
* @param {{ runner?: (cmd: string, args: string[]) => { status: number|null, stdout: string, stderr: string, error?: NodeJS.ErrnoException } }} [opts]
|
|
@@ -136,21 +109,12 @@ function runGhAvailable({ runner = spawn } = {}) {
|
|
|
136
109
|
return { ok: true, detail: r.stdout.trim().split('\n')[0] };
|
|
137
110
|
}
|
|
138
111
|
|
|
139
|
-
// ---------------------------------------------------------------------------
|
|
140
112
|
// check: github-token
|
|
141
|
-
// ---------------------------------------------------------------------------
|
|
142
113
|
|
|
143
114
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
* token counts as present when either `GITHUB_TOKEN` / `GH_TOKEN` is set in
|
|
148
|
-
* the environment **or** `gh auth token` returns a value. The `mandrel` CLI
|
|
149
|
-
* does not load `.env`, so the previous env-only check false-blocked
|
|
150
|
-
* operators who authenticate solely via `gh auth login` (Finding A.4) —
|
|
151
|
-
* the runtime never needed `GITHUB_TOKEN` in that case because it falls back
|
|
152
|
-
* to the `gh` CLI. Never echoes the token value in `detail` or `remedy`
|
|
153
|
-
* (security baseline §5 — Secrets Management).
|
|
115
|
+
* Resolve a token the way `providers/github/auth.js#resolveToken` does: env
|
|
116
|
+
* `GITHUB_TOKEN`/`GH_TOKEN`, else `gh auth token`. The CLI does not load
|
|
117
|
+
* `.env`, so an env-only check would false-block `gh auth login` users.
|
|
154
118
|
*
|
|
155
119
|
* @param {{ env?: Record<string,string|undefined>,
|
|
156
120
|
* runner?: (cmd: string, args: string[]) => {
|
|
@@ -176,25 +140,14 @@ function runGithubToken({ env = process.env, runner = spawn } = {}) {
|
|
|
176
140
|
};
|
|
177
141
|
}
|
|
178
142
|
|
|
179
|
-
// ---------------------------------------------------------------------------
|
|
180
143
|
// check: gh-auth
|
|
181
|
-
// ---------------------------------------------------------------------------
|
|
182
144
|
|
|
183
145
|
/**
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* "Resource not accessible by integration") even though the token works for
|
|
190
|
-
* every git/API operation mandrel actually performs. The non-interactive
|
|
191
|
-
* runtime never consults `gh auth status`: it resolves auth via the env token
|
|
192
|
-
* or `gh auth token` (`.agents/scripts/providers/github/auth.js#resolveToken`,
|
|
193
|
-
* mirrored by the `github-token` check above). So when `gh auth status` fails
|
|
194
|
-
* but a token is present in the environment, degrade to **warn-and-skip**
|
|
195
|
-
* (ok=true) rather than false-blocking the ready verdict — the same
|
|
196
|
-
* warn-and-skip resolution #3915 applied to the project-scope preflight.
|
|
197
|
-
* A genuine "no token anywhere and not logged in" condition still fails.
|
|
146
|
+
* `gh auth status` live-validates the token, which an Actions installation
|
|
147
|
+
* token (and some fine-grained tokens) cannot pass even though they work for
|
|
148
|
+
* everything mandrel does. The runtime never consults it, so a failing status
|
|
149
|
+
* with an env token present is warn-and-skip (ok); only "no token and not
|
|
150
|
+
* logged in" fails.
|
|
198
151
|
*
|
|
199
152
|
* @param {{ runner?: (cmd: string, args: string[]) => { status: number|null, stdout: string, stderr: string, error?: NodeJS.ErrnoException }, env?: Record<string,string|undefined> }} [opts]
|
|
200
153
|
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
@@ -224,49 +177,23 @@ function runGhAuth({ runner = spawn, env = process.env } = {}) {
|
|
|
224
177
|
'Run `gh auth login` (choose GitHub.com → HTTPS → login with a web browser), then re-run.',
|
|
225
178
|
};
|
|
226
179
|
}
|
|
227
|
-
// Extract "Logged in to github.com as <handle>" from stdout or stderr.
|
|
228
180
|
const output = (r.stdout + r.stderr).trim();
|
|
229
181
|
const match = /Logged in to \S+ as (\S+)/i.exec(output);
|
|
230
182
|
const detail = match ? `logged in as ${match[1]}` : 'logged in';
|
|
231
183
|
return { ok: true, detail };
|
|
232
184
|
}
|
|
233
185
|
|
|
234
|
-
// ---------------------------------------------------------------------------
|
|
235
186
|
// check: commands-in-sync
|
|
236
|
-
// ---------------------------------------------------------------------------
|
|
237
187
|
|
|
238
188
|
/**
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
* `.claude/commands/*.md` destinations and report parity (the projection is
|
|
244
|
-
* a flat `/<name>` command surface; the #3576 plugin projection was
|
|
245
|
-
* reverted). A dest command backed only by a local workflow is in sync, not
|
|
246
|
-
* stale (#4721).
|
|
189
|
+
* Parity of `.claude/commands/*.md` against the union of `.agents/workflows/`
|
|
190
|
+
* and `.agents/local/workflows/`. A basename is expected iff at least one
|
|
191
|
+
* source copy is not `command: false`, mirroring the sync script's
|
|
192
|
+
* payload-wins shadowing; an unreadable source counts as projected.
|
|
247
193
|
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
* projectable local copy. Filtering each source dir independently and
|
|
252
|
-
* unioning the surviving basenames reproduces that exactly.
|
|
253
|
-
*
|
|
254
|
-
* Resolution anchor (Story #3588): the root defaults to `process.cwd()` —
|
|
255
|
-
* the consumer project directory where `mandrel sync` materializes both
|
|
256
|
-
* `.agents/` and the command tree — mirroring the `agents-materialized`
|
|
257
|
-
* and `agents-drift` checks. It MUST NOT fall back to `resolveProjectRoot()`:
|
|
258
|
-
* that walks up from this module's own location and lands on the *package*
|
|
259
|
-
* directory in an npm-installed consumer
|
|
260
|
-
* (`node_modules/mandrel/`), where the generated command tree never
|
|
261
|
-
* exists — yielding a permanent `N not synced` false positive whose
|
|
262
|
-
* `npm run sync:commands` remedy can never clear it.
|
|
263
|
-
*
|
|
264
|
-
* Injectable seams (used by tests so no real filesystem is touched):
|
|
265
|
-
* - `cwd()` replaces `process.cwd` so tests can pin the consumer root.
|
|
266
|
-
* - `readDir` replaces `fs.readdirSync`.
|
|
267
|
-
* - `readFile` replaces `fs.readFileSync` (frontmatter `command: false`
|
|
268
|
-
* projection opt-out, #4482 — an unreadable source is treated as
|
|
269
|
-
* projected, matching the sync script's fail-loud read).
|
|
194
|
+
* The root defaults to `process.cwd()`, never `resolveProjectRoot()` — that
|
|
195
|
+
* lands on `node_modules/mandrel/` in an installed consumer, where the
|
|
196
|
+
* command tree never exists, producing a permanent false "not synced".
|
|
270
197
|
*
|
|
271
198
|
* @param {{ projectRoot?: string, cwd?: () => string, readDir?: (dir: string) => string[], readFile?: (file: string) => string | null }} [opts]
|
|
272
199
|
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
@@ -299,12 +226,7 @@ function runCommandsInSync({ projectRoot, cwd, readDir, readFile } = {}) {
|
|
|
299
226
|
];
|
|
300
227
|
const destDir = path.join(root, '.claude', 'commands');
|
|
301
228
|
|
|
302
|
-
//
|
|
303
|
-
// the sync script — they are path-included modules, not slash commands).
|
|
304
|
-
// Workflows whose frontmatter carries `command: false` (#4482) opt out of
|
|
305
|
-
// projection and must not count toward the expected command set. An absent
|
|
306
|
-
// local dir degrades to [] via the listDir catch, so payload-only
|
|
307
|
-
// consumers are unchanged.
|
|
229
|
+
// Top-level .md only (helpers/ are included modules, not commands).
|
|
308
230
|
const expected = new Set();
|
|
309
231
|
for (const srcDir of srcDirs) {
|
|
310
232
|
for (const f of listDir(srcDir)) {
|
|
@@ -338,14 +260,10 @@ function runCommandsInSync({ projectRoot, cwd, readDir, readFile } = {}) {
|
|
|
338
260
|
};
|
|
339
261
|
}
|
|
340
262
|
|
|
341
|
-
// ---------------------------------------------------------------------------
|
|
342
263
|
// check: agents-in-sync
|
|
343
|
-
// ---------------------------------------------------------------------------
|
|
344
264
|
|
|
345
265
|
/**
|
|
346
|
-
*
|
|
347
|
-
* or malformed files degrade to `null` so a config problem never crashes a
|
|
348
|
-
* doctor check; the caller applies framework defaults on `null`.
|
|
266
|
+
* Raw JSON read; any failure degrades to `null`.
|
|
349
267
|
*
|
|
350
268
|
* @param {string} absPath
|
|
351
269
|
* @param {typeof fs} fsImpl
|
|
@@ -360,20 +278,10 @@ function readJsonSafe(absPath, fsImpl) {
|
|
|
360
278
|
}
|
|
361
279
|
|
|
362
280
|
/**
|
|
363
|
-
* Resolve `delivery.routing.roleScopedAgents`
|
|
364
|
-
*
|
|
365
|
-
* `
|
|
366
|
-
*
|
|
367
|
-
* the module doc: registry.js must load inside the preflight guard, before
|
|
368
|
-
* any third-party package is guaranteed present).
|
|
369
|
-
*
|
|
370
|
-
* Reads `.agentrc.json` and `.agentrc.local.json` directly and shallow-merges
|
|
371
|
-
* only the `delivery.routing` block (local wins per-key) — narrower than the
|
|
372
|
-
* resolver's full deep-merge, but sufficient for this one boolean, and it
|
|
373
|
-
* still honours a local override rather than silently ignoring it. Delegates
|
|
374
|
-
* the actual default/coercion to `getDeliveryRouting` (`config/delivery-
|
|
375
|
-
* routing.js`), which has zero imports of its own and is already the single
|
|
376
|
-
* source of truth for this default elsewhere in the framework.
|
|
281
|
+
* Resolve `delivery.routing.roleScopedAgents` without `resolveConfig()`,
|
|
282
|
+
* which pulls in AJV and would break the built-ins-only contract. Shallow-
|
|
283
|
+
* merges only `delivery.routing` from `.agentrc.json` and
|
|
284
|
+
* `.agentrc.local.json` (local wins).
|
|
377
285
|
*
|
|
378
286
|
* @param {string} projectRoot
|
|
379
287
|
* @param {typeof fs} fsImpl
|
|
@@ -397,44 +305,11 @@ function resolveRoleScopedAgentsFlag(projectRoot, fsImpl) {
|
|
|
397
305
|
}
|
|
398
306
|
|
|
399
307
|
/**
|
|
400
|
-
*
|
|
401
|
-
*
|
|
402
|
-
*
|
|
403
|
-
*
|
|
404
|
-
*
|
|
405
|
-
*
|
|
406
|
-
* Resolution anchor: the root defaults to `process.cwd()` — the consumer
|
|
407
|
-
* project directory where `mandrel sync` materializes both `.agents/` and the
|
|
408
|
-
* agent tree — mirroring `commands-in-sync`. It MUST NOT fall back to
|
|
409
|
-
* `resolveProjectRoot()`: that walks up from this module's own location and
|
|
410
|
-
* lands on the *package* directory in an npm-installed consumer, where the
|
|
411
|
-
* generated agent tree never exists.
|
|
412
|
-
*
|
|
413
|
-
* A repo with no `.agents/agents/` sources and no `.claude/agents/` tree is a
|
|
414
|
-
* clean no-op (0 sources, 0 dests → "up to date").
|
|
415
|
-
*
|
|
416
|
-
* **Tightened from advisory to fatal (Story #4530, M7-B).** Prior to this
|
|
417
|
-
* Story, a **never materialized** agent tree (sources present, `.claude/
|
|
418
|
-
* agents/` empty) was reported as advisory — "inert", because no workflow
|
|
419
|
-
* spawned the role agents yet. M7-B has landed: `helpers/deliver-story` Step
|
|
420
|
-
* 1a dispatches `subagent_type: acceptance-critic` on the **default** path
|
|
421
|
-
* (`roleScopedAgents` defaults `true`). An unmaterialized tree under that
|
|
422
|
-
* default is no longer a benign scaffolding gap — it is the acceptance
|
|
423
|
-
* ceremony's fresh-context critic silently failing to spawn and falling back
|
|
424
|
-
* to a weaker inline critic, with doctor reporting green throughout. This
|
|
425
|
-
* check now fails in exactly that case. When `roleScopedAgents` is `false`
|
|
426
|
-
* (the operator kill-switch), an unmaterialized tree is expected — the check
|
|
427
|
-
* stays advisory. Once the tree HAS been materialized, drift (a source
|
|
428
|
-
* missing from the dest, or a stale dest file) fails the check exactly like
|
|
429
|
-
* `commands-in-sync`, unconditionally, exactly as before this Story.
|
|
430
|
-
*
|
|
431
|
-
* Injectable seams (used by tests so no real filesystem is touched):
|
|
432
|
-
* - `cwd()` replaces `process.cwd` so tests can pin the consumer root.
|
|
433
|
-
* - `readDir` replaces `fs.readdirSync`.
|
|
434
|
-
* - `fsImpl` replaces the `node:fs` surface used for the `.agentrc.json` /
|
|
435
|
-
* `.agentrc.local.json` reads.
|
|
436
|
-
* - `roleScopedAgents` overrides the resolved flag directly, bypassing the
|
|
437
|
-
* config reads entirely.
|
|
308
|
+
* Parity of `.claude/agents/*.md` against `.agents/agents/*.md` (root anchored
|
|
309
|
+
* at `process.cwd()` as in `commands-in-sync`). A never-materialized tree is
|
|
310
|
+
* fatal while `roleScopedAgents` is on — the acceptance critic would silently
|
|
311
|
+
* fail to spawn and fall back to a weaker inline critic — and advisory when it
|
|
312
|
+
* is off. Drift in a materialized tree always fails.
|
|
438
313
|
*
|
|
439
314
|
* @param {{
|
|
440
315
|
* projectRoot?: string,
|
|
@@ -483,7 +358,6 @@ function runAgentsInSync({
|
|
|
483
358
|
? roleScopedAgents
|
|
484
359
|
: resolveRoleScopedAgentsFlag(root, fsImpl);
|
|
485
360
|
if (!resolvedFlag) {
|
|
486
|
-
// Kill-switch off: an unmaterialized tree is expected, not a defect.
|
|
487
361
|
return {
|
|
488
362
|
ok: true,
|
|
489
363
|
detail: `${sources.length} agent def(s) not materialized (roleScopedAgents is disabled)`,
|
|
@@ -517,18 +391,12 @@ function runAgentsInSync({
|
|
|
517
391
|
};
|
|
518
392
|
}
|
|
519
393
|
|
|
520
|
-
// ---------------------------------------------------------------------------
|
|
521
394
|
// check: runtime-deps
|
|
522
|
-
// ---------------------------------------------------------------------------
|
|
523
395
|
|
|
524
396
|
/**
|
|
525
|
-
*
|
|
526
|
-
*
|
|
527
|
-
*
|
|
528
|
-
* node_modules, so a declared range cannot enforce which `@babel/parser` major
|
|
529
|
-
* the complexity kernel actually gets, and the wrong major fails scoring
|
|
530
|
-
* mid-scan with an opaque plugin-list error. Reporting it here puts it where a
|
|
531
|
-
* consumer is already looking for what to fix.
|
|
397
|
+
* Presence is not enough: a declared range cannot pin which `@babel/parser`
|
|
398
|
+
* major the consumer's node_modules supplies, and the wrong one fails
|
|
399
|
+
* scoring mid-scan with an opaque error — so report it here.
|
|
532
400
|
*
|
|
533
401
|
* @param {() => string|null} parserMajorError
|
|
534
402
|
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
@@ -546,24 +414,9 @@ function allPresentVerdict(parserMajorError) {
|
|
|
546
414
|
}
|
|
547
415
|
|
|
548
416
|
/**
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
* `projectRoot` defaults to `process.cwd()` (the consumer project root) so
|
|
553
|
-
* the manifest path and the require-resolution context mirror the context in
|
|
554
|
-
* which the framework scripts actually run (Story #4046 A2). Using
|
|
555
|
-
* `resolveProjectRoot()` (the package root inside `node_modules/mandrel/`)
|
|
556
|
-
* breaks the check under pnpm isolated-mode layouts where the consumer's
|
|
557
|
-
* node_modules are hoisted above `node_modules/mandrel/` and are invisible
|
|
558
|
-
* from the package root's resolver.
|
|
559
|
-
*
|
|
560
|
-
* Injectable seams:
|
|
561
|
-
* - `resolve(dep)` — replaces the real `require.resolve`; throws when a dep
|
|
562
|
-
* is missing.
|
|
563
|
-
* - `manifestRequired` — array of required package names, skips the
|
|
564
|
-
* filesystem read of `runtime-deps.json`.
|
|
565
|
-
* - `parserMajorError()` — replaces the resolved-parser-major probe, so the
|
|
566
|
-
* unsupported-major report is assertable without installing one.
|
|
417
|
+
* Are the runtime deps resolvable from the consumer root? Anchored at
|
|
418
|
+
* `process.cwd()`, not the package root: under pnpm isolated mode the
|
|
419
|
+
* consumer's node_modules are invisible from `node_modules/mandrel/`.
|
|
567
420
|
*
|
|
568
421
|
* @param {{ projectRoot?: string, resolve?: (dep: string) => string, manifestRequired?: string[] }} [opts]
|
|
569
422
|
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
@@ -574,10 +427,6 @@ function runRuntimeDeps({
|
|
|
574
427
|
manifestRequired,
|
|
575
428
|
parserMajorError = describeParserMajorError,
|
|
576
429
|
} = {}) {
|
|
577
|
-
// Anchor at process.cwd() (the consumer root), not resolveProjectRoot() (the
|
|
578
|
-
// package root). Under pnpm isolated-mode the consumer's node_modules are not
|
|
579
|
-
// visible from inside node_modules/mandrel/, so the old anchor produced false
|
|
580
|
-
// "missing" reports on a clean install (Story #4046 A2).
|
|
581
430
|
const root = projectRoot ?? process.cwd();
|
|
582
431
|
|
|
583
432
|
let required = manifestRequired;
|
|
@@ -598,17 +447,8 @@ function runRuntimeDeps({
|
|
|
598
447
|
|
|
599
448
|
const missing = [];
|
|
600
449
|
|
|
601
|
-
//
|
|
602
|
-
//
|
|
603
|
-
// node_modules). Under pnpm isolated-mode the consumer's node_modules are
|
|
604
|
-
// not reachable from inside node_modules/mandrel/; anchoring at process.cwd()
|
|
605
|
-
// finds them correctly.
|
|
606
|
-
//
|
|
607
|
-
// `isResolvable` is shared with the framework-side preflight rather than
|
|
608
|
-
// reimplemented here: it probes the bare specifier AND `<name>/package.json`,
|
|
609
|
-
// because a dependency with no `main` and no `exports` cannot be resolved by
|
|
610
|
-
// name at all. Probing only the bare name reports such a package missing
|
|
611
|
-
// while it sits installed, and this check gates `mandrel doctor`.
|
|
450
|
+
// `isResolvable` also probes `<name>/package.json`: a dep with no `main`
|
|
451
|
+
// and no `exports` cannot be resolved by bare name yet is installed.
|
|
612
452
|
const resolve =
|
|
613
453
|
resolveSeam ?? createRequire(path.join(root, 'package.json')).resolve;
|
|
614
454
|
for (const dep of required) {
|
|
@@ -630,30 +470,12 @@ function runRuntimeDeps({
|
|
|
630
470
|
};
|
|
631
471
|
}
|
|
632
472
|
|
|
633
|
-
// ---------------------------------------------------------------------------
|
|
634
473
|
// check: agents-materialized
|
|
635
|
-
// ---------------------------------------------------------------------------
|
|
636
474
|
|
|
637
475
|
/**
|
|
638
|
-
*
|
|
639
|
-
*
|
|
640
|
-
*
|
|
641
|
-
* the "postinstall-skipped" state — the package was installed with scripts
|
|
642
|
-
* disabled (e.g. `npm ci --ignore-scripts`, a sandboxed CI, or a package
|
|
643
|
-
* manager that skips lifecycle scripts), so the materializer never ran. The
|
|
644
|
-
* remedy is to run `mandrel sync` (lib/cli/sync.js) by hand.
|
|
645
|
-
*
|
|
646
|
-
* Resolution anchors:
|
|
647
|
-
* - `./.agents/instructions.md` is resolved against `cwd` (the consumer
|
|
648
|
-
* project root), matching where `mandrel sync` writes the materialized tree.
|
|
649
|
-
* - `mandrel` is resolved from `cwd` so we detect *their* install, not
|
|
650
|
-
* a copy hoisted next to this CLI module — mirroring sync.js's resolver.
|
|
651
|
-
*
|
|
652
|
-
* Injectable seams (used by tests so no real filesystem or package is needed):
|
|
653
|
-
* - `cwd()` — replaces `process.cwd`.
|
|
654
|
-
* - `existsSync(p)` — replaces `fs.existsSync`.
|
|
655
|
-
* - `resolvePackage(fromDir)` — replaces `mandrel` resolution; throws
|
|
656
|
-
* when the package is not installed.
|
|
476
|
+
* Is `./.agents/instructions.md` present? Absent with the package installed
|
|
477
|
+
* means postinstall was skipped (`--ignore-scripts`, sandboxed CI). Both
|
|
478
|
+
* lookups anchor at the consumer's cwd.
|
|
657
479
|
*
|
|
658
480
|
* @param {{
|
|
659
481
|
* cwd?: () => string,
|
|
@@ -704,31 +526,11 @@ function runAgentsMaterialized({ cwd, existsSync, resolvePackage } = {}) {
|
|
|
704
526
|
};
|
|
705
527
|
}
|
|
706
528
|
|
|
707
|
-
// ---------------------------------------------------------------------------
|
|
708
529
|
// check: agents-drift
|
|
709
|
-
// ---------------------------------------------------------------------------
|
|
710
|
-
|
|
711
|
-
// defaultResolvePackageRoot and listPayloadFiles (re-exported as `listFiles`
|
|
712
|
-
// from sync.js) are imported from `lib/cli/sync.js` at the top of this file
|
|
713
|
-
// (Story #4048 B3 — no mirror copies).
|
|
714
530
|
|
|
715
531
|
/**
|
|
716
|
-
*
|
|
717
|
-
*
|
|
718
|
-
*
|
|
719
|
-
* Size short-circuit (Story #4193): when the injected `fsImpl` exposes
|
|
720
|
-
* `statSync`, a `statSync(src).size !== statSync(dest).size` mismatch is
|
|
721
|
-
* sufficient proof of drift, so it returns `true` on two `stat` syscalls
|
|
722
|
-
* **without reading either file's contents** — the overwhelmingly common
|
|
723
|
-
* drift shape after a stale `sync` is a size change. Equal sizes do not
|
|
724
|
-
* guarantee equal content, so an equal-size pair falls through to the
|
|
725
|
-
* `readFileSync` + `Buffer.equals` byte comparison. The short-circuit is
|
|
726
|
-
* opt-in on `statSync` being present; a seam that omits it (e.g. a legacy
|
|
727
|
-
* test double) transparently uses the byte-read path, preserving the prior
|
|
728
|
-
* behaviour exactly.
|
|
729
|
-
*
|
|
730
|
-
* Security: returns only a boolean — it never surfaces file contents to the
|
|
731
|
-
* caller (security baseline §5 — Data Leakage & Logging).
|
|
532
|
+
* A size mismatch proves drift without reading contents; equal sizes fall
|
|
533
|
+
* through to a byte compare. `statSync` is optional on the seam.
|
|
732
534
|
*
|
|
733
535
|
* @param {string} src - absolute path to the package-payload file
|
|
734
536
|
* @param {string} dest - absolute path to the materialized file
|
|
@@ -746,28 +548,9 @@ function payloadFileDrifted(src, dest, fsImpl) {
|
|
|
746
548
|
}
|
|
747
549
|
|
|
748
550
|
/**
|
|
749
|
-
* Compare
|
|
750
|
-
*
|
|
751
|
-
*
|
|
752
|
-
* missing) materialized file so the operator can re-sync or move local edits
|
|
753
|
-
* into `.agents/local/`.
|
|
754
|
-
*
|
|
755
|
-
* Security: logs only paths and counts — file contents are read for a byte
|
|
756
|
-
* comparison but never placed into `detail` or `remedy` (security baseline
|
|
757
|
-
* §5 — Data Leakage & Logging). The comparison is short-circuiting and never
|
|
758
|
-
* accumulates file contents.
|
|
759
|
-
*
|
|
760
|
-
* Performance: per-file drift is decided by `payloadFileDrifted`, which gates
|
|
761
|
-
* the byte read behind a cheap `statSync` size comparison (Story #4193) so a
|
|
762
|
-
* size-changed file — the common drift shape after a stale `sync` — reports
|
|
763
|
-
* without reading either file's contents.
|
|
764
|
-
*
|
|
765
|
-
* Injectable seams (used by tests so no real filesystem or package is needed):
|
|
766
|
-
* - `cwd()` — replaces `process.cwd`.
|
|
767
|
-
* - `fsImpl` — replaces the `node:fs` surface (`existsSync`, `readdirSync`,
|
|
768
|
-
* `readFileSync`, and optionally `statSync` for the size short-circuit).
|
|
769
|
-
* - `resolvePackageRoot(fromDir)` — replaces `mandrel` resolution;
|
|
770
|
-
* throws when the package is not installed.
|
|
551
|
+
* Compare materialized `./.agents/` bytes to the installed package payload
|
|
552
|
+
* (excluding `.agents/local/`) and report the first missing or drifted file.
|
|
553
|
+
* Only paths and counts are reported, never contents.
|
|
771
554
|
*
|
|
772
555
|
* @param {{
|
|
773
556
|
* cwd?: () => string,
|
|
@@ -785,9 +568,7 @@ export function runAgentsDrift({ cwd, fsImpl = fs, resolvePackageRoot } = {}) {
|
|
|
785
568
|
try {
|
|
786
569
|
packageRoot = resolveRoot(projectRoot);
|
|
787
570
|
} catch {
|
|
788
|
-
//
|
|
789
|
-
// agents-materialized owns the "not installed" remedy, so this check is
|
|
790
|
-
// a no-op success rather than a false drift signal.
|
|
571
|
+
// agents-materialized owns the "not installed" remedy.
|
|
791
572
|
return {
|
|
792
573
|
ok: true,
|
|
793
574
|
detail: 'mandrel not installed — drift skipped',
|
|
@@ -804,7 +585,6 @@ export function runAgentsDrift({ cwd, fsImpl = fs, resolvePackageRoot } = {}) {
|
|
|
804
585
|
|
|
805
586
|
const destRoot = path.join(projectRoot, '.agents');
|
|
806
587
|
if (!fsImpl.existsSync(destRoot)) {
|
|
807
|
-
// Nothing materialized yet — agents-materialized owns that remedy.
|
|
808
588
|
return { ok: true, detail: './.agents/ not materialized — drift skipped' };
|
|
809
589
|
}
|
|
810
590
|
|
|
@@ -844,66 +624,18 @@ export function runAgentsDrift({ cwd, fsImpl = fs, resolvePackageRoot } = {}) {
|
|
|
844
624
|
};
|
|
845
625
|
}
|
|
846
626
|
|
|
847
|
-
// ---------------------------------------------------------------------------
|
|
848
627
|
// check: pin-current
|
|
849
|
-
// ---------------------------------------------------------------------------
|
|
850
628
|
|
|
851
629
|
/**
|
|
852
|
-
* Fatal
|
|
853
|
-
*
|
|
854
|
-
*
|
|
855
|
-
*
|
|
856
|
-
*
|
|
857
|
-
*
|
|
858
|
-
*
|
|
859
|
-
*
|
|
860
|
-
*
|
|
861
|
-
* resolves to — e.g. an out-of-band symlink, or `npm install mandrel@latest
|
|
862
|
-
* --no-save` — which `mandrel doctor` graded as fully green before this
|
|
863
|
-
* check existed, because the only version `defaultCurrentVersion` ever read
|
|
864
|
-
* WAS the inflated `node_modules` one.
|
|
865
|
-
*
|
|
866
|
-
* **Range-aware.** The declared pin is a *range*, not an equality, so the
|
|
867
|
-
* question this check asks is satisfaction, not identity. A consumer who
|
|
868
|
-
* declares `^2.1.0` and runs a routine `npm update` gets 2.4.0 in
|
|
869
|
-
* `node_modules` with `package.json` untouched — that is npm behaving
|
|
870
|
-
* exactly as documented, and under this project's `always-bump-minor`
|
|
871
|
-
* release cadence it is the *normal* steady state, not a defect. Grading it
|
|
872
|
-
* fatal (as this check originally did, comparing only the pin's base
|
|
873
|
-
* version) made `mandrel doctor` cry wolf on healthy installs.
|
|
874
|
-
*
|
|
875
|
-
* The graded contract:
|
|
876
|
-
* - installed **satisfies** the declared range and equals its base version
|
|
877
|
-
* → pass, quietly.
|
|
878
|
-
* - installed **satisfies** the declared range but is newer than its base
|
|
879
|
-
* (`^2.1.0` + 2.4.0) → pass with an **advisory** `detail`. Re-pinning via
|
|
880
|
-
* `mandrel update` is tidier, but nothing is broken. This mirrors how
|
|
881
|
-
* `version-current` stays non-fatal: `ok: true` with the advisory carried
|
|
882
|
-
* in `detail` (the registry's `advisory: true` flag documents an entry
|
|
883
|
-
* whose `run()` *never* fails, which is not true of this check).
|
|
884
|
-
* - installed does **not** satisfy the declared range (`^2.1.0` + 3.0.0, or
|
|
885
|
-
* an exact `2.1.0` pin + 2.4.0) → **fail**. The declared dependency does
|
|
886
|
-
* not describe the code that is running.
|
|
887
|
-
* - installed is **behind** the pin's base version (`^2.4.0` + 2.1.0) →
|
|
888
|
-
* **fail**, and note that `<` the base never satisfies any of the ranges
|
|
889
|
-
* `resolveConsumerPinSpec` yields, so this is a sub-case of the above
|
|
890
|
-
* given a distinct, more actionable message.
|
|
891
|
-
*
|
|
892
|
-
* Skips cleanly (not a failure) when there is no resolvable pin at all — no
|
|
893
|
-
* `package.json`, no `mandrel` entry in `dependencies`/`devDependencies`, or
|
|
894
|
-
* a non-semver specifier (`workspace:`, `git+`, `latest`, a comparator
|
|
895
|
-
* range) — via {@link resolveConsumerPinSpec}'s own `null` contract. This
|
|
896
|
-
* is also how mandrel's own repo (no self-dependency) and workspace/npx
|
|
897
|
-
* consumers degrade to a clean pass rather than a false failure.
|
|
898
|
-
*
|
|
899
|
-
* Injectable seams (used by tests so no real filesystem or package is
|
|
900
|
-
* needed):
|
|
901
|
-
* - `cwd()` — replaces `process.cwd`, anchoring both the pin read and the
|
|
902
|
-
* `node_modules` resolution at the same consumer root (mirrors
|
|
903
|
-
* `agents-drift` / `agents-in-sync`).
|
|
904
|
-
* - `fsImpl` — replaces the `node:fs` surface.
|
|
905
|
-
* - `resolvePackageRoot(fromDir)` — replaces `mandrel` resolution; throws
|
|
906
|
-
* when the package is not installed.
|
|
630
|
+
* Fatal: does the installed `mandrel` satisfy the consumer's declared range?
|
|
631
|
+
* Distinct from `agents-drift` (file contents) and `version-current` (newer
|
|
632
|
+
* published). Graded by range satisfaction, not identity, because `^2.1.0` +
|
|
633
|
+
* 2.4.0 after `npm update` is the normal steady state:
|
|
634
|
+
* - satisfies and equals the base → pass;
|
|
635
|
+
* - satisfies but newer than the base → pass, advisory in `detail`;
|
|
636
|
+
* - behind the base → fail (distinct message);
|
|
637
|
+
* - otherwise outside the range → fail.
|
|
638
|
+
* No resolvable semver pin (absent, `workspace:`, `git+`, `latest`, …) skips.
|
|
907
639
|
*
|
|
908
640
|
* @param {{
|
|
909
641
|
* cwd?: () => string,
|
|
@@ -929,8 +661,6 @@ export function runPinCurrent({ cwd, fsImpl = fs, resolvePackageRoot } = {}) {
|
|
|
929
661
|
try {
|
|
930
662
|
installedRoot = resolveRoot(projectRoot);
|
|
931
663
|
} catch {
|
|
932
|
-
// No baseline to compare the pin against; agents-materialized /
|
|
933
|
-
// runtime-deps own the "not installed" remedy.
|
|
934
664
|
return {
|
|
935
665
|
ok: true,
|
|
936
666
|
detail: 'mandrel not installed — pin check skipped',
|
|
@@ -971,10 +701,7 @@ export function runPinCurrent({ cwd, fsImpl = fs, resolvePackageRoot } = {}) {
|
|
|
971
701
|
}
|
|
972
702
|
|
|
973
703
|
if (compareSemver(installed, spec.version) > 0) {
|
|
974
|
-
//
|
|
975
|
-
// `npm update` under a caret/tilde pin. Healthy, so `ok: true`; the
|
|
976
|
-
// advisory rides in `detail` (the doctor runner only prints `remedy` for
|
|
977
|
-
// failures).
|
|
704
|
+
// The doctor prints only `detail` for a pass, so the advisory rides there.
|
|
978
705
|
return {
|
|
979
706
|
ok: true,
|
|
980
707
|
detail: `v${installed} satisfies the ${declared} pin but is newer than it — run \`mandrel update\` to re-pin (advisory)`,
|
|
@@ -987,19 +714,9 @@ export function runPinCurrent({ cwd, fsImpl = fs, resolvePackageRoot } = {}) {
|
|
|
987
714
|
};
|
|
988
715
|
}
|
|
989
716
|
|
|
990
|
-
// ---------------------------------------------------------------------------
|
|
991
717
|
// check: version-current
|
|
992
|
-
// ---------------------------------------------------------------------------
|
|
993
|
-
|
|
994
|
-
// parseVersion and compareVersions are imported from `lib/cli/version-helpers.js`
|
|
995
|
-
// at the top of this file (Story #4048 B3 — no mirror copies). `compareSemver`
|
|
996
|
-
// is the registry-local alias for the imported `compareVersions`.
|
|
997
718
|
|
|
998
719
|
/**
|
|
999
|
-
* Resolve the installed `mandrel` version from this package's own
|
|
1000
|
-
* `package.json`. This module lives at `<root>/lib/cli/registry.js`, so the
|
|
1001
|
-
* manifest is two directories up. Mirrors `lib/cli/update.js#defaultCurrentVersion`.
|
|
1002
|
-
*
|
|
1003
720
|
* @param {typeof fs} fsImpl
|
|
1004
721
|
* @returns {string}
|
|
1005
722
|
*/
|
|
@@ -1010,17 +727,12 @@ function defaultInstalledVersion(fsImpl) {
|
|
|
1010
727
|
return String(parsed.version);
|
|
1011
728
|
}
|
|
1012
729
|
|
|
1013
|
-
/**
|
|
1014
|
-
* Default cache filename — mirrors `version-check.js#DEFAULT_CACHE_FILENAME`.
|
|
1015
|
-
*/
|
|
730
|
+
/** Mirrors `version-check.js#DEFAULT_CACHE_FILENAME`. */
|
|
1016
731
|
const DEFAULT_VERSION_CACHE_FILENAME = 'version-check.json';
|
|
1017
732
|
|
|
1018
733
|
/**
|
|
1019
|
-
*
|
|
1020
|
-
* `
|
|
1021
|
-
* npm/pnpm reinstalls that may replace `node_modules/` entirely (Story #4046
|
|
1022
|
-
* A2). Mirrors `commands-in-sync` / `agents-materialized` / `agents-drift`
|
|
1023
|
-
* which all anchor at `process.cwd()`.
|
|
734
|
+
* Anchored at the consumer root so the cache survives reinstalls that
|
|
735
|
+
* replace `node_modules/`.
|
|
1024
736
|
*
|
|
1025
737
|
* @returns {string}
|
|
1026
738
|
*/
|
|
@@ -1029,32 +741,8 @@ function defaultVersionCachePath() {
|
|
|
1029
741
|
}
|
|
1030
742
|
|
|
1031
743
|
/**
|
|
1032
|
-
* Cache-only stale-version advisory
|
|
1033
|
-
*
|
|
1034
|
-
* Reads the daily freshness cache written by `lib/cli/version-check.js` and
|
|
1035
|
-
* reports whether a newer version than the installed one is already known
|
|
1036
|
-
* locally. This check is **cache-only**: it NEVER issues a network request
|
|
1037
|
-
* (it calls `readCache`, not `isStale`, so the network `runner` seam is never
|
|
1038
|
-
* reached) — the daily refresh is owned by `version-check.js`, invoked
|
|
1039
|
-
* elsewhere on the normal command path.
|
|
1040
|
-
*
|
|
1041
|
-
* **Non-fatal advisory contract.** A stale install is informational, not a
|
|
1042
|
-
* readiness failure, so this check ALWAYS returns `ok: true` and therefore can
|
|
1043
|
-
* never flip `mandrel doctor`'s exit code or block CI. When a newer version is
|
|
1044
|
-
* cached, the advisory is surfaced through `detail` ("a newer version is
|
|
1045
|
-
* available") and an actionable `remedy` (`mandrel update`); when the cache is
|
|
1046
|
-
* absent, malformed, or already current, the check reports the up-to-date /
|
|
1047
|
-
* unknown state with no remedy. The registry entry carries `advisory: true` so
|
|
1048
|
-
* downstream renderers can label it as informational.
|
|
1049
|
-
*
|
|
1050
|
-
* Security (security-baseline § 5 — Data Leakage & Logging): emits only version
|
|
1051
|
-
* strings; never reads or echoes tokens, credentials, or raw cache bytes beyond
|
|
1052
|
-
* the two version fields `readCache` already validates.
|
|
1053
|
-
*
|
|
1054
|
-
* Injectable seams (used by tests so no real filesystem is touched):
|
|
1055
|
-
* - `cachePath` — absolute path to the freshness cache JSON.
|
|
1056
|
-
* - `installedVersion` — the currently installed version string.
|
|
1057
|
-
* - `fsImpl` — `node:fs` surface forwarded to `readCache`.
|
|
744
|
+
* Cache-only stale-version advisory: reads the freshness cache and never hits
|
|
745
|
+
* the network. Always `ok: true`, so it can never fail doctor or CI.
|
|
1058
746
|
*
|
|
1059
747
|
* @param {{
|
|
1060
748
|
* cachePath?: string,
|
|
@@ -1071,7 +759,6 @@ function runVersionCurrent({ cachePath, installedVersion, fsImpl = fs } = {}) {
|
|
|
1071
759
|
try {
|
|
1072
760
|
current = defaultInstalledVersion(fsImpl);
|
|
1073
761
|
} catch {
|
|
1074
|
-
// Without a readable manifest we cannot compare; stay non-fatal.
|
|
1075
762
|
return {
|
|
1076
763
|
ok: true,
|
|
1077
764
|
detail: 'installed version unknown — advisory skipped',
|
|
@@ -1081,7 +768,6 @@ function runVersionCurrent({ cachePath, installedVersion, fsImpl = fs } = {}) {
|
|
|
1081
768
|
|
|
1082
769
|
const cached = readCache({ cachePath: resolvedPath, fs: fsImpl });
|
|
1083
770
|
if (!cached) {
|
|
1084
|
-
// Missing / malformed cache → nothing to advise on yet. Non-fatal.
|
|
1085
771
|
return {
|
|
1086
772
|
ok: true,
|
|
1087
773
|
detail: `v${current} (no cached freshness check yet)`,
|
|
@@ -1099,35 +785,20 @@ function runVersionCurrent({ cachePath, installedVersion, fsImpl = fs } = {}) {
|
|
|
1099
785
|
return { ok: true, detail: `v${current} is up to date` };
|
|
1100
786
|
}
|
|
1101
787
|
|
|
1102
|
-
//
|
|
1103
|
-
// Registry
|
|
1104
|
-
// ---------------------------------------------------------------------------
|
|
788
|
+
// check: merge-driver
|
|
1105
789
|
|
|
1106
790
|
/**
|
|
1107
|
-
* Is this clone's `baselines/*.json` merge driver
|
|
1108
|
-
*
|
|
1109
|
-
*
|
|
1110
|
-
* `.gitattributes`
|
|
1111
|
-
* repo; the driver COMMAND is per-clone `git config`, because git will not
|
|
1112
|
-
* execute a command chosen by whoever wrote the repository. A fresh clone
|
|
1113
|
-
* therefore has the first half and not the second — and git reports nothing
|
|
1114
|
-
* at all, it just quietly falls back to text-merging baselines, which is the
|
|
1115
|
-
* behaviour the driver exists to replace.
|
|
1116
|
-
*
|
|
1117
|
-
* Silent degradation is why this is a doctor check rather than a one-time
|
|
1118
|
-
* install step. It is scoped to repos that opted in: when `.gitattributes`
|
|
1119
|
-
* does not declare the driver, the check passes as skipped, so a consumer
|
|
1120
|
-
* who never installed the quality surface is not told to fix something they
|
|
1121
|
-
* did not ask for.
|
|
791
|
+
* Is this clone's `baselines/*.json` merge driver registered? `.gitattributes`
|
|
792
|
+
* ships with the repo but the driver command is per-clone `git config`, and a
|
|
793
|
+
* missing one silently falls back to a text merge. Skipped when
|
|
794
|
+
* `.gitattributes` does not declare the driver.
|
|
1122
795
|
*
|
|
1123
796
|
* @param {{cwd?: () => string, fsImpl?: typeof fs, runner?: typeof spawn}} [opts]
|
|
1124
797
|
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
1125
798
|
*/
|
|
1126
799
|
export function runMergeDriver({ cwd, fsImpl = fs, runner = spawn } = {}) {
|
|
1127
800
|
const projectRoot = (cwd ?? (() => process.cwd()))();
|
|
1128
|
-
//
|
|
1129
|
-
// reading it from wherever `mandrel doctor` was typed answers about a
|
|
1130
|
-
// different repository (or none).
|
|
801
|
+
// Git runs from projectRoot: the config key is per-clone.
|
|
1131
802
|
const { declared, command } = probeBaselineMergeDriver({
|
|
1132
803
|
projectRoot,
|
|
1133
804
|
fsImpl,
|
|
@@ -1151,27 +822,11 @@ export function runMergeDriver({ cwd, fsImpl = fs, runner = spawn } = {}) {
|
|
|
1151
822
|
}
|
|
1152
823
|
|
|
1153
824
|
/**
|
|
1154
|
-
*
|
|
1155
|
-
*
|
|
1156
|
-
*
|
|
1157
|
-
*
|
|
1158
|
-
*
|
|
1159
|
-
* driver was installed. Git's behaviour then is the same silence a missing key
|
|
1160
|
-
* produces — the driver exits non-zero, git leaves the file conflicted, and the
|
|
1161
|
-
* operator reads it as "baselines conflict again" rather than as a broken
|
|
1162
|
-
* registration. So the check executes what git would execute.
|
|
1163
|
-
*
|
|
1164
|
-
* `--help` is the probe because the driver's real invocation mutates `%A` in
|
|
1165
|
-
* place; the shipped CLI answers `--help` with exit 0 and touches nothing.
|
|
1166
|
-
*
|
|
1167
|
-
* The command is tokenised, never handed to a shell
|
|
1168
|
-
* ({@link parseBaselineMergeDriverCommand}) — it is a config value, and running
|
|
1169
|
-
* it through `shell: true` would make any write to that key arbitrary command
|
|
1170
|
-
* execution (security-baseline § Output & Rendering).
|
|
1171
|
-
*
|
|
1172
|
-
* The probe runs from `projectRoot`, because the command's script path is
|
|
1173
|
-
* relative to the worktree root — which is where git invokes a merge driver
|
|
1174
|
-
* from, and is not necessarily where `mandrel doctor` was typed.
|
|
825
|
+
* Execute the configured driver with `--help` (the real invocation mutates
|
|
826
|
+
* `%A`): a set-but-broken command — typically an absolute node path moved by
|
|
827
|
+
* an nvm/volta bump — fails as silently as an unset key. The command is
|
|
828
|
+
* tokenised, never shell-run, since a config value must not become arbitrary
|
|
829
|
+
* command execution. Runs from projectRoot, where git invokes drivers.
|
|
1175
830
|
*
|
|
1176
831
|
* @param {string} command
|
|
1177
832
|
* @param {typeof spawn} runner
|
|
@@ -1199,32 +854,20 @@ function probeConfiguredDriver(command, runner, projectRoot) {
|
|
|
1199
854
|
};
|
|
1200
855
|
}
|
|
1201
856
|
|
|
1202
|
-
// ---------------------------------------------------------------------------
|
|
1203
857
|
// check: test-credit-path
|
|
1204
|
-
// ---------------------------------------------------------------------------
|
|
1205
858
|
|
|
1206
|
-
/**
|
|
1207
|
-
* The runner whose own green full run deposits the close `test` credit as a
|
|
1208
|
-
* side effect (`.agents/scripts/run-tests.js` → `lib/test-run-credit.js`).
|
|
1209
|
-
*/
|
|
859
|
+
/** The runner whose green full run deposits the close `test` credit itself. */
|
|
1210
860
|
const MANDREL_TEST_RUNNER = 'run-tests.js';
|
|
1211
861
|
|
|
1212
|
-
/**
|
|
1213
|
-
* The deposit that works whatever `npm test` resolves to: it spawns the
|
|
1214
|
-
* project's own suite and stamps the result, so it is honest by construction.
|
|
1215
|
-
*/
|
|
862
|
+
/** Deposits the credit whatever `npm test` resolves to. */
|
|
1216
863
|
const TEST_CREDIT_DEPOSIT_COMMAND =
|
|
1217
864
|
'node .agents/scripts/evidence-gate.js --standalone --scope-id <storyId> --gate test --worktree <workCwd> -- npm test';
|
|
1218
865
|
|
|
1219
|
-
/** Remedy shared by every shape that does not earn the credit on its own. */
|
|
1220
866
|
const TEST_CREDIT_REMEDY = `run the suite through the depositor instead of bare \`npm test\`: ${TEST_CREDIT_DEPOSIT_COMMAND}`;
|
|
1221
867
|
|
|
1222
868
|
/**
|
|
1223
|
-
*
|
|
1224
|
-
*
|
|
1225
|
-
* `project.commands.test`: the close gate's argv is the literal `npm test`, so
|
|
1226
|
-
* the npm script is the command whose shape decides whether a bare run
|
|
1227
|
-
* deposits anything.
|
|
869
|
+
* Read from `package.json`, not `project.commands.test`: the close gate's argv
|
|
870
|
+
* is the literal `npm test`.
|
|
1228
871
|
*
|
|
1229
872
|
* @param {string} projectRoot
|
|
1230
873
|
* @param {typeof fs.readFileSync} readFileImpl
|
|
@@ -1243,20 +886,10 @@ function readProjectTestScript(projectRoot, readFileImpl) {
|
|
|
1243
886
|
}
|
|
1244
887
|
|
|
1245
888
|
/**
|
|
1246
|
-
*
|
|
1247
|
-
*
|
|
1248
|
-
*
|
|
1249
|
-
*
|
|
1250
|
-
* **Always `ok: true`.** A project on `vitest`, `jest` or any other runner is
|
|
1251
|
-
* a supported setup, not a broken install — the only thing it lacks is the
|
|
1252
|
-
* runner-side bonus deposit, and the remedy command covers it. So the check
|
|
1253
|
-
* informs rather than gates, and (unlike every other entry here) carries its
|
|
1254
|
-
* `remedy` alongside a passing verdict; the same guidance also rides in
|
|
1255
|
-
* `detail`, which is the field the doctor prints for a passing check.
|
|
1256
|
-
*
|
|
1257
|
-
* The runner is detected by name, never by executing anything: a script that
|
|
1258
|
-
* reaches `run-tests.js` indirectly reads as "own runner", which errs toward
|
|
1259
|
-
* naming the deposit command — correct on either shape.
|
|
889
|
+
* Does a bare `npm test` reach mandrel's runner and so deposit the close
|
|
890
|
+
* `test` credit? Always `ok: true` — another runner is supported, it just
|
|
891
|
+
* needs the explicit depositor — so the remedy rides a passing verdict and is
|
|
892
|
+
* repeated in `detail`. Detected by name only, never executed.
|
|
1260
893
|
*
|
|
1261
894
|
* @param {{ projectRoot?: string, readFile?: typeof fs.readFileSync }} [opts]
|
|
1262
895
|
* @returns {{ ok: boolean, detail: string, remedy?: string }}
|
|
@@ -1283,14 +916,7 @@ function runTestCreditPath({ projectRoot, readFile = fs.readFileSync } = {}) {
|
|
|
1283
916
|
};
|
|
1284
917
|
}
|
|
1285
918
|
|
|
1286
|
-
/**
|
|
1287
|
-
* Ordered array of doctor checks. Each entry follows the
|
|
1288
|
-
* `{ name: string, run(opts?): { ok: boolean, detail: string, remedy?: string } }` contract.
|
|
1289
|
-
* The doctor runner iterates this array sequentially.
|
|
1290
|
-
*
|
|
1291
|
-
* The `run` functions return plain objects (not Promises) — the doctor runner
|
|
1292
|
-
* may call them with `await` but they do not need to be async.
|
|
1293
|
-
*/
|
|
919
|
+
/** `advisory: true` marks a check whose `run()` never fails. */
|
|
1294
920
|
export const registry = [
|
|
1295
921
|
{
|
|
1296
922
|
name: 'node-version',
|
|
@@ -1338,24 +964,15 @@ export const registry = [
|
|
|
1338
964
|
},
|
|
1339
965
|
{
|
|
1340
966
|
name: 'pin-current',
|
|
1341
|
-
// Fatal, unlike version-current below (Story #4525/#4530): a pin/install
|
|
1342
|
-
// disagreement means the declared dependency does not describe the code
|
|
1343
|
-
// that is running.
|
|
1344
967
|
run: (opts) => runPinCurrent(opts),
|
|
1345
968
|
},
|
|
1346
969
|
{
|
|
1347
970
|
name: 'version-current',
|
|
1348
|
-
// Non-fatal: surfaces a cache-only stale-version advisory. `run()` always
|
|
1349
|
-
// returns ok:true, so it never blocks `mandrel doctor`'s exit code or CI.
|
|
1350
971
|
advisory: true,
|
|
1351
972
|
run: (opts) => runVersionCurrent(opts),
|
|
1352
973
|
},
|
|
1353
974
|
{
|
|
1354
975
|
name: 'test-credit-path',
|
|
1355
|
-
// Non-fatal: `run()` always returns ok:true. A project on its own test
|
|
1356
|
-
// runner is a supported setup that simply has to deposit the close
|
|
1357
|
-
// `test` credit explicitly, so this reports a condition rather than
|
|
1358
|
-
// failing the install (Story #5324).
|
|
1359
976
|
advisory: true,
|
|
1360
977
|
run: (opts) => runTestCreditPath(opts),
|
|
1361
978
|
},
|