mandrel 2.59.0 → 2.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/README.md +21 -19
- package/.agents/agents/acceptance-critic.md +24 -43
- package/.agents/agents/story-worker.md +20 -21
- package/.agents/docs/agentrc-reference.json +5 -84
- package/.agents/docs/configuration.md +48 -132
- package/.agents/docs/workflows.md +2 -2
- package/.agents/instructions.md +5 -8
- package/.agents/rules/ci-remediation.md +41 -8
- package/.agents/rules/gherkin-standards.md +4 -0
- package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
- package/.agents/schemas/agentrc.schema.json +16 -496
- package/.agents/schemas/story-deliver-terminal.schema.json +13 -3
- package/.agents/schemas/validation-evidence.schema.json +2 -1
- package/.agents/scripts/README.md +23 -13
- package/.agents/scripts/acceptance-eval.js +35 -169
- package/.agents/scripts/agents-bootstrap-github.js +27 -129
- package/.agents/scripts/apply-quality-bootstrap.js +4 -40
- package/.agents/scripts/audit-baselines.js +6 -27
- package/.agents/scripts/audit-labels-bootstrap.js +5 -29
- package/.agents/scripts/audit-to-stories.js +91 -361
- package/.agents/scripts/boot-sweep.js +19 -72
- package/.agents/scripts/bootstrap.js +74 -395
- package/.agents/scripts/ceremony-derive.js +10 -41
- package/.agents/scripts/check-arch-cycles.js +14 -64
- package/.agents/scripts/check-baselines.js +8 -48
- package/.agents/scripts/check-context-budget.js +105 -311
- package/.agents/scripts/check-cyclomatic.js +12 -44
- package/.agents/scripts/check-dead-exports.js +13 -64
- package/.agents/scripts/check-doc-links.js +38 -186
- package/.agents/scripts/check-gherkin-corpus.js +24 -127
- package/.agents/scripts/check-test-temp-hygiene.js +28 -169
- package/.agents/scripts/coverage-capture.js +34 -98
- package/.agents/scripts/deliver-light.js +25 -171
- package/.agents/scripts/deliver-recover.js +6 -42
- package/.agents/scripts/deliver-run.js +534 -0
- package/.agents/scripts/diagnose-friction.js +24 -116
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +23 -85
- package/.agents/scripts/file-ci-gap.js +57 -49
- package/.agents/scripts/generate-config-docs.js +30 -170
- package/.agents/scripts/generate-lens-checklists.js +8 -52
- package/.agents/scripts/generate-skills-index.js +14 -112
- package/.agents/scripts/generate-workflows-doc.js +10 -70
- package/.agents/scripts/git-cleanup.js +2 -34
- package/.agents/scripts/lib/Graph.js +24 -81
- package/.agents/scripts/lib/ITicketingProvider.js +47 -143
- package/.agents/scripts/lib/Logger.js +14 -76
- package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
- package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
- package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
- package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
- package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
- package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
- package/.agents/scripts/lib/audit-baselines/read.js +3 -16
- package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
- package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
- package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
- package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
- package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
- package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
- package/.agents/scripts/lib/audit-suite/findings.js +12 -52
- package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
- package/.agents/scripts/lib/audit-suite/index.js +1 -15
- package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
- package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
- package/.agents/scripts/lib/audit-suite/runner.js +13 -43
- package/.agents/scripts/lib/audit-suite/selector.js +49 -349
- package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
- package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
- package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
- package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
- package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
- package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
- package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
- package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
- package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
- package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
- package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
- package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
- package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
- package/.agents/scripts/lib/baseline-loader.js +12 -51
- package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
- package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
- package/.agents/scripts/lib/baselines/components.js +10 -61
- package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
- package/.agents/scripts/lib/baselines/crap-preview-incremental.js +7 -19
- package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
- package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
- package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
- package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
- package/.agents/scripts/lib/baselines/envelope.js +13 -129
- package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
- package/.agents/scripts/lib/baselines/git-base.js +23 -142
- package/.agents/scripts/lib/baselines/kernel.js +11 -111
- package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
- package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
- package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
- package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
- package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
- package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
- package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
- package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
- package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
- package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
- package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
- package/.agents/scripts/lib/baselines/path-canon.js +19 -128
- package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
- package/.agents/scripts/lib/baselines/reader.js +14 -107
- package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
- package/.agents/scripts/lib/baselines/scope.js +11 -135
- package/.agents/scripts/lib/baselines/writer.js +16 -149
- package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
- package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
- package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
- package/.agents/scripts/lib/bdd-step-index.js +26 -100
- package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
- package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
- package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
- package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
- package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
- package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
- package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
- package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
- package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
- package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
- package/.agents/scripts/lib/bootstrap/summary.js +1 -8
- package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
- package/.agents/scripts/lib/branch-name-guard.js +4 -23
- package/.agents/scripts/lib/changed-files.js +39 -121
- package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
- package/.agents/scripts/lib/checks/index.js +18 -101
- package/.agents/scripts/lib/checks/loop-health.js +11 -53
- package/.agents/scripts/lib/checks/state.js +16 -91
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
- package/.agents/scripts/lib/child-exec.js +39 -108
- package/.agents/scripts/lib/cli/standard-args.js +9 -116
- package/.agents/scripts/lib/cli-args.js +31 -146
- package/.agents/scripts/lib/cli-usage.js +5 -27
- package/.agents/scripts/lib/cli-utils.js +2 -12
- package/.agents/scripts/lib/close-validation/commands.js +13 -76
- package/.agents/scripts/lib/close-validation/gates.js +92 -331
- package/.agents/scripts/lib/close-validation/process.js +121 -151
- package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
- package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
- package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
- package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
- package/.agents/scripts/lib/close-validation/runner.js +53 -110
- package/.agents/scripts/lib/command-header.js +6 -28
- package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
- package/.agents/scripts/lib/config/baselines.js +3 -14
- package/.agents/scripts/lib/config/ci.js +8 -38
- package/.agents/scripts/lib/config/commands.js +1 -15
- package/.agents/scripts/lib/config/defaults.js +4 -33
- package/.agents/scripts/lib/config/delivery-routing.js +6 -34
- package/.agents/scripts/lib/config/explain.js +10 -83
- package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +3 -31
- package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
- package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
- package/.agents/scripts/lib/config/gates/index.js +2 -17
- package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
- package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
- package/.agents/scripts/lib/config/gates/shared.js +4 -64
- package/.agents/scripts/lib/config/github.js +4 -22
- package/.agents/scripts/lib/config/limits.js +4 -57
- package/.agents/scripts/lib/config/paths.js +2 -21
- package/.agents/scripts/lib/config/qa.js +4 -38
- package/.agents/scripts/lib/config/quality.js +76 -432
- package/.agents/scripts/lib/config/runners.js +12 -56
- package/.agents/scripts/lib/config/runtime.js +13 -57
- package/.agents/scripts/lib/config/shared.js +2 -16
- package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
- package/.agents/scripts/lib/config/temp-paths.js +40 -280
- package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
- package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
- package/.agents/scripts/lib/config-resolver.js +11 -52
- package/.agents/scripts/lib/config-schema-shared.js +1 -4
- package/.agents/scripts/lib/config-settings-schema-delivery.js +16 -291
- package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
- package/.agents/scripts/lib/config-settings-schema.js +37 -274
- package/.agents/scripts/lib/coverage-baseline.js +20 -110
- package/.agents/scripts/lib/coverage-capture-fullscope.js +18 -35
- package/.agents/scripts/lib/coverage-capture-incremental.js +15 -45
- package/.agents/scripts/lib/coverage-capture-usage.js +8 -25
- package/.agents/scripts/lib/coverage-capture.js +99 -224
- package/.agents/scripts/lib/coverage-utils.js +14 -79
- package/.agents/scripts/lib/cpu-pool.js +17 -123
- package/.agents/scripts/lib/crap-baseline-join.js +16 -88
- package/.agents/scripts/lib/crap-coordinates.js +6 -25
- package/.agents/scripts/lib/crap-engine.js +40 -153
- package/.agents/scripts/lib/crap-method-identity.js +16 -78
- package/.agents/scripts/lib/crap-utils.js +31 -155
- package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
- package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
- package/.agents/scripts/lib/dead-exports-knip.js +18 -56
- package/.agents/scripts/lib/dead-exports-mode.js +5 -24
- package/.agents/scripts/lib/degraded-mode.js +3 -26
- package/.agents/scripts/lib/dependency-parser.js +8 -40
- package/.agents/scripts/lib/dependency-version.js +13 -35
- package/.agents/scripts/lib/detect-package-manager.js +6 -36
- package/.agents/scripts/lib/doc-tiers.js +22 -124
- package/.agents/scripts/lib/duplicate-search.js +8 -72
- package/.agents/scripts/lib/env-loader.js +5 -27
- package/.agents/scripts/lib/error-redactor.js +6 -31
- package/.agents/scripts/lib/errors/index.js +2 -22
- package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
- package/.agents/scripts/lib/escomplex-kernel.js +21 -123
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +94 -419
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -149
- package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
- package/.agents/scripts/lib/findings/classify-finding.js +14 -69
- package/.agents/scripts/lib/findings/promote-finding.js +14 -112
- package/.agents/scripts/lib/findings/provenance-field.js +11 -52
- package/.agents/scripts/lib/findings/route-finding.js +37 -255
- package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
- package/.agents/scripts/lib/findings/severity.js +18 -104
- package/.agents/scripts/lib/format-generated-json.js +12 -44
- package/.agents/scripts/lib/full-suite-lock.js +160 -429
- package/.agents/scripts/lib/full-suite-queue.js +213 -0
- package/.agents/scripts/lib/gates/baseline-store.js +5 -9
- package/.agents/scripts/lib/gates/friction.js +1 -3
- package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
- package/.agents/scripts/lib/gh-exec.js +123 -191
- package/.agents/scripts/lib/git/cached-fetch.js +9 -52
- package/.agents/scripts/lib/git/sync-from-base.js +15 -107
- package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
- package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
- package/.agents/scripts/lib/git-utils.js +37 -161
- package/.agents/scripts/lib/github/framework-repo.js +8 -71
- package/.agents/scripts/lib/github-url.js +2 -17
- package/.agents/scripts/lib/import-graph.js +11 -38
- package/.agents/scripts/lib/install-cmd-parser.js +4 -13
- package/.agents/scripts/lib/json-utils.js +3 -18
- package/.agents/scripts/lib/label-constants.js +16 -111
- package/.agents/scripts/lib/label-taxonomy.js +4 -30
- package/.agents/scripts/lib/maintainability-engine.js +12 -80
- package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
- package/.agents/scripts/lib/maintainability-utils.js +16 -92
- package/.agents/scripts/lib/mandrel-catalog.js +12 -70
- package/.agents/scripts/lib/notifications/notifier.js +13 -38
- package/.agents/scripts/lib/npm-scripts.js +4 -23
- package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
- package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
- package/.agents/scripts/lib/observability/signal-validator.js +5 -37
- package/.agents/scripts/lib/observability/signals-writer.js +11 -121
- package/.agents/scripts/lib/observability/source-classifier.js +22 -203
- package/.agents/scripts/lib/observability/terse-result.js +14 -47
- package/.agents/scripts/lib/onboard/init-tail.js +13 -74
- package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
- package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
- package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +28 -156
- package/.agents/scripts/lib/orchestration/change-set.js +7 -36
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
- package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
- package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
- package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
- package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
- package/.agents/scripts/lib/orchestration/check-state.js +92 -0
- package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +121 -157
- package/.agents/scripts/lib/orchestration/code-review.js +24 -128
- package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
- package/.agents/scripts/lib/orchestration/complexity-gate.js +118 -462
- package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
- package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
- package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
- package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
- package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
- package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
- package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
- package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
- package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
- package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
- package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
- package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
- package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
- package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
- package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
- package/.agents/scripts/lib/orchestration/light-suitability.js +37 -307
- package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
- package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
- package/.agents/scripts/lib/orchestration/plan-context.js +55 -318
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
- package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
- package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
- package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
- package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
- package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +16 -78
- package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
- package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
- package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
- package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +71 -289
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +96 -362
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +9 -39
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +60 -186
- package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
- package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
- package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
- package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
- package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
- package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
- package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
- package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
- package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
- package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
- package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
- package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
- package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
- package/.agents/scripts/lib/orchestration/review-depth.js +12 -91
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
- package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
- package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
- package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
- package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
- package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
- package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
- package/.agents/scripts/lib/orchestration/run-epilogue.js +245 -326
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +55 -159
- package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
- package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
- package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +20 -82
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +136 -486
- package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
- package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +96 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +180 -273
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
- package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
- package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
- package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
- package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -200
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +167 -252
- package/.agents/scripts/lib/orchestration/story-init-envelope.js +52 -0
- package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
- package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
- package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -135
- package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
- package/.agents/scripts/lib/orchestration/ticket-validator.js +63 -344
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -261
- package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
- package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
- package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
- package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
- package/.agents/scripts/lib/path-security.js +3 -6
- package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
- package/.agents/scripts/lib/preflight-runner.js +13 -69
- package/.agents/scripts/lib/process-group.js +143 -0
- package/.agents/scripts/lib/project-root.js +2 -8
- package/.agents/scripts/lib/provider-factory.js +2 -25
- package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
- package/.agents/scripts/lib/qa/qa-session.js +15 -69
- package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
- package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
- package/.agents/scripts/lib/reserved-test-ids.js +9 -47
- package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
- package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
- package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
- package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
- package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
- package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
- package/.agents/scripts/lib/signals/detectors/common.js +12 -38
- package/.agents/scripts/lib/signals/index.js +2 -19
- package/.agents/scripts/lib/signals/schema.js +14 -109
- package/.agents/scripts/lib/signals/write.js +2 -11
- package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
- package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
- package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
- package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
- package/.agents/scripts/lib/single-story-sweep.js +14 -97
- package/.agents/scripts/lib/skills/parse-skill.js +13 -59
- package/.agents/scripts/lib/skills/skills-index.js +8 -29
- package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
- package/.agents/scripts/lib/source-extensions.js +11 -42
- package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
- package/.agents/scripts/lib/stdio-flush.js +9 -36
- package/.agents/scripts/lib/story-adjacency.js +8 -40
- package/.agents/scripts/lib/story-body/body-format-lints.js +51 -66
- package/.agents/scripts/lib/story-body/footer-block.js +11 -44
- package/.agents/scripts/lib/story-body/story-body.js +123 -344
- package/.agents/scripts/lib/temp-retention.js +42 -143
- package/.agents/scripts/lib/templates/decomposer-prompts.js +18 -80
- package/.agents/scripts/lib/test-env.js +12 -65
- package/.agents/scripts/lib/test-run-credit.js +10 -65
- package/.agents/scripts/lib/test-runner-contract.js +19 -74
- package/.agents/scripts/lib/test-temp.js +38 -184
- package/.agents/scripts/lib/test-tiers.js +12 -96
- package/.agents/scripts/lib/ticket-body-sections.js +21 -96
- package/.agents/scripts/lib/transpile.js +15 -74
- package/.agents/scripts/lib/util/concurrent-map.js +6 -25
- package/.agents/scripts/lib/util/parse-id-list.js +8 -34
- package/.agents/scripts/lib/util/poll-loop.js +8 -28
- package/.agents/scripts/lib/util/with-timeout.js +2 -11
- package/.agents/scripts/lib/validation-evidence.js +21 -96
- package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
- package/.agents/scripts/lib/wave-runner/live-probe.js +67 -209
- package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
- package/.agents/scripts/lib/workers/crap-worker.js +11 -64
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
- package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
- package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
- package/.agents/scripts/lib/workflow-closure.js +22 -105
- package/.agents/scripts/lib/workspace-provisioner.js +16 -54
- package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
- package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
- package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
- package/.agents/scripts/lib/worktree-manager.js +15 -40
- package/.agents/scripts/lint-issue-body.js +12 -68
- package/.agents/scripts/mandrel-update-preflight.js +10 -70
- package/.agents/scripts/merge-baseline.js +30 -105
- package/.agents/scripts/nav-registry-diff.js +22 -108
- package/.agents/scripts/notify.js +12 -69
- package/.agents/scripts/plan-context.js +97 -92
- package/.agents/scripts/plan-critics.js +12 -66
- package/.agents/scripts/plan-persist.js +71 -137
- package/.agents/scripts/plan-run-epilogue.js +20 -43
- package/.agents/scripts/pr-watch-with-update.js +79 -263
- package/.agents/scripts/providers/github/auth.js +3 -8
- package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
- package/.agents/scripts/providers/github/board-add.js +5 -21
- package/.agents/scripts/providers/github/branch-protection.js +11 -43
- package/.agents/scripts/providers/github/cache.js +2 -14
- package/.agents/scripts/providers/github/comments.js +7 -40
- package/.agents/scripts/providers/github/compose.js +3 -19
- package/.agents/scripts/providers/github/errors.js +22 -125
- package/.agents/scripts/providers/github/issues.js +31 -123
- package/.agents/scripts/providers/github/labels.js +24 -124
- package/.agents/scripts/providers/github/mappers.js +5 -27
- package/.agents/scripts/providers/github/merge-methods.js +3 -22
- package/.agents/scripts/providers/github/project-board.js +2 -17
- package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
- package/.agents/scripts/providers/github/request-helpers.js +5 -32
- package/.agents/scripts/providers/github/search-budget.js +9 -39
- package/.agents/scripts/providers/github/search-query.js +5 -26
- package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
- package/.agents/scripts/providers/github/sub-issues.js +7 -36
- package/.agents/scripts/providers/github/tickets.js +32 -134
- package/.agents/scripts/providers/github.js +18 -59
- package/.agents/scripts/prune-plan-run-labels.js +12 -46
- package/.agents/scripts/quality-preview.js +35 -220
- package/.agents/scripts/resolve-doc-tiers.js +3 -26
- package/.agents/scripts/resolve-stories.js +16 -67
- package/.agents/scripts/resync-status-column.js +6 -25
- package/.agents/scripts/run-tests.js +29 -104
- package/.agents/scripts/single-story-close.js +23 -135
- package/.agents/scripts/single-story-confirm-merge.js +32 -139
- package/.agents/scripts/single-story-init.js +47 -259
- package/.agents/scripts/stories-wave-tick.js +179 -415
- package/.agents/scripts/sync-agentrc.js +3 -21
- package/.agents/scripts/sync-claude-agents.js +9 -55
- package/.agents/scripts/sync-claude-commands.js +20 -110
- package/.agents/scripts/test-wrapper.js +6 -43
- package/.agents/scripts/update-coverage-baseline.js +5 -22
- package/.agents/scripts/update-crap-baseline.js +7 -30
- package/.agents/scripts/update-duplication-baseline.js +16 -92
- package/.agents/scripts/update-maintainability-baseline.js +8 -62
- package/.agents/scripts/update-ticket-state.js +1 -7
- package/.agents/scripts/validate-skills.js +6 -26
- package/.agents/skills/core/gates-and-baselines/reference.md +0 -1
- package/.agents/skills/skills.index.json +2 -2
- package/.agents/skills/stack/qa/playwright/SKILL.md +26 -0
- package/.agents/templates/agent-protocol.md +2 -2
- package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
- package/.agents/workflows/audit-accessibility.md +4 -7
- package/.agents/workflows/audit-adrs.md +3 -6
- package/.agents/workflows/audit-architecture.md +3 -11
- package/.agents/workflows/audit-baselines.md +6 -9
- package/.agents/workflows/audit-clean-code.md +8 -12
- package/.agents/workflows/audit-data-model.md +3 -7
- package/.agents/workflows/audit-dependencies.md +4 -7
- package/.agents/workflows/audit-devops.md +4 -8
- package/.agents/workflows/audit-documentation.md +1 -4
- package/.agents/workflows/audit-mobile.md +4 -7
- package/.agents/workflows/audit-navigability.md +3 -6
- package/.agents/workflows/audit-performance.md +2 -4
- package/.agents/workflows/audit-privacy.md +4 -7
- package/.agents/workflows/audit-quality.md +4 -7
- package/.agents/workflows/audit-security.md +4 -7
- package/.agents/workflows/audit-seo.md +4 -7
- package/.agents/workflows/audit-sre.md +4 -7
- package/.agents/workflows/audit-to-stories.md +17 -30
- package/.agents/workflows/audit-ux-ui.md +4 -7
- package/.agents/workflows/helpers/acceptance-self-eval.md +84 -157
- package/.agents/workflows/helpers/audit-lens-core.md +1 -1
- package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
- package/.agents/workflows/helpers/code-review.md +4 -2
- package/.agents/workflows/helpers/deliver-digest.md +37 -28
- package/.agents/workflows/helpers/deliver-light.md +92 -101
- package/.agents/workflows/helpers/deliver-reference.md +162 -220
- package/.agents/workflows/helpers/deliver-story-reference.md +197 -607
- package/.agents/workflows/helpers/deliver-story.md +17 -18
- package/.agents/workflows/helpers/plan-reference.md +125 -167
- package/.agents/workflows/helpers/qa-core.md +12 -0
- package/.agents/workflows/mandrel-deliver.md +47 -31
- package/.agents/workflows/mandrel-plan.md +22 -21
- package/.agents/workflows/mandrel-update.md +36 -21
- package/.agents/workflows/memory-consolidate.md +1 -1
- package/.agents/workflows/qa-assist.md +27 -71
- package/.agents/workflows/qa-explore.md +19 -59
- package/.agents/workflows/qa-run.md +11 -33
- package/README.md +1 -1
- package/bin/mandrel.js +5 -46
- package/bin/postinstall.js +18 -107
- package/docs/CHANGELOG.md +60 -0
- package/lib/cli/doctor.js +11 -71
- package/lib/cli/init.js +26 -165
- package/lib/cli/migrate.js +5 -64
- package/lib/cli/registry.js +84 -467
- package/lib/cli/sync-agents.js +4 -64
- package/lib/cli/sync-commands.js +11 -64
- package/lib/cli/sync.js +34 -213
- package/lib/cli/uninstall.js +40 -219
- package/lib/cli/update.js +326 -523
- package/lib/cli/version-check.js +8 -72
- package/lib/cli/version-helpers.js +14 -87
- package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
- package/lib/migrations/index.js +17 -92
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
- package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
- package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
- package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
- package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
- package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
- package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
- package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +21 -0
- package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
- package/package.json +17 -14
- package/.agents/docs/SDLC.md +0 -590
- package/.agents/docs/quality-gates.md +0 -1179
- package/.agents/rules/known-tooling-behavior.md +0 -150
- package/.agents/rules/orchestration-error-handling.md +0 -61
- package/.agents/rules/test-seams.md +0 -59
- package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
- package/.agents/schemas/baselines/lint.schema.json +0 -47
- package/.agents/schemas/model-attribution.schema.json +0 -53
- package/.agents/scripts/check-action-pinning.js +0 -260
- package/.agents/scripts/check-audit-attribution.js +0 -302
- package/.agents/scripts/check-baseline-drift.js +0 -211
- package/.agents/scripts/check-baseline-scope.js +0 -362
- package/.agents/scripts/check-generated-validator.js +0 -202
- package/.agents/scripts/check-knip-entries.js +0 -159
- package/.agents/scripts/check-lifecycle-lint.js +0 -294
- package/.agents/scripts/check-pinned-override-notes.js +0 -102
- package/.agents/scripts/check-schema-references.js +0 -366
- package/.agents/scripts/check-test-portability.js +0 -512
- package/.agents/scripts/check-workflow-citations.js +0 -332
- package/.agents/scripts/check-workflow-cli-lint.js +0 -299
- package/.agents/scripts/check-workflow-timeouts.js +0 -291
- package/.agents/scripts/install-matrix-assert.js +0 -326
- package/.agents/scripts/lib/audit-advisories.js +0 -195
- package/.agents/scripts/lib/audit-attribution.js +0 -134
- package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
- package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
- package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
- package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
- package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
- package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
- package/.agents/scripts/lib/c8-cli-path.js +0 -21
- package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
- package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
- package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
- package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
- package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
- package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
- package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
- package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
- package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
- package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
- package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
- package/.agents/scripts/lib/fs-walk.js +0 -52
- package/.agents/scripts/lib/knip-config-resolver.js +0 -181
- package/.agents/scripts/lib/knip-entry-sync.js +0 -452
- package/.agents/scripts/lib/orchestration/model-attribution.js +0 -418
- package/.agents/scripts/lib/orchestration/story-plan-state.js +0 -33
- package/.agents/scripts/lib/orchestration/structured-comment-parser.js +0 -67
- package/.agents/scripts/lib/pinned-override-notes.js +0 -88
- package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
- package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
- package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
- package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
- package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
- package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
- package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
- package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
- package/.agents/scripts/lib/test-isolate/runner.js +0 -483
- package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
- package/.agents/scripts/lib/test-profile/render-report.js +0 -45
- package/.agents/scripts/lint-label-vocabulary.js +0 -214
- package/.agents/scripts/post-structured-comment.js +0 -127
- package/.agents/scripts/provision-git-hooks.js +0 -85
- package/.agents/scripts/prune-baseline-orphans.js +0 -181
- package/.agents/scripts/run-coverage.js +0 -197
- package/.agents/scripts/run-lint.js +0 -133
- package/.agents/scripts/run-test-profile.js +0 -129
- package/.agents/scripts/run-verify.js +0 -118
- package/.agents/scripts/test-isolate.js +0 -55
- package/.agents/scripts/update-dead-exports-baseline.js +0 -321
|
@@ -1,22 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* lib/audit-suite/selector.js — `selectAudits` rule-matching core.
|
|
3
|
-
*
|
|
4
|
-
* Extracted from `.agents/scripts/select-audits.js` (Story #1083, Epic
|
|
5
|
-
* #1072) so the audit-suite SDK barrel at `./index.js` can re-export it
|
|
6
|
-
* without importing upward from a top-level CLI file.
|
|
7
|
-
*
|
|
8
|
-
* Pure (modulo `gitSpawn`) — exposed helpers are:
|
|
9
|
-
* - matchesFilePattern — single file × single glob (picomatch, `dot`)
|
|
10
|
-
* - matchesAnyFilePattern — file list × pattern list, short-circuiting
|
|
11
|
-
* - selectSensitivePathClasses — change set × the manifest's `sensitivePaths`
|
|
12
|
-
* block; the review-depth derivation's matcher
|
|
13
|
-
* - selectAudits — main entry; reads audit-rules.json, runs `git
|
|
14
|
-
* diff --name-only`, applies keyword + glob
|
|
15
|
-
* rules.
|
|
16
|
-
*
|
|
17
|
-
* All rule-matching lives here; the former `select-audits.js` CLI wrapper
|
|
18
|
-
* was retired in #4482 (consumers call `selectAudits` via the barrel).
|
|
19
|
-
*/
|
|
1
|
+
/** Audit-lens selection over `audit-rules.json`. */
|
|
20
2
|
|
|
21
3
|
import { readdirSync, readFileSync } from 'node:fs';
|
|
22
4
|
import fs from 'node:fs/promises';
|
|
@@ -31,40 +13,17 @@ import { readAuditRulesSync } from './audit-rules-reader.js';
|
|
|
31
13
|
const DEFAULT_GIT_TIMEOUT_MS = 30000;
|
|
32
14
|
|
|
33
15
|
/**
|
|
34
|
-
*
|
|
35
|
-
* `scope` field in [`audit-rules.json`](../../../schemas/audit-rules.json).
|
|
36
|
-
* This frozen tuple is the single source of truth for the tier vocabulary the
|
|
37
|
-
* schema's `scope` enum enforces and {@link resolveLensTier} returns:
|
|
38
|
-
*
|
|
39
|
-
* - `local` — decidable from a single Story's diff; verified at
|
|
40
|
-
* write-time and Story-scope review, not re-run at Epic close.
|
|
41
|
-
* - `cumulative` — only decidable across the Epic's combined diff; verified
|
|
42
|
-
* at Epic close.
|
|
43
|
-
* - `global` — evaluates a whole-product property regardless of the diff;
|
|
44
|
-
* verified at Epic close, exempt from change-set narrowing.
|
|
16
|
+
* Lens `scope` vocabulary; `global` is never narrowed by change set.
|
|
45
17
|
*
|
|
46
18
|
* @type {readonly ['local', 'cumulative', 'global']}
|
|
47
19
|
*/
|
|
48
20
|
export const LENS_TIERS = Object.freeze(['local', 'cumulative', 'global']);
|
|
49
21
|
|
|
50
22
|
/**
|
|
51
|
-
*
|
|
52
|
-
* This is the pure read-side of the `scope` field (Epic #4405, Story #4407)
|
|
53
|
-
* that replaced the former `alwaysRun` special case: every downstream tier —
|
|
54
|
-
* write-time checklist threading, Story-scope review, the Epic-close roster
|
|
55
|
-
* split — routes off this one field instead of a maintained prose constraint.
|
|
56
|
-
*
|
|
57
|
-
* Deterministic given the on-disk manifest: it reads the same
|
|
58
|
-
* `audit-rules.json` that {@link selectAudits} consumes (resolved through the
|
|
59
|
-
* project's configured `schemasRoot`), looks up the lens, and returns its
|
|
60
|
-
* `scope`. It takes no ticket, runs no git, and has no side effects.
|
|
61
|
-
*
|
|
62
|
-
* @param {string} lens Lens key registered in `audit-rules.json`
|
|
63
|
-
* (e.g. `audit-clean-code`).
|
|
23
|
+
* @param {string} lens Lens key registered in `audit-rules.json`.
|
|
64
24
|
* @returns {'local' | 'cumulative' | 'global'} The lens's declared tier.
|
|
65
|
-
* @throws {Error} When
|
|
66
|
-
*
|
|
67
|
-
* {@link LENS_TIERS}.
|
|
25
|
+
* @throws {Error} When the lens is unregistered, the manifest is unreadable, or
|
|
26
|
+
* its scope is outside {@link LENS_TIERS}.
|
|
68
27
|
*/
|
|
69
28
|
export function resolveLensTier(lens) {
|
|
70
29
|
const rulesData = readAuditRulesSync();
|
|
@@ -87,30 +46,8 @@ export function resolveLensTier(lens) {
|
|
|
87
46
|
}
|
|
88
47
|
|
|
89
48
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* review (Epic #4405, Story #4409): a lens is selected iff
|
|
93
|
-
* `resolveLensTier(lens) === 'local'` **and** the pure
|
|
94
|
-
* {@link matchesAnyFilePattern} matcher hits at least one of `changedFiles`
|
|
95
|
-
* against the lens's registered `triggers.filePatterns`.
|
|
96
|
-
*
|
|
97
|
-
* This deliberately does **not** call {@link selectAudits}: `selectAudits`
|
|
98
|
-
* unions in keyword-matched and gate-scoped lenses and has no per-tier gate,
|
|
99
|
-
* so it would widen the roster beyond the local, footprint-matched set the
|
|
100
|
-
* shift-left Story-scope tier owns. A local lens with a universal
|
|
101
|
-
* `filePatterns` glob (e.g. `audit-clean-code`, whose sole pattern matches
|
|
102
|
-
* every path) matches every change set here, so its concern is verified at
|
|
103
|
-
* BOTH innermost tiers — the
|
|
104
|
-
* write-time checklist threading and this Story-scope lens pass — and excluded
|
|
105
|
-
* from the retired Epic-close roster (local lenses stay Story-scope only).
|
|
106
|
-
* A local lens with an empty `filePatterns` list matches nothing here, so a
|
|
107
|
-
* diff matching no local lens's patterns yields an empty roster and adds no
|
|
108
|
-
* lens work.
|
|
109
|
-
*
|
|
110
|
-
* Pure over its injected seams: `injectedRules` skips the disk read of the
|
|
111
|
-
* manifest and `resolveLensTierFn` overrides the tier resolver, so callers can
|
|
112
|
-
* exercise the selection without touching the filesystem. Selection order
|
|
113
|
-
* follows the manifest's declaration order, which is deterministic.
|
|
49
|
+
* Local-tier lenses whose `filePatterns` hit the change set (not
|
|
50
|
+
* {@link selectAudits}, which would widen it with keyword matches).
|
|
114
51
|
*
|
|
115
52
|
* @param {{
|
|
116
53
|
* changedFiles?: string[],
|
|
@@ -140,25 +77,7 @@ export function selectLocalLenses({
|
|
|
140
77
|
}
|
|
141
78
|
|
|
142
79
|
/**
|
|
143
|
-
*
|
|
144
|
-
* `sensitivePaths` block of [`audit-rules.json`](../../../schemas/audit-rules.json).
|
|
145
|
-
*
|
|
146
|
-
* This is the matcher behind the close-time review-depth derivation
|
|
147
|
-
* (`review-depth.js#deriveChangeLevel`, Story #4542): a change set intersecting
|
|
148
|
-
* any registered class's globs is *observably* sensitive — auth, a migration, a
|
|
149
|
-
* billing path — and earns a deep pass however narrow the diff is. The classes
|
|
150
|
-
* and their globs live in the manifest next to the lens `triggers.filePatterns`
|
|
151
|
-
* precisely so an operator can extend them without a code change, and matching
|
|
152
|
-
* runs through the same {@link matchesAnyFilePattern} picomatch machinery rather
|
|
153
|
-
* than a second matcher with its own glob semantics.
|
|
154
|
-
*
|
|
155
|
-
* An empty change set, an absent `sensitivePaths` block, or a class whose globs
|
|
156
|
-
* match nothing all contribute no class — the caller then resolves depth from
|
|
157
|
-
* diff width alone.
|
|
158
|
-
*
|
|
159
|
-
* Pure over its injected seam: `injectedRules` skips the manifest disk read.
|
|
160
|
-
* Selection order follows the manifest's declaration order, which is
|
|
161
|
-
* deterministic.
|
|
80
|
+
* Manifest `sensitivePaths` classes the change set touches (review depth).
|
|
162
81
|
*
|
|
163
82
|
* @param {{
|
|
164
83
|
* changedFiles?: string[],
|
|
@@ -184,17 +103,6 @@ export function selectSensitivePathClasses({
|
|
|
184
103
|
}
|
|
185
104
|
|
|
186
105
|
/**
|
|
187
|
-
* Resolve the consumer's navigability route globs from the resolved config.
|
|
188
|
-
* Reads `delivery.quality.navigability.routeGlobs` — the route-tree SSOT the
|
|
189
|
-
* navigability lens enumerates. Returns an empty array when the block (or any
|
|
190
|
-
* ancestor) is absent, so an unconfigured consumer contributes no web-surface
|
|
191
|
-
* evidence (Epic #4131 — "no-op when unconfigured").
|
|
192
|
-
*
|
|
193
|
-
* Module-local: the sole reader is {@link hasWebSurface}. It was previously
|
|
194
|
-
* exported alongside a route-added routing seam that Story #4926 removed —
|
|
195
|
-
* lens routing is decided by the `scope` field in `audit-rules.json`, never by
|
|
196
|
-
* a second predicate here.
|
|
197
|
-
*
|
|
198
106
|
* @param {object|null|undefined} config Resolved `.agentrc.json` wrapper.
|
|
199
107
|
* @returns {string[]} Route globs, or `[]` when unconfigured.
|
|
200
108
|
*/
|
|
@@ -203,12 +111,7 @@ function resolveNavigabilityRouteGlobs(config) {
|
|
|
203
111
|
return Array.isArray(globs) ? globs.filter((g) => typeof g === 'string') : [];
|
|
204
112
|
}
|
|
205
113
|
|
|
206
|
-
/**
|
|
207
|
-
* Package names (or scope/name segments of them) that declare a **web
|
|
208
|
-
* rendering surface**. Matched against the consumer's root `package.json`
|
|
209
|
-
* `dependencies` + `devDependencies` keys, segment-wise, so `@angular/core`
|
|
210
|
-
* matches via `angular` and `@remix-run/react` via `react`.
|
|
211
|
-
*/
|
|
114
|
+
/** Matched segment-wise against dependency names (`@angular/core` → `angular`). */
|
|
212
115
|
const WEB_FRAMEWORK_PACKAGES = Object.freeze([
|
|
213
116
|
'react',
|
|
214
117
|
'next',
|
|
@@ -223,15 +126,9 @@ const WEB_FRAMEWORK_PACKAGES = Object.freeze([
|
|
|
223
126
|
'angular',
|
|
224
127
|
]);
|
|
225
128
|
|
|
226
|
-
/** File extensions whose presence in the source tree implies a web surface. */
|
|
227
129
|
const WEB_ASSET_EXTENSIONS = Object.freeze(['.html', '.css', '.jsx', '.tsx']);
|
|
228
130
|
|
|
229
|
-
/**
|
|
230
|
-
* Directories the web-surface file scan never descends into. `node_modules` is
|
|
231
|
-
* the load-bearing one (a dependency's bundled `.css` says nothing about the
|
|
232
|
-
* consumer's own surface); the test directories are excluded because a fixture
|
|
233
|
-
* `.html` is a test artifact, not a shipped page.
|
|
234
|
-
*/
|
|
131
|
+
/** A dependency's or fixture's asset says nothing about the consumer's own surface. */
|
|
235
132
|
const WEB_SCAN_SKIP_DIRS = Object.freeze([
|
|
236
133
|
'node_modules',
|
|
237
134
|
'.git',
|
|
@@ -251,34 +148,24 @@ const WEB_SCAN_SKIP_DIRS = Object.freeze([
|
|
|
251
148
|
'fixtures',
|
|
252
149
|
]);
|
|
253
150
|
|
|
254
|
-
/** Scan bounds — the probe is a cheap heuristic, not an exhaustive crawl. */
|
|
255
151
|
const WEB_SCAN_MAX_DEPTH = 6;
|
|
256
152
|
const WEB_SCAN_MAX_ENTRIES = 4000;
|
|
257
153
|
|
|
258
154
|
/**
|
|
259
|
-
*
|
|
260
|
-
* keyed by project root. The config half ({@link resolveNavigabilityRouteGlobs})
|
|
261
|
-
* is a free object read and is deliberately NOT memoized, so a caller passing a
|
|
262
|
-
* different config never reads a stale answer.
|
|
155
|
+
* Filesystem half only, so a different config never reads a stale answer.
|
|
263
156
|
*
|
|
264
157
|
* @type {Map<string, boolean>}
|
|
265
158
|
*/
|
|
266
159
|
const _webSurfaceFsCache = new Map();
|
|
267
160
|
|
|
268
|
-
/** Test-only
|
|
161
|
+
/** Test-only. */
|
|
269
162
|
export function _resetWebSurfaceCache() {
|
|
270
163
|
_webSurfaceFsCache.clear();
|
|
271
164
|
}
|
|
272
165
|
|
|
273
166
|
/**
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
* {@link declaresWebFramework} and {@link declaresOrmDependency}.
|
|
277
|
-
*
|
|
278
|
-
* Returns `null` — *indeterminate* — when the manifest exists but cannot be
|
|
279
|
-
* read or parsed; callers fail open on that. A genuinely absent manifest
|
|
280
|
-
* (`ENOENT`) is determinate: there is no declaration, so there is no signal,
|
|
281
|
-
* and the file scan gets its turn.
|
|
167
|
+
* Tri-state: `null` when the manifest exists but is unreadable/unparseable
|
|
168
|
+
* (callers fail open); an absent manifest is a determinate `false`.
|
|
282
169
|
*
|
|
283
170
|
* @param {string} root
|
|
284
171
|
* @param {readonly string[]} packageList
|
|
@@ -311,10 +198,6 @@ function declaresDependencyIn(root, packageList) {
|
|
|
311
198
|
}
|
|
312
199
|
|
|
313
200
|
/**
|
|
314
|
-
* True when the root `package.json` declares a web-framework dependency.
|
|
315
|
-
* Tri-state contract per {@link declaresDependencyIn}; the fail-open caller
|
|
316
|
-
* is {@link hasWebSurface}.
|
|
317
|
-
*
|
|
318
201
|
* @param {string} root
|
|
319
202
|
* @returns {boolean|null}
|
|
320
203
|
*/
|
|
@@ -323,16 +206,8 @@ function declaresWebFramework(root) {
|
|
|
323
206
|
}
|
|
324
207
|
|
|
325
208
|
/**
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
* Returns `null` — *indeterminate* — when the root itself is unreadable, or
|
|
329
|
-
* when the scan exhausted its entry budget without finding one: a truncated
|
|
330
|
-
* scan genuinely did not finish looking, and reporting "no web surface" from
|
|
331
|
-
* a half-walked tree would silently drop lens coverage.
|
|
332
|
-
*
|
|
333
|
-
* Uses `readdirSync(withFileTypes)` rather than `git ls-files` — a filesystem
|
|
334
|
-
* check suffices, and shelling out to git would make the probe cost a process
|
|
335
|
-
* spawn on every selection.
|
|
209
|
+
* `null` on an unreadable root or exhausted budget: a half-walked tree must
|
|
210
|
+
* not report "no web surface".
|
|
336
211
|
*
|
|
337
212
|
* @param {string} root
|
|
338
213
|
* @returns {boolean|null}
|
|
@@ -348,9 +223,7 @@ function scanForWebAssets(root) {
|
|
|
348
223
|
try {
|
|
349
224
|
entries = readdirSync(dir, { withFileTypes: true });
|
|
350
225
|
} catch {
|
|
351
|
-
//
|
|
352
|
-
// far likelier than an entire web surface hiding behind it. An
|
|
353
|
-
// unreadable ROOT is a different story — see below.
|
|
226
|
+
// An unreadable subdirectory is skipped; an unreadable root is indeterminate.
|
|
354
227
|
if (dir === root) return null;
|
|
355
228
|
continue;
|
|
356
229
|
}
|
|
@@ -372,31 +245,9 @@ function scanForWebAssets(root) {
|
|
|
372
245
|
}
|
|
373
246
|
|
|
374
247
|
/**
|
|
375
|
-
*
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
* Mandrel is materialized into other projects, so this cannot be a property of
|
|
379
|
-
* *this* repository: a consumer with a real web surface MUST still get the web
|
|
380
|
-
* lenses. It is therefore derived from observables in the consumer's own
|
|
381
|
-
* checkout, and deliberately NOT from a new `.agentrc` key — a new key would
|
|
382
|
-
* have to be threaded through the runtime AJV (`lib/config-settings-schema*.js`)
|
|
383
|
-
* *and* the published mirror, and would make consumers hand-configure something
|
|
384
|
-
* already derivable.
|
|
385
|
-
*
|
|
386
|
-
* A project is web-capable when ANY of these hold:
|
|
387
|
-
* 1. `delivery.quality.navigability.routeGlobs` is configured — the existing
|
|
388
|
-
* web signal the navigability lens already routes off.
|
|
389
|
-
* 2. The root `package.json` declares a web framework (react / next / vue /
|
|
390
|
-
* svelte / astro / nuxt / remix / gatsby / angular).
|
|
391
|
-
* 3. A bounded source scan finds a `.html` / `.css` / `.jsx` / `.tsx` file
|
|
392
|
-
* outside test directories.
|
|
393
|
-
*
|
|
394
|
-
* **Fail direction: OPEN.** When a signal is indeterminate — an unparseable
|
|
395
|
-
* `package.json`, an unreadable root, a scan that hit its entry budget — the
|
|
396
|
-
* project is treated as web-capable. A false positive costs one wasted lens
|
|
397
|
-
* run; a false negative silently drops audit coverage on a project that has a
|
|
398
|
-
* real web surface, and nothing downstream would ever report the omission.
|
|
399
|
-
* Wasted spend is recoverable; dropped coverage is not.
|
|
248
|
+
* `target: "web"` applicability from the consumer's checkout: route globs, a
|
|
249
|
+
* web framework dependency, or a web asset. Fails OPEN when indeterminate — a
|
|
250
|
+
* wasted lens run is recoverable, silently dropped coverage is not.
|
|
400
251
|
*
|
|
401
252
|
* @param {{ config?: object|null, projectRoot?: string }} [params]
|
|
402
253
|
* @returns {boolean}
|
|
@@ -419,12 +270,7 @@ export function hasWebSurface({ config, projectRoot = PROJECT_ROOT } = {}) {
|
|
|
419
270
|
return result;
|
|
420
271
|
}
|
|
421
272
|
|
|
422
|
-
/**
|
|
423
|
-
* Package names (or scope/name segments of them) that declare a **persistence
|
|
424
|
-
* layer** — ORMs and query builders that own a database schema. Matched
|
|
425
|
-
* segment-wise against the consumer's root `package.json` dependency keys, so
|
|
426
|
-
* `@prisma/client` matches via `prisma` and `@mikro-orm/core` via `mikro-orm`.
|
|
427
|
-
*/
|
|
273
|
+
/** ORMs / query builders, matched segment-wise (`@prisma/client` → `prisma`). */
|
|
428
274
|
const ORM_PACKAGES = Object.freeze([
|
|
429
275
|
'prisma',
|
|
430
276
|
'drizzle-orm',
|
|
@@ -439,18 +285,13 @@ const ORM_PACKAGES = Object.freeze([
|
|
|
439
285
|
'waterline',
|
|
440
286
|
]);
|
|
441
287
|
|
|
442
|
-
/** File extensions whose tracked presence implies a persistence schema. */
|
|
443
288
|
const PERSISTENCE_SCHEMA_EXTENSIONS = Object.freeze(['.sql', '.prisma']);
|
|
444
289
|
|
|
445
|
-
/** Directory basenames that name a schema-migrations directory. */
|
|
446
290
|
const MIGRATION_DIR_NAMES = Object.freeze(['migrations', 'migrate']);
|
|
447
291
|
|
|
448
292
|
/**
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
* Mandrel's own `lib/migrations/` of framework-version upgrade steps). A
|
|
452
|
-
* migrations directory only counts as a persistence marker when it sits under
|
|
453
|
-
* one of these conventional ORM/database parents.
|
|
293
|
+
* A migrations directory counts only under one of these parents, so unrelated
|
|
294
|
+
* ones (e.g. Mandrel's own `lib/migrations/`) are not persistence markers.
|
|
454
295
|
*/
|
|
455
296
|
const DB_MIGRATION_PARENTS = Object.freeze([
|
|
456
297
|
'db',
|
|
@@ -461,25 +302,15 @@ const DB_MIGRATION_PARENTS = Object.freeze([
|
|
|
461
302
|
'sql',
|
|
462
303
|
]);
|
|
463
304
|
|
|
464
|
-
/**
|
|
465
|
-
* Process-lifetime memo for the filesystem half of the persistence probe,
|
|
466
|
-
* keyed by project root — the persistence-layer analogue of
|
|
467
|
-
* {@link _webSurfaceFsCache}.
|
|
468
|
-
*
|
|
469
|
-
* @type {Map<string, boolean>}
|
|
470
|
-
*/
|
|
305
|
+
/** @type {Map<string, boolean>} */
|
|
471
306
|
const _persistenceFsCache = new Map();
|
|
472
307
|
|
|
473
|
-
/** Test-only
|
|
308
|
+
/** Test-only. */
|
|
474
309
|
export function _resetPersistenceLayerCache() {
|
|
475
310
|
_persistenceFsCache.clear();
|
|
476
311
|
}
|
|
477
312
|
|
|
478
313
|
/**
|
|
479
|
-
* True when the root `package.json` declares an ORM / query-builder dependency.
|
|
480
|
-
* Tri-state contract per {@link declaresDependencyIn}; the fail-open caller
|
|
481
|
-
* is {@link hasPersistenceLayer}.
|
|
482
|
-
*
|
|
483
314
|
* @param {string} root
|
|
484
315
|
* @returns {boolean|null}
|
|
485
316
|
*/
|
|
@@ -488,16 +319,8 @@ function declaresOrmDependency(root) {
|
|
|
488
319
|
}
|
|
489
320
|
|
|
490
321
|
/**
|
|
491
|
-
*
|
|
492
|
-
*
|
|
493
|
-
* directory sitting under a conventional database parent (`db/`, `prisma/`, …).
|
|
494
|
-
*
|
|
495
|
-
* Unlike the web-asset scan, a truncated or completed no-find scan resolves to
|
|
496
|
-
* **false** (not `null`): persistence artifacts live near the repo root by
|
|
497
|
-
* convention, so a bounded near-root scan that does not find one is strong
|
|
498
|
-
* evidence of absence — and it keeps a large ORM-less repo (Mandrel itself)
|
|
499
|
-
* determinately not-applicable regardless of tree size. Only an unreadable
|
|
500
|
-
* ROOT is indeterminate (`null`), which the caller fails open on.
|
|
322
|
+
* Unlike the web scan, an exhausted budget is `false` (these artifacts live
|
|
323
|
+
* near the root); only an unreadable root is `null`.
|
|
501
324
|
*
|
|
502
325
|
* @param {string} root
|
|
503
326
|
* @returns {boolean|null}
|
|
@@ -540,29 +363,8 @@ function scanForPersistenceArtifacts(root) {
|
|
|
540
363
|
}
|
|
541
364
|
|
|
542
365
|
/**
|
|
543
|
-
*
|
|
544
|
-
*
|
|
545
|
-
* (Story #4633). The data-model lens reads ORM models, schema migrations, and
|
|
546
|
-
* seed data; a project with none of those has nothing for it to inspect, so the
|
|
547
|
-
* lens self-skips with an explicit not-applicable report rather than running to
|
|
548
|
-
* empty findings.
|
|
549
|
-
*
|
|
550
|
-
* Like {@link hasWebSurface}, this is derived from observables in the
|
|
551
|
-
* consumer's own checkout — Mandrel is materialized into other projects, so a
|
|
552
|
-
* consumer with a real database MUST still get the lens. A project has a
|
|
553
|
-
* persistence layer when ANY of these hold:
|
|
554
|
-
* 1. The root `package.json` declares an ORM / query-builder dependency
|
|
555
|
-
* (prisma / drizzle / typeorm / sequelize / mongoose / knex / …).
|
|
556
|
-
* 2. A bounded source scan finds a tracked `.prisma` / `.sql` schema file.
|
|
557
|
-
* 3. A bounded source scan finds a `migrations` / `migrate` directory under a
|
|
558
|
-
* conventional database parent (`db/`, `prisma/`, `drizzle/`, …).
|
|
559
|
-
*
|
|
560
|
-
* **Fail direction: OPEN.** When the ORM-dependency signal is indeterminate —
|
|
561
|
-
* an unparseable `package.json`, an unreadable root — the project is treated as
|
|
562
|
-
* having a persistence layer, for the same reason as the web probe: a wasted
|
|
563
|
-
* lens run is recoverable, silently dropped coverage is not. A determinate
|
|
564
|
-
* "no ORM dependency + no schema artifact found" (Mandrel's own shape) is a
|
|
565
|
-
* clean not-applicable.
|
|
366
|
+
* Applicability predicate for `target: "data-model"` lenses: an ORM
|
|
367
|
+
* dependency or a schema artifact. Fails OPEN like {@link hasWebSurface}.
|
|
566
368
|
*
|
|
567
369
|
* @param {{ config?: object|null, projectRoot?: string }} [params]
|
|
568
370
|
* @returns {boolean}
|
|
@@ -583,26 +385,17 @@ export function hasPersistenceLayer({ projectRoot = PROJECT_ROOT } = {}) {
|
|
|
583
385
|
return result;
|
|
584
386
|
}
|
|
585
387
|
|
|
586
|
-
/**
|
|
587
|
-
* Test a single filename against a single glob pattern using the project's
|
|
588
|
-
* configured matcher semantics (`picomatch` with `dot: true`). Exported so
|
|
589
|
-
* regression tests can pin engine behaviour without stubbing audit-rules.
|
|
590
|
-
*/
|
|
388
|
+
/** Single file × single glob, with the project's matcher semantics (`dot: true`). */
|
|
591
389
|
export function matchesFilePattern(pattern, file) {
|
|
592
390
|
return picomatch(pattern, { dot: true })(file);
|
|
593
391
|
}
|
|
594
392
|
|
|
595
|
-
/**
|
|
596
|
-
* Return true when any of `files` matches any of `patterns`.
|
|
597
|
-
* Same semantics as `matchesFilePattern`; matchers are compiled once per call.
|
|
598
|
-
*/
|
|
599
393
|
export function matchesAnyFilePattern(patterns, files) {
|
|
600
394
|
if (!patterns?.length || !files?.length) return false;
|
|
601
395
|
const matchers = patterns.map((p) => picomatch(p, { dot: true }));
|
|
602
396
|
return files.some((file) => matchers.some((m) => m(file)));
|
|
603
397
|
}
|
|
604
398
|
|
|
605
|
-
/** Extensions the sibling-test predicate treats as production source code. */
|
|
606
399
|
const SOURCE_CODE_EXTENSIONS = Object.freeze([
|
|
607
400
|
'.js',
|
|
608
401
|
'.mjs',
|
|
@@ -622,9 +415,6 @@ const TEST_DIR_RE = new RegExp(
|
|
|
622
415
|
const CODE_EXT_RE = new RegExp(String.raw`\.[cm]?[jt]sx?$`);
|
|
623
416
|
|
|
624
417
|
/**
|
|
625
|
-
* True when `file` is a test/spec file — either by the `.test.` / `.spec.`
|
|
626
|
-
* infix or by living under a conventional test directory.
|
|
627
|
-
*
|
|
628
418
|
* @param {string} file
|
|
629
419
|
* @returns {boolean}
|
|
630
420
|
*/
|
|
@@ -633,8 +423,7 @@ function isTestFile(file) {
|
|
|
633
423
|
}
|
|
634
424
|
|
|
635
425
|
/**
|
|
636
|
-
*
|
|
637
|
-
* the code extension stripped (`src/foo.test.js` and `src/foo.js` both → `foo`).
|
|
426
|
+
* Basename without `.test`/`.spec` infix and code extension.
|
|
638
427
|
*
|
|
639
428
|
* @param {string} file
|
|
640
429
|
* @returns {string}
|
|
@@ -645,20 +434,8 @@ function stemOf(file) {
|
|
|
645
434
|
}
|
|
646
435
|
|
|
647
436
|
/**
|
|
648
|
-
*
|
|
649
|
-
*
|
|
650
|
-
* touches at least one **production source** file whose **sibling test is not
|
|
651
|
-
* also in the change set**. This flips the historical (backwards) trigger that
|
|
652
|
-
* fired the coverage-gap detector on test-file changes — a diff that only edits
|
|
653
|
-
* tests has, if anything, *more* coverage, not less; the risk lives in source
|
|
654
|
-
* that shipped without a matching test.
|
|
655
|
-
*
|
|
656
|
-
* A source file's sibling is matched by stem (`src/foo.js` ↔ any changed
|
|
657
|
-
* `foo.test.js` / `foo.spec.js`, regardless of directory). Test-only diffs,
|
|
658
|
-
* doc/config-only diffs, and source diffs whose every file has a sibling test
|
|
659
|
-
* in the same change set all return `false` and route no quality lens.
|
|
660
|
-
*
|
|
661
|
-
* Pure over its input; no git, no disk.
|
|
437
|
+
* `sourceWithoutSiblingTest`: a source file changed with no same-stem test
|
|
438
|
+
* in the change set.
|
|
662
439
|
*
|
|
663
440
|
* @param {string[]|null|undefined} changedFiles
|
|
664
441
|
* @returns {boolean}
|
|
@@ -677,54 +454,21 @@ export function changeSetLacksSiblingTest(changedFiles) {
|
|
|
677
454
|
}
|
|
678
455
|
|
|
679
456
|
/**
|
|
680
|
-
*
|
|
681
|
-
*
|
|
457
|
+
* Returns `{ selectedAudits, ticketId, gate, context }`, or a degraded
|
|
458
|
+
* envelope (gate-mode throws) on git timeout or an unresolvable `headRef`.
|
|
682
459
|
*
|
|
683
460
|
* @param {object} params
|
|
684
461
|
* @param {number} params.ticketId
|
|
685
462
|
* @param {string} params.gate
|
|
686
463
|
* @param {import('../ITicketingProvider.js').ITicketingProvider} params.provider
|
|
687
|
-
* @param {string[]} [params.changedFiles]
|
|
688
|
-
*
|
|
689
|
-
* it skips the internal `git diff` entirely and `baseBranch` / `headRef` are
|
|
690
|
-
* then unused. Callers whose change set is NOT the working tree's
|
|
691
|
-
* `baseBranch...headRef` MUST pass this: the plan-run epilogue runs from the
|
|
692
|
-
* main checkout *after* its Stories have merged, where any `main...HEAD`
|
|
693
|
-
* range is empty by construction and selection would silently degrade to
|
|
694
|
-
* keyword-only matching (Story #4571). An empty array is honoured as
|
|
695
|
-
* "the set is known, and it is empty" — distinct from omitting the option,
|
|
696
|
-
* which means "derive it from git".
|
|
464
|
+
* @param {string[]} [params.changedFiles] Known change set (skips `git diff`);
|
|
465
|
+
* required post-land, where `base...head` is empty.
|
|
697
466
|
* @param {string} [params.baseBranch]
|
|
698
|
-
* @param {string} [params.headRef]
|
|
699
|
-
* Git ref whose diff-against-`baseBranch` defines the change set. Defaults
|
|
700
|
-
* to `HEAD` (the working-copy tip) for ticket-scoped callers. Epic-mode
|
|
701
|
-
* callers MUST pass the requested Epic's own branch ref (e.g.
|
|
702
|
-
* `refs/heads/epic/<id>`) so the change set is pinned to that Epic's branch
|
|
703
|
-
* rather than whatever HEAD the shared checkout happens to sit on. Under two
|
|
704
|
-
* concurrent `/mandrel-deliver` runs sharing one checkout, diffing against
|
|
705
|
-
* `HEAD` silently resolves the *other* Epic's change set (Story #3362). When
|
|
706
|
-
* `headRef` cannot be resolved in the repo, the selector returns a
|
|
707
|
-
* `degraded: true` envelope (or hard-fails in gate-mode) instead of diffing
|
|
708
|
-
* the wrong tree.
|
|
467
|
+
* @param {string} [params.headRef] Pass explicitly in a shared checkout.
|
|
709
468
|
* @param {(cwd: string, ...args: string[]) => Promise<{status:number, stdout:string, stderr:string}>} [params.injectedGitSpawn]
|
|
710
|
-
* Test-only seam. Production callers leave unset; the real (synchronous) `gitSpawn`
|
|
711
|
-
* is wrapped in `Promise.resolve` so `withTimeout` can still race it. Tests can
|
|
712
|
-
* inject a promise that never resolves to exercise the ETIMEDOUT fallback.
|
|
713
469
|
* @param {number} [params.gitTimeoutMsOverride]
|
|
714
|
-
* Test-only seam to shrink the git-spawn timeout below the configured default
|
|
715
|
-
* (which is 30_000 ms) so timeout tests don't stall the suite.
|
|
716
470
|
* @param {{ argv?: string[], env?: NodeJS.ProcessEnv }} [params.gateModeOpts]
|
|
717
|
-
* Test-only seam to drive the `--gate-mode` / `MANDREL_GATE_MODE=1`
|
|
718
|
-
* detection; production callers leave unset and `isGateMode` reads
|
|
719
|
-
* `process.argv` / `process.env`.
|
|
720
471
|
* @param {typeof hasWebSurface} [params.hasWebSurfaceFn]
|
|
721
|
-
* Test-only seam overriding the web-surface probe behind the
|
|
722
|
-
* `target: "web"` applicability gate. Production callers leave unset.
|
|
723
|
-
*
|
|
724
|
-
* Returns either the success envelope (`{ selectedAudits, ticketId, gate, context }`)
|
|
725
|
-
* OR the degraded envelope (`{ ok: false, degraded: true, reason, detail }`)
|
|
726
|
-
* when the git-diff probe times out OR `headRef` cannot be resolved and
|
|
727
|
-
* gate-mode is unset. In gate-mode, the same conditions throw.
|
|
728
472
|
*/
|
|
729
473
|
export async function selectAudits({
|
|
730
474
|
ticketId,
|
|
@@ -748,12 +492,6 @@ export async function selectAudits({
|
|
|
748
492
|
|
|
749
493
|
const runGit = injectedGitSpawn ?? (async (...args) => gitSpawn(...args));
|
|
750
494
|
|
|
751
|
-
// A caller that already knows the change set supplies it, and no git ref is
|
|
752
|
-
// consulted at all — `baseBranch` / `headRef` describe a diff that is not
|
|
753
|
-
// being taken. The plan-run epilogue is the motivating caller (Story #4571):
|
|
754
|
-
// it resolves the run's landed diff from the Stories' squash-merges, and any
|
|
755
|
-
// `main...HEAD` range it could name from the main checkout post-land is
|
|
756
|
-
// empty by construction.
|
|
757
495
|
const hasInjectedChangedFiles = Array.isArray(injectedChangedFiles);
|
|
758
496
|
|
|
759
497
|
if (!hasInjectedChangedFiles && headRef !== 'HEAD') {
|
|
@@ -800,16 +538,10 @@ export async function selectAudits({
|
|
|
800
538
|
ticketId,
|
|
801
539
|
gate,
|
|
802
540
|
context: {
|
|
803
|
-
// Full file list, exposed so Epic-mode callers (e.g. epic-audit) can
|
|
804
|
-
// pass it through as the {{changedFiles}} substitution value. Existing
|
|
805
|
-
// callers that read only `changedFilesCount` remain unaffected.
|
|
806
541
|
changedFiles,
|
|
807
542
|
changedFilesCount: changedFiles.length,
|
|
808
|
-
//
|
|
809
|
-
//
|
|
810
|
-
// mis-pinned diff never reaches the audit-lens selector silently. `null`
|
|
811
|
-
// on the injected path: no ref was diffed, and naming one would invite
|
|
812
|
-
// exactly that assertion to pass against a diff nobody took.
|
|
543
|
+
// Callers assert this matches the requested branch. `null` when injected:
|
|
544
|
+
// no ref was diffed, so none may pass that assertion.
|
|
813
545
|
resolvedRef: hasInjectedChangedFiles ? null : headRef,
|
|
814
546
|
ticketTitle: ticket.title,
|
|
815
547
|
},
|
|
@@ -817,8 +549,6 @@ export async function selectAudits({
|
|
|
817
549
|
}
|
|
818
550
|
|
|
819
551
|
/**
|
|
820
|
-
* Read and parse `audit-rules.json` from the configured schemas root.
|
|
821
|
-
*
|
|
822
552
|
* @param {object} config Resolved `.agentrc.json` wrapper.
|
|
823
553
|
* @returns {Promise<object>}
|
|
824
554
|
*/
|
|
@@ -837,19 +567,13 @@ async function loadAuditRules(config) {
|
|
|
837
567
|
}
|
|
838
568
|
}
|
|
839
569
|
|
|
840
|
-
/** Lower-cased ticket text the keyword triggers match against. */
|
|
841
570
|
function ticketSearchText(ticket) {
|
|
842
571
|
return `${ticket.title || ''} ${ticket.body || ''}`.toLowerCase();
|
|
843
572
|
}
|
|
844
573
|
|
|
845
574
|
/**
|
|
846
|
-
*
|
|
847
|
-
*
|
|
848
|
-
* diffing `baseBranch...HEAD` would silently report a *different* change set
|
|
849
|
-
* (Story #3362) — so that surfaces as an explicit degraded signal instead of
|
|
850
|
-
* leaking the wrong scope. Returns `null` when the ref resolves; otherwise
|
|
851
|
-
* the degraded envelope from `softFailOrThrow` (which throws in gate-mode).
|
|
852
|
-
* A non-timeout spawn failure propagates.
|
|
575
|
+
* An unresolvable `headRef` would silently diff a different change set, so it
|
|
576
|
+
* degrades instead. Returns `null` when it resolves.
|
|
853
577
|
*
|
|
854
578
|
* @param {{ runGit: Function, headRef: string, timeoutMs: number, gateModeOpts?: object }} params
|
|
855
579
|
* @returns {Promise<object|null>}
|
|
@@ -888,10 +612,7 @@ async function resolveHeadRefOrDegrade({
|
|
|
888
612
|
}
|
|
889
613
|
|
|
890
614
|
/**
|
|
891
|
-
*
|
|
892
|
-
* `{ files }` on success — a diff that exits non-zero yields an empty list,
|
|
893
|
-
* preserving the pre-extraction flow — or `{ degraded }` with the soft-fail
|
|
894
|
-
* envelope on timeout. A non-timeout spawn failure propagates.
|
|
615
|
+
* A non-zero diff yields `{ files: [] }`; a timeout yields `{ degraded }`.
|
|
895
616
|
*
|
|
896
617
|
* @param {{ runGit: Function, baseBranch: string, headRef: string, timeoutMs: number, gateModeOpts?: object }} params
|
|
897
618
|
* @returns {Promise<{ files?: string[], degraded?: object }>}
|
|
@@ -917,10 +638,7 @@ async function acquireChangedFilesFromDiff({
|
|
|
917
638
|
);
|
|
918
639
|
} catch (err) {
|
|
919
640
|
if (err?.code === 'ETIMEDOUT') {
|
|
920
|
-
//
|
|
921
|
-
// degraded envelope so the caller sees the explicit signal instead of
|
|
922
|
-
// silently falling through to keyword-only matching. In gate-mode,
|
|
923
|
-
// hard-fail closed.
|
|
641
|
+
// Degrade rather than fall through to keyword-only matching.
|
|
924
642
|
return {
|
|
925
643
|
degraded: softFailOrThrow(
|
|
926
644
|
'GIT_DIFF_TIMEOUT',
|
|
@@ -941,9 +659,7 @@ async function acquireChangedFilesFromDiff({
|
|
|
941
659
|
}
|
|
942
660
|
|
|
943
661
|
/**
|
|
944
|
-
* Whole-word
|
|
945
|
-
* test selects lenses on accidental fragments ("ui" inside "requires",
|
|
946
|
-
* "auth" inside "author" — #4579).
|
|
662
|
+
* Whole-word match: a substring test fires on fragments ("auth" in "author").
|
|
947
663
|
*
|
|
948
664
|
* @param {string[]} keywords
|
|
949
665
|
* @param {string} content Lower-cased ticket text.
|
|
@@ -957,10 +673,8 @@ function matchesAnyKeyword(keywords, content) {
|
|
|
957
673
|
}
|
|
958
674
|
|
|
959
675
|
/**
|
|
960
|
-
*
|
|
961
|
-
*
|
|
962
|
-
* its gate — a Node-only project must not pay a filesystem scan on a roster
|
|
963
|
-
* with no `web` lens in it, nor a DB-less project pay one for `data-model`.
|
|
676
|
+
* Lazily memoized per target, so a roster without a `web` lens never pays the
|
|
677
|
+
* filesystem scan.
|
|
964
678
|
*
|
|
965
679
|
* @param {{ config: object, hasWebSurfaceFn: Function, hasPersistenceLayerFn: Function }} params
|
|
966
680
|
* @returns {(target: string) => boolean}
|
|
@@ -985,10 +699,6 @@ function makeTargetApplicabilityProbe({
|
|
|
985
699
|
}
|
|
986
700
|
|
|
987
701
|
/**
|
|
988
|
-
* True when any of a lens's content triggers fires against the change set:
|
|
989
|
-
* whole-word keywords, file-pattern globs, or the coverage-gap
|
|
990
|
-
* `sourceWithoutSiblingTest` predicate (#4628).
|
|
991
|
-
*
|
|
992
702
|
* @param {object} triggers The lens's `triggers` block.
|
|
993
703
|
* @param {string} contentToSearch Lower-cased ticket text.
|
|
994
704
|
* @param {string[]} changedFiles
|
|
@@ -1004,10 +714,6 @@ function lensTriggerFires(triggers, contentToSearch, changedFiles) {
|
|
|
1004
714
|
}
|
|
1005
715
|
|
|
1006
716
|
/**
|
|
1007
|
-
* Run the audit-rules matching loop over one gate's roster: a lens is
|
|
1008
|
-
* selected when its gate matches, its `target` applicability gate passes,
|
|
1009
|
-
* and any of its keyword / file-pattern / sibling-test triggers fires.
|
|
1010
|
-
*
|
|
1011
717
|
* @param {{
|
|
1012
718
|
* audits: Record<string, object>,
|
|
1013
719
|
* gate: string,
|
|
@@ -1030,14 +736,8 @@ function matchAuditRules({
|
|
|
1030
736
|
|
|
1031
737
|
if (!triggers.gates?.includes(gate)) continue;
|
|
1032
738
|
|
|
1033
|
-
//
|
|
1034
|
-
//
|
|
1035
|
-
// whole-word-matches ordinary prose — `audit-seo` fires on the `meta`
|
|
1036
|
-
// inside every Story body's `<!-- meta: {...} -->` machine comment. The
|
|
1037
|
-
// roster's own instruction is that the host MUST walk every listed lens,
|
|
1038
|
-
// so an inapplicable entry is not just wasted spend: it teaches operators
|
|
1039
|
-
// to ignore the MUST. An absent `target` (or `any`) means "always
|
|
1040
|
-
// applicable", so no existing lens changes behaviour.
|
|
739
|
+
// An inapplicable lens still keyword-matches prose (`audit-seo` on
|
|
740
|
+
// `<!-- meta: -->`); listing it teaches operators to skip listed lenses.
|
|
1041
741
|
const { target } = ruleOpts;
|
|
1042
742
|
if (target && target !== 'any' && !projectSupportsTarget(target)) continue;
|
|
1043
743
|
|