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,41 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `qa` contract resolver —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* lives, which deployment targets (`environments`) exist and how to sign in
|
|
8
|
-
* to each, and which personas the seam accepts. The block is
|
|
9
|
-
* *optional in the schema* (most repos never bind the harness, so config
|
|
10
|
-
* validation must not break them — see Tech Spec #3285 § "qa contract
|
|
11
|
-
* block"), which means presence is enforced at run time by this resolver
|
|
12
|
-
* rather than by the AJV gate.
|
|
13
|
-
*
|
|
14
|
-
* This resolver is the single seam the harness calls. It fails **loudly**:
|
|
15
|
-
* - Absent block → throw with the operator-actionable phrase
|
|
16
|
-
* "this project has not bound the QA harness". There is no silent
|
|
17
|
-
* fallback to auto-detection; the harness must not pretend a contract
|
|
18
|
-
* exists.
|
|
19
|
-
* - Malformed block → throw an error naming the offending field so the
|
|
20
|
-
* operator can fix `.agentrc.json` without spelunking the schema.
|
|
21
|
-
* - Well-formed block → return the normalized contract object with
|
|
22
|
-
* `environments` + `defaultEnvironment` and the two optional fields
|
|
23
|
-
* (`consoleAllowlist`, `designTokens`) defaulted.
|
|
24
|
-
*
|
|
25
|
-
* `resolveQaEnvironment(contract, target)` selects one environment per
|
|
26
|
-
* harness invocation — by exact name or by raw-URL origin match against each
|
|
27
|
-
* environment's `baseUrl` — and throws loudly (naming the known environments)
|
|
28
|
-
* on an unknown name or unmatched URL.
|
|
29
|
-
*
|
|
30
|
-
* It also **resolves the selected environment's `signInSeam`** (Story #5135).
|
|
31
|
-
* A `{ skill }` seam naming an id that resolves to no readable `SKILL.md`
|
|
32
|
-
* under either skills root used to fail silently: the contract validated, the
|
|
33
|
-
* seam was returned unread, and the dangling pointer only surfaced much later
|
|
34
|
-
* when a sweep reached its sign-in step — after the harness had already
|
|
35
|
-
* driven a browser. Resolution now happens here, at config-resolution time,
|
|
36
|
-
* so the failure lands where the operator can fix `.agentrc.json`. A seam
|
|
37
|
-
* that is absent entirely is a legitimate, declarable state (the workflows
|
|
38
|
-
* drive the unauthenticated surface and record the gap), not an error.
|
|
2
|
+
* `qa` contract resolver — the single seam the QA harness calls. The block is
|
|
3
|
+
* optional in the schema (non-QA repos must validate), so presence is enforced
|
|
4
|
+
* here at run time, loudly: an absent block, a malformed field, or a dangling
|
|
5
|
+
* `signInSeam.skill` throws an operator-actionable error; there is no silent
|
|
6
|
+
* fallback.
|
|
39
7
|
*/
|
|
40
8
|
|
|
41
9
|
import Ajv from 'ajv';
|
|
@@ -47,13 +15,8 @@ import {
|
|
|
47
15
|
} from '../skills/walk-skill-files.js';
|
|
48
16
|
|
|
49
17
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* contract, however, is meaningless without all four, so the resolver
|
|
53
|
-
* enforces them here. Keeping the list adjacent to the resolver (not in the
|
|
54
|
-
* schema) is deliberate: the schema validates *shape* for any repo, the
|
|
55
|
-
* resolver enforces *harness-binding completeness* only when the harness is
|
|
56
|
-
* actually invoked.
|
|
18
|
+
* Optional in the schema (shape for any repo), required here (binding
|
|
19
|
+
* completeness only when the harness actually runs).
|
|
57
20
|
*/
|
|
58
21
|
export const QA_REQUIRED_FIELDS = Object.freeze([
|
|
59
22
|
'featureRoot',
|
|
@@ -62,16 +25,10 @@ export const QA_REQUIRED_FIELDS = Object.freeze([
|
|
|
62
25
|
'personas',
|
|
63
26
|
]);
|
|
64
27
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
* consumer omits the flag. Every other environment defaults to read-only
|
|
68
|
-
* (`allowWrites: false`) so an unguarded remote target cannot accept writes
|
|
69
|
-
* by accident — only the conventional `local` environment is write-enabled
|
|
70
|
-
* by default.
|
|
71
|
-
*/
|
|
28
|
+
// The only environment whose `allowWrites` defaults to true; every other
|
|
29
|
+
// target is read-only unless the consumer opts in.
|
|
72
30
|
const WRITE_ENABLED_DEFAULT_ENVIRONMENT = 'local';
|
|
73
31
|
|
|
74
|
-
/** Defaults applied to the optional fields of a well-formed contract. */
|
|
75
32
|
export const QA_CONTRACT_DEFAULTS = Object.freeze({
|
|
76
33
|
consoleAllowlist: Object.freeze([]),
|
|
77
34
|
designTokens: null,
|
|
@@ -93,16 +50,8 @@ function getQaValidator() {
|
|
|
93
50
|
}
|
|
94
51
|
|
|
95
52
|
/**
|
|
96
|
-
* Normalize
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* The schema accepts either a plain `string[]` of persona names (the honest
|
|
100
|
-
* shape for a `urlTemplate` dev-impersonation seam, where the workflow reads
|
|
101
|
-
* only the persona name) or the object-map form keyed by persona name (each
|
|
102
|
-
* entry carrying `credentialRef` / `signInSkill` for a `skill`/credential
|
|
103
|
-
* seam). Downstream the workflow consumes only the persona *names*, so the
|
|
104
|
-
* canonical internal form is an object map keyed by persona name. A name-only
|
|
105
|
-
* persona maps to an empty record — it carries no fabricated auth material.
|
|
53
|
+
* Normalize `string[]` or object-map personas to an object map; a name-only
|
|
54
|
+
* persona maps to `{}` (no fabricated auth material).
|
|
106
55
|
*
|
|
107
56
|
* @param {string[] | Record<string, object>} personas Either accepted shape.
|
|
108
57
|
* @returns {{ personas: Record<string, object>, personaNames: string[] }}
|
|
@@ -115,7 +64,6 @@ function normalizePersonas(personas) {
|
|
|
115
64
|
}
|
|
116
65
|
return { personas: map, personaNames: [...personas] };
|
|
117
66
|
}
|
|
118
|
-
// Object-map form: clone each entry so callers cannot mutate the input.
|
|
119
67
|
const map = {};
|
|
120
68
|
for (const [name, material] of Object.entries(personas)) {
|
|
121
69
|
map[name] = { ...material };
|
|
@@ -124,15 +72,10 @@ function normalizePersonas(personas) {
|
|
|
124
72
|
}
|
|
125
73
|
|
|
126
74
|
/**
|
|
127
|
-
* Render an AJV error into an actionable, field-named sentence.
|
|
128
|
-
*
|
|
129
75
|
* @param {import('ajv').ErrorObject} err
|
|
130
76
|
* @returns {string}
|
|
131
77
|
*/
|
|
132
78
|
function describeError(err) {
|
|
133
|
-
// `instancePath` is e.g. "/featureRoot" or "/signInSeam"; strip the
|
|
134
|
-
// leading slash so the message reads `qa.featureRoot ...`. A top-level
|
|
135
|
-
// error (empty path) describes the block itself.
|
|
136
79
|
const field = err.instancePath ? err.instancePath.replace(/^\//, '') : '';
|
|
137
80
|
const dotted = field ? `qa.${field.replace(/\//g, '.')}` : 'qa';
|
|
138
81
|
if (err.keyword === 'additionalProperties') {
|
|
@@ -143,16 +86,8 @@ function describeError(err) {
|
|
|
143
86
|
}
|
|
144
87
|
|
|
145
88
|
/**
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
* Accepts either the full resolved config wrapper (`{ qa, project, ... }`)
|
|
149
|
-
* or the bare `qa` bag. Returns a fresh normalized object — callers must not
|
|
150
|
-
* mutate the input.
|
|
151
|
-
*
|
|
152
|
-
* `personas` is accepted in either shape (a `string[]` of names or the
|
|
153
|
-
* object-map form) and normalized to one canonical internal form: an object
|
|
154
|
-
* map keyed by persona name. A `personaNames` array is also returned for the
|
|
155
|
-
* common case (url-template seam) where only the names are consumed.
|
|
89
|
+
* Accepts the full config or the bare `qa` bag; returns a fresh normalized
|
|
90
|
+
* contract.
|
|
156
91
|
*
|
|
157
92
|
* @param {object | null | undefined} config Full resolved config or bare qa block.
|
|
158
93
|
* @returns {{
|
|
@@ -174,10 +109,7 @@ export function resolveQaContract(config) {
|
|
|
174
109
|
throw new Error(ABSENT_MESSAGE);
|
|
175
110
|
}
|
|
176
111
|
|
|
177
|
-
//
|
|
178
|
-
// harness-required field is treated as absent (the operator scaffolded an
|
|
179
|
-
// empty `qa: {}` but never bound it), so it gets the loud no-fallback
|
|
180
|
-
// message rather than a field-by-field validation dump.
|
|
112
|
+
// A scaffolded `qa: {}` with no required field is "absent", not malformed.
|
|
181
113
|
const presentRequired = QA_REQUIRED_FIELDS.filter(
|
|
182
114
|
(key) => qa[key] !== undefined,
|
|
183
115
|
);
|
|
@@ -185,15 +117,13 @@ export function resolveQaContract(config) {
|
|
|
185
117
|
throw new Error(ABSENT_MESSAGE);
|
|
186
118
|
}
|
|
187
119
|
|
|
188
|
-
//
|
|
189
|
-
// name even when a required field is also missing.
|
|
120
|
+
// Shape first, so a wrong-typed field is named even when another is missing.
|
|
190
121
|
const validate = getQaValidator();
|
|
191
122
|
if (!validate(qa)) {
|
|
192
123
|
const detail = (validate.errors || []).map(describeError).join('; ');
|
|
193
124
|
throw new Error(`qa: malformed contract — ${detail}`);
|
|
194
125
|
}
|
|
195
126
|
|
|
196
|
-
// Required-field completeness, naming the first missing field.
|
|
197
127
|
const missing = QA_REQUIRED_FIELDS.filter((key) => qa[key] === undefined);
|
|
198
128
|
if (missing.length > 0) {
|
|
199
129
|
throw new Error(
|
|
@@ -205,15 +135,12 @@ export function resolveQaContract(config) {
|
|
|
205
135
|
|
|
206
136
|
const { personas, personaNames } = normalizePersonas(qa.personas);
|
|
207
137
|
|
|
208
|
-
// Clone each environment so callers cannot mutate the resolver's input.
|
|
209
138
|
const environments = {};
|
|
210
139
|
for (const [name, env] of Object.entries(qa.environments)) {
|
|
211
140
|
environments[name] = { ...env };
|
|
212
141
|
}
|
|
213
142
|
|
|
214
|
-
//
|
|
215
|
-
// otherwise the first-declared environment. `resolveQaEnvironment(contract)`
|
|
216
|
-
// (no target) resolves to this one.
|
|
143
|
+
// `local` when declared, else the first-declared environment.
|
|
217
144
|
const environmentNames = Object.keys(environments);
|
|
218
145
|
const defaultEnvironment = Object.hasOwn(
|
|
219
146
|
environments,
|
|
@@ -240,11 +167,6 @@ export function resolveQaContract(config) {
|
|
|
240
167
|
}
|
|
241
168
|
|
|
242
169
|
/**
|
|
243
|
-
* Normalize a value to its URL origin (`protocol//host:port`), or `null` when
|
|
244
|
-
* it is not a parseable absolute URL. Used to match a raw-URL `target` against
|
|
245
|
-
* each environment's `baseUrl` by origin, so a target carrying a path,
|
|
246
|
-
* query-string, or trailing slash still resolves to the right environment.
|
|
247
|
-
*
|
|
248
170
|
* @param {string} value
|
|
249
171
|
* @returns {string | null}
|
|
250
172
|
*/
|
|
@@ -257,21 +179,11 @@ function toOrigin(value) {
|
|
|
257
179
|
}
|
|
258
180
|
|
|
259
181
|
/**
|
|
260
|
-
*
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
* than mid-sweep. The resolved `SKILL.md` path is attached as
|
|
266
|
-
* `skillPath` so the harness reads the file the check actually found.
|
|
267
|
-
*
|
|
268
|
-
* The two failures get **different** messages (Story #5285). A well-formed id
|
|
269
|
-
* that resolves nowhere is a skill to author; a malformed one is an id to
|
|
270
|
-
* fix, and telling the operator to author `../../secrets/SKILL.md` would be
|
|
271
|
-
* advice they cannot take. A config validated against the shipped schema
|
|
272
|
-
* never reaches the malformed branch — the `pattern` rejects it first — but
|
|
273
|
-
* this resolver also runs over hand-assembled contracts in tests and over
|
|
274
|
-
* configs loaded past a degraded validator, so the branch is real.
|
|
182
|
+
* An absent seam is a declarable `null`. A `{ skill }` seam must resolve
|
|
183
|
+
* under a skills root now, not mid-sweep after a browser was driven; the
|
|
184
|
+
* resolved path is attached as `skillPath`. A malformed id and an unresolved
|
|
185
|
+
* one get different messages because they need different fixes (the
|
|
186
|
+
* malformed branch is reachable past a degraded validator).
|
|
275
187
|
*
|
|
276
188
|
* @param {object | undefined} seam
|
|
277
189
|
* @param {string} envName Environment name, for the error message.
|
|
@@ -309,32 +221,15 @@ function resolveSignInSeam(seam, envName, options) {
|
|
|
309
221
|
}
|
|
310
222
|
|
|
311
223
|
/**
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
* `
|
|
315
|
-
* - **Omitted / falsy** → the contract's `defaultEnvironment`.
|
|
316
|
-
* - **Exact environment name** → that environment.
|
|
317
|
-
* - **Raw URL** → the environment whose `baseUrl` shares the same origin
|
|
318
|
-
* (`protocol//host:port`), so a target with a path or query still matches.
|
|
319
|
-
*
|
|
320
|
-
* Resolution is name-first: a `target` that exactly names an environment wins
|
|
321
|
-
* even if it also happens to parse as a URL.
|
|
322
|
-
*
|
|
323
|
-
* `allowWrites` is resolved to an explicit boolean on the returned object: the
|
|
324
|
-
* environment's own value when set, otherwise `true` only for the conventional
|
|
325
|
-
* `local` environment and `false` for every other target — an unguarded remote
|
|
326
|
-
* environment is read-only unless the consumer opts in.
|
|
327
|
-
*
|
|
328
|
-
* Fails **loudly**: an unknown name or an unmatched URL throws an error that
|
|
329
|
-
* names the known environments so the operator can correct the invocation.
|
|
224
|
+
* Select one environment: omitted → default; exact name (wins even if it
|
|
225
|
+
* parses as a URL); else a raw URL matched by origin against each `baseUrl`.
|
|
226
|
+
* `allowWrites` resolves to an explicit boolean.
|
|
330
227
|
*
|
|
331
228
|
* @param {{ environments: Record<string, { baseUrl: string, signInSeam?: object, allowWrites?: boolean }>, defaultEnvironment: string }} contract
|
|
332
229
|
* A contract returned by `resolveQaContract`.
|
|
333
|
-
* @param {string} [target] Environment name or raw URL.
|
|
334
|
-
* @param {{ repoRoot?: string }} [options]
|
|
335
|
-
* resolution; defaults to the project root. Injected by tests.
|
|
230
|
+
* @param {string} [target] Environment name or raw URL.
|
|
231
|
+
* @param {{ repoRoot?: string }} [options] Roots skill-seam resolution.
|
|
336
232
|
* @returns {{ name: string, baseUrl: string, signInSeam: object | null, allowWrites: boolean }}
|
|
337
|
-
* `signInSeam` is `null` when the environment declares none.
|
|
338
233
|
* @throws {Error} on an unknown name, an unmatched URL, or a `{ skill }` seam
|
|
339
234
|
* that resolves under no skills root.
|
|
340
235
|
*/
|
|
@@ -354,15 +249,11 @@ export function resolveQaEnvironment(contract, target, options = {}) {
|
|
|
354
249
|
const known = Object.keys(environments);
|
|
355
250
|
const knownList = known.map((name) => `\`${name}\``).join(', ');
|
|
356
251
|
|
|
357
|
-
// No target → the default environment.
|
|
358
252
|
const name =
|
|
359
253
|
target == null || target === '' ? contract.defaultEnvironment : target;
|
|
360
254
|
|
|
361
|
-
// Exact-name match wins first (a name that also parses as a URL still
|
|
362
|
-
// resolves by name).
|
|
363
255
|
let resolvedName = Object.hasOwn(environments, name) ? name : null;
|
|
364
256
|
|
|
365
|
-
// Otherwise try to match the target as a raw URL against each baseUrl origin.
|
|
366
257
|
if (resolvedName === null) {
|
|
367
258
|
const targetOrigin = toOrigin(name);
|
|
368
259
|
if (targetOrigin !== null) {
|
|
@@ -1,41 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* resolve-selection.js —
|
|
3
|
-
*
|
|
2
|
+
* resolve-selection.js — turns a QA harness selector into a concrete,
|
|
3
|
+
* deterministic scenario set under `featureRoot`:
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* - `{ kind: 'feature', id }` — one file whose stem or root-relative path
|
|
6
|
+
* equals `id` (case-insensitive; ambiguity throws);
|
|
7
|
+
* - `{ kind: 'tag', expression }` — scenarios satisfying a cucumber-style
|
|
8
|
+
* `@tag` / and / or / not / parens expression;
|
|
9
|
+
* - `{ kind: 'domain', name }` — every scenario at or below `<root>/<name>/`.
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
* single `.feature` file whose path stem (basename without the
|
|
12
|
-
* `.feature` extension) equals the id, or whose `featureRoot`-relative
|
|
13
|
-
* POSIX path (with or without the extension) equals the id. Matching is
|
|
14
|
-
* exact and case-insensitive; ambiguous ids (more than one match) throw.
|
|
15
|
-
*
|
|
16
|
-
* - **tag expression** — `{ kind: 'tag', expression: '@smoke and not @wip' }`
|
|
17
|
-
* resolves to the scenario set whose tag list satisfies the boolean
|
|
18
|
-
* expression. The expression grammar is the cucumber-common subset:
|
|
19
|
-
* `@tag` atoms, `and` / `or` / `not` operators (case-insensitive), and
|
|
20
|
-
* parentheses. A scenario inherits no implicit tags; only the tags the
|
|
21
|
-
* scanner attached to it (feature-level + scenario-level, as collected
|
|
22
|
-
* by `parseFeatureBody`) participate.
|
|
23
|
-
*
|
|
24
|
-
* - **domain** — `{ kind: 'domain', name: 'billing' }` resolves to every
|
|
25
|
-
* scenario under the `featureRoot`-relative subdirectory `name`. A
|
|
26
|
-
* domain is a first-level (or nested) directory grouping beneath the
|
|
27
|
-
* feature root; the selector matches any scenario whose file lives at
|
|
28
|
-
* or below `<featureRoot>/<name>/`.
|
|
29
|
-
*
|
|
30
|
-
* Determinism is load-bearing — the QA harness re-runs the same selector
|
|
31
|
-
* across sweeps and must scope the identical scenario set each time. All
|
|
32
|
-
* outputs are sorted by `(file, line)` so the order never depends on
|
|
33
|
-
* filesystem iteration order.
|
|
34
|
-
*
|
|
35
|
-
* This module is pure resolution: it does no browser work, reads no config
|
|
36
|
-
* beyond the `featureRoot` passed in, and never mutates state. The harness
|
|
37
|
-
* workflow (Story #3297) consumes the resolved set; this layer only answers
|
|
38
|
-
* "which scenarios does this selector name?".
|
|
11
|
+
* Output is sorted by `(file, line)` so re-runs scope the identical set.
|
|
39
12
|
*/
|
|
40
13
|
|
|
41
14
|
import path from 'node:path';
|
|
@@ -43,9 +16,6 @@ import path from 'node:path';
|
|
|
43
16
|
import { listFeatureFiles, scanBddScenarios } from '../bdd-scenario-scanner.js';
|
|
44
17
|
|
|
45
18
|
/**
|
|
46
|
-
* Normalise a path to POSIX separators so `featureRoot`-relative matching
|
|
47
|
-
* behaves identically on Windows and POSIX hosts.
|
|
48
|
-
*
|
|
49
19
|
* @param {string} p
|
|
50
20
|
* @returns {string}
|
|
51
21
|
*/
|
|
@@ -54,10 +24,6 @@ function toPosix(p) {
|
|
|
54
24
|
}
|
|
55
25
|
|
|
56
26
|
/**
|
|
57
|
-
* Compute a scenario's `featureRoot`-relative POSIX path. Used by the
|
|
58
|
-
* feature-id and domain matchers so selectors are written against the
|
|
59
|
-
* stable, repo-relative shape rather than absolute worktree paths.
|
|
60
|
-
*
|
|
61
27
|
* @param {string} featureRoot - Absolute path to the feature root.
|
|
62
28
|
* @param {string} file - Absolute path to a `.feature` file.
|
|
63
29
|
* @returns {string} POSIX-style path relative to `featureRoot`.
|
|
@@ -67,9 +33,6 @@ function relFromRoot(featureRoot, file) {
|
|
|
67
33
|
}
|
|
68
34
|
|
|
69
35
|
/**
|
|
70
|
-
* Strip the trailing `.feature` extension (case-insensitive) from a
|
|
71
|
-
* relative path, leaving the path stem the feature-id selector matches on.
|
|
72
|
-
*
|
|
73
36
|
* @param {string} relPath
|
|
74
37
|
* @returns {string}
|
|
75
38
|
*/
|
|
@@ -77,15 +40,7 @@ function stripFeatureExt(relPath) {
|
|
|
77
40
|
return relPath.replace(/\.feature$/i, '');
|
|
78
41
|
}
|
|
79
42
|
|
|
80
|
-
// ---------------------------------------------------------------------------
|
|
81
|
-
// Tag-expression evaluation
|
|
82
|
-
// ---------------------------------------------------------------------------
|
|
83
|
-
|
|
84
43
|
/**
|
|
85
|
-
* Classify a single matched lexeme into a token. `@tag` atoms keep their
|
|
86
|
-
* raw value; `(` / `)` / `and` / `or` / `not` produce structural tokens.
|
|
87
|
-
* Anything else is a malformed expression and throws.
|
|
88
|
-
*
|
|
89
44
|
* @param {string} raw
|
|
90
45
|
* @returns {{ type: string, value?: string }}
|
|
91
46
|
*/
|
|
@@ -106,10 +61,6 @@ function classifyToken(raw) {
|
|
|
106
61
|
}
|
|
107
62
|
|
|
108
63
|
/**
|
|
109
|
-
* Tokenise a cucumber-style tag expression into a flat token stream.
|
|
110
|
-
* Recognised tokens: `(`, `)`, `and`, `or`, `not`, and `@tag` atoms.
|
|
111
|
-
* Whitespace separates tokens; parentheses need no surrounding space.
|
|
112
|
-
*
|
|
113
64
|
* @param {string} expression
|
|
114
65
|
* @returns {Array<{ type: string, value?: string }>}
|
|
115
66
|
*/
|
|
@@ -122,7 +73,6 @@ function tokenizeTagExpression(expression) {
|
|
|
122
73
|
match !== null;
|
|
123
74
|
match = re.exec(expression)
|
|
124
75
|
) {
|
|
125
|
-
// Guard against runs of unmatched garbage between tokens.
|
|
126
76
|
const between = expression.slice(lastIndex, match.index).trim();
|
|
127
77
|
if (between.length > 0) {
|
|
128
78
|
throw new Error(
|
|
@@ -142,15 +92,13 @@ function tokenizeTagExpression(expression) {
|
|
|
142
92
|
}
|
|
143
93
|
|
|
144
94
|
/**
|
|
145
|
-
* Recursive
|
|
95
|
+
* Recursive descent:
|
|
146
96
|
*
|
|
147
97
|
* expr := term ( 'or' term )*
|
|
148
98
|
* term := factor( 'and' factor)*
|
|
149
99
|
* factor := 'not' factor | '(' expr ')' | tag
|
|
150
100
|
*
|
|
151
|
-
*
|
|
152
|
-
* case-insensitively against the scenario's tag set (which carries the
|
|
153
|
-
* leading `@`).
|
|
101
|
+
* Tag atoms match case-insensitively (with the leading `@`).
|
|
154
102
|
*
|
|
155
103
|
* @param {string} expression
|
|
156
104
|
* @returns {(tags: Set<string>) => boolean}
|
|
@@ -226,9 +174,6 @@ export function parseTagExpression(expression) {
|
|
|
226
174
|
}
|
|
227
175
|
|
|
228
176
|
/**
|
|
229
|
-
* Build a lower-cased tag `Set` for a scanned scenario so the predicate can
|
|
230
|
-
* test membership case-insensitively.
|
|
231
|
-
*
|
|
232
177
|
* @param {{ tags?: string[] }} scenario
|
|
233
178
|
* @returns {Set<string>}
|
|
234
179
|
*/
|
|
@@ -236,13 +181,7 @@ function tagSetOf(scenario) {
|
|
|
236
181
|
return new Set((scenario.tags ?? []).map((t) => t.toLowerCase()));
|
|
237
182
|
}
|
|
238
183
|
|
|
239
|
-
// ---------------------------------------------------------------------------
|
|
240
|
-
// Public resolver
|
|
241
|
-
// ---------------------------------------------------------------------------
|
|
242
|
-
|
|
243
184
|
/**
|
|
244
|
-
* Sort scanned scenarios deterministically by `(file, line)`.
|
|
245
|
-
*
|
|
246
185
|
* @param {Array<{ file: string, line: number }>} scenarios
|
|
247
186
|
* @returns {Array<object>}
|
|
248
187
|
*/
|
|
@@ -255,21 +194,15 @@ function sortScenarios(scenarios) {
|
|
|
255
194
|
}
|
|
256
195
|
|
|
257
196
|
/**
|
|
258
|
-
* Resolve a selector into a concrete scenario set under `featureRoot`.
|
|
259
|
-
*
|
|
260
197
|
* @param {object} args
|
|
261
198
|
* @param {string} args.featureRoot - Absolute path to the contract's
|
|
262
|
-
* `.feature` root.
|
|
263
|
-
*
|
|
264
|
-
*
|
|
265
|
-
* `{ kind: 'feature', id }`, `{ kind: 'tag', expression }`, or
|
|
266
|
-
* `{ kind: 'domain', name }`.
|
|
199
|
+
* `.feature` root.
|
|
200
|
+
* @param {object} args.selector - `{ kind: 'feature', id }`,
|
|
201
|
+
* `{ kind: 'tag', expression }`, or `{ kind: 'domain', name }`.
|
|
267
202
|
* @param {{ logger?: object }} [opts]
|
|
268
203
|
* @returns {{ kind: string, featureRoot: string, files: string[], scenarios: Array<object> }}
|
|
269
|
-
* `
|
|
270
|
-
*
|
|
271
|
-
* selection it is the satisfying subset, for feature/domain it is every
|
|
272
|
-
* scenario in the matched files).
|
|
204
|
+
* `scenarios` is the satisfying subset for tags, every scenario in the
|
|
205
|
+
* matched files otherwise.
|
|
273
206
|
*/
|
|
274
207
|
export function resolveSelection(args = {}, opts = {}) {
|
|
275
208
|
const { featureRoot, selector } = args;
|
|
@@ -351,8 +284,7 @@ function resolveDomain(featureRoot, selector, opts) {
|
|
|
351
284
|
'[resolve-selection] domain selector requires a non-empty name',
|
|
352
285
|
);
|
|
353
286
|
}
|
|
354
|
-
//
|
|
355
|
-
// "billing/checkout.feature" but not "billing-archive/x.feature".
|
|
287
|
+
// Trailing slash so "billing" never matches "billing-archive/".
|
|
356
288
|
const prefix = `${toPosix(name.trim()).replace(/\/+$/, '')}/`;
|
|
357
289
|
const all = scanBddScenarios({ featureRoots: [featureRoot], ...opts });
|
|
358
290
|
const scenarios = sortScenarios(
|
|
@@ -1,48 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* lib/reserved-test-ids.js — the
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* post-test temp reaper shipped, but it lived as a private regexp inside
|
|
7
|
-
* `cleanup-repo-test-temp.js` (`/^epic-999\d{3}$/`) and nothing else could
|
|
8
|
-
* consult it. Two independent surfaces need the same rule, and spelling it
|
|
9
|
-
* twice is how they would drift:
|
|
10
|
-
*
|
|
11
|
-
* 1. **Write side.** A test that spawns a real CLI at the repository root
|
|
12
|
-
* inherits the real state directory, so its fixture telemetry can land
|
|
13
|
-
* in the operator's live `temp/` signals tree. The post-run guard in
|
|
14
|
-
* `check-test-temp-hygiene.js` fails the run when a stream file owned by
|
|
15
|
-
* a reserved id survives there.
|
|
16
|
-
* 2. **Read side.** The retro composer renders the distinct Stories a
|
|
17
|
-
* friction bucket spans as recurrence evidence in a body that is filed
|
|
18
|
-
* as a real GitHub issue. A reserved id is synthetic by construction, so
|
|
19
|
-
* it can never be resolved to a real issue and must never be published
|
|
20
|
-
* as evidence (issue #4870 named `#999999` as a contributing Story).
|
|
21
|
-
*
|
|
22
|
-
* Deliberately dependency-free: the write side is a CLI guard and the read
|
|
23
|
-
* side is a pure composer, so the shared rule must not drag config, fs, or
|
|
24
|
-
* git resolution into either.
|
|
2
|
+
* lib/reserved-test-ids.js — the one declaration of the synthetic
|
|
3
|
+
* test-fixture id band, shared by the temp-pollution guard and the retro
|
|
4
|
+
* composer (which must never publish a synthetic id as evidence).
|
|
5
|
+
* Dependency-free on purpose.
|
|
25
6
|
*/
|
|
26
7
|
|
|
27
|
-
/** First id in the reserved test-fixture band. */
|
|
28
8
|
const RESERVED_TEST_ID_MIN = 999000;
|
|
29
9
|
|
|
30
|
-
/** Last id in the reserved test-fixture band. */
|
|
31
10
|
const RESERVED_TEST_ID_MAX = 999999;
|
|
32
11
|
|
|
33
|
-
/**
|
|
34
|
-
* Human-readable band, for guard failure messages that have to tell an
|
|
35
|
-
* operator which ids they may not use for real work.
|
|
36
|
-
*/
|
|
12
|
+
/** For guard messages naming the ids real work may not use. */
|
|
37
13
|
export const RESERVED_TEST_ID_BAND = `${RESERVED_TEST_ID_MIN}–${RESERVED_TEST_ID_MAX}`;
|
|
38
14
|
|
|
39
15
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* Exact-band membership, because this is the predicate the temp reaper and
|
|
43
|
-
* the pollution guard share: both classify an on-disk directory that a test
|
|
44
|
-
* created, and over-reaching (treating every large id as reserved) would let
|
|
45
|
-
* one of them delete or condemn a directory the band never claimed.
|
|
16
|
+
* Exact-band membership: the reaper and the guard act on on-disk dirs, and
|
|
17
|
+
* over-reaching would delete or condemn one the band never claimed.
|
|
46
18
|
*
|
|
47
19
|
* @param {unknown} id
|
|
48
20
|
* @returns {boolean}
|
|
@@ -56,18 +28,8 @@ export function isReservedTestId(id) {
|
|
|
56
28
|
}
|
|
57
29
|
|
|
58
30
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* The floor is the reserved band, not the band itself: an id at or above
|
|
62
|
-
* `RESERVED_TEST_ID_MIN` is synthetic by construction (the framework reserves
|
|
63
|
-
* that space for fixtures, and no repository has minted that many issues), so
|
|
64
|
-
* nothing at or beyond the floor can be resolved to a real issue. A
|
|
65
|
-
* non-integer or non-positive id is not a ticket reference at all.
|
|
66
|
-
*
|
|
67
|
-
* This is a plausibility bound, not an existence probe: it is the strongest
|
|
68
|
-
* statement a caller with no ticket-provider access can make, and it is what
|
|
69
|
-
* keeps the invariant true at every call site instead of only where somebody
|
|
70
|
-
* remembered to wire a probe.
|
|
31
|
+
* A plausibility bound, not an existence probe: anything at or above the
|
|
32
|
+
* band floor is synthetic, and non-positive ids are not references.
|
|
71
33
|
*
|
|
72
34
|
* @param {unknown} id
|
|
73
35
|
* @returns {boolean}
|
|
@@ -1,30 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* runtime-deps/dep-resolution — is a declared runtime dependency
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* in `.agents/runtime-deps.json` therefore documents a requirement it cannot
|
|
8
|
-
* enforce, and the preflight guard needs to compare the range against what
|
|
9
|
-
* actually resolved.
|
|
10
|
-
*
|
|
11
|
-
* Deliberately major-only, and deliberately not `semver`. The framework's
|
|
12
|
-
* runtime ranges are all `^`, whose whole contract is "this major"; pulling in
|
|
13
|
-
* a semver implementation to decide one comparison would add a dependency to
|
|
14
|
-
* the very closure this module exists to keep honest.
|
|
2
|
+
* runtime-deps/dep-resolution — is a declared runtime dependency present and
|
|
3
|
+
* the right major. Deps resolve from the consumer's `node_modules`, so a
|
|
4
|
+
* declared range is only enforced by comparing it to what resolved.
|
|
5
|
+
* Major-only and semver-free on purpose: every range is `^`, and a semver
|
|
6
|
+
* dependency would grow the very closure this guards.
|
|
15
7
|
*
|
|
16
8
|
* @module lib/runtime-deps/dep-resolution
|
|
17
9
|
*/
|
|
18
10
|
|
|
19
11
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* Module-local: `majorMismatch` is the only question callers have.
|
|
23
|
-
*
|
|
24
|
-
* Anything this cannot read as `<major>.` — `*`, a tag, a git URL, a
|
|
25
|
-
* `>=x <y` span — yields `null` and is treated as "not range-checked". That
|
|
26
|
-
* asymmetry is intentional: a conservative miss is a no-op, while a false
|
|
27
|
-
* positive blocks a working install.
|
|
12
|
+
* Anything not `<major>.`-shaped yields `null` (not range-checked): a
|
|
13
|
+
* conservative miss is a no-op, a false positive blocks a working install.
|
|
28
14
|
*
|
|
29
15
|
* @param {string|null|undefined} spec
|
|
30
16
|
* @returns {number|null}
|
|
@@ -36,18 +22,8 @@ function majorOf(spec) {
|
|
|
36
22
|
}
|
|
37
23
|
|
|
38
24
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* Module-local: `checkRuntimeDeps` is the only caller, and exporting it only
|
|
42
|
-
* for a test would be a production-dead export.
|
|
43
|
-
*
|
|
44
|
-
* `false` whenever either side is unreadable, so an unparseable range or an
|
|
45
|
-
* unreadable installed version is never reported as a mismatch.
|
|
46
|
-
*
|
|
47
|
-
* `0.x` majors compare as written: `^0.1.0` and `0.2.1` differ in minor, not
|
|
48
|
-
* major, so this does not separate them. Accepted — the `0.x` packages in the
|
|
49
|
-
* closure are terminal, and the range this exists to enforce is
|
|
50
|
-
* `@babel/parser`'s `^7`.
|
|
25
|
+
* `false` when either side is unreadable. `0.x` minors are not separated —
|
|
26
|
+
* accepted, since the range this enforces is `@babel/parser`'s `^7`.
|
|
51
27
|
*
|
|
52
28
|
* @param {string|null|undefined} range
|
|
53
29
|
* @param {string|null|undefined} resolved
|
|
@@ -62,14 +38,8 @@ function majorMismatch(range, resolved) {
|
|
|
62
38
|
}
|
|
63
39
|
|
|
64
40
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* The bare specifier is tried first, then `<name>/package.json`. The fallback
|
|
68
|
-
* is not belt-and-braces: a package with no `main` and no `exports` — which
|
|
69
|
-
* `typhonjs-escomplex-commons` and `babel-runtime` both are — cannot be
|
|
70
|
-
* resolved by name at all, and is reached only by deep path. Probing the bare
|
|
71
|
-
* name alone would report such a package missing while it sits installed, and
|
|
72
|
-
* this guard exits the process on that verdict.
|
|
41
|
+
* Falls back to `<name>/package.json`: a package with no `main`/`exports`
|
|
42
|
+
* cannot be resolved by name, and reporting it missing would exit the process.
|
|
73
43
|
*
|
|
74
44
|
* @param {string} dep
|
|
75
45
|
* @param {(specifier: string) => string} resolve
|
|
@@ -91,13 +61,8 @@ export function isResolvable(dep, resolve) {
|
|
|
91
61
|
}
|
|
92
62
|
|
|
93
63
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* Named separately from the missing-deps message because the remedy differs:
|
|
98
|
-
* the package is installed, so installing again changes nothing. What is
|
|
99
|
-
* wrong is the version the consumer's own tree resolves, which only they can
|
|
100
|
-
* change.
|
|
64
|
+
* Distinct from the missing-deps message: reinstalling changes nothing, only
|
|
65
|
+
* the consumer can pin a compatible major.
|
|
101
66
|
*
|
|
102
67
|
* @param {{name: string, required: string, resolved: string}[]} mismatched
|
|
103
68
|
* @param {{ root: string }} ctx
|
|
@@ -119,11 +84,6 @@ export function formatMismatchedDepsMessage(mismatched, { root }) {
|
|
|
119
84
|
}
|
|
120
85
|
|
|
121
86
|
/**
|
|
122
|
-
* Resolve each required package via the injected `resolve` seam and collect
|
|
123
|
-
* the ones that fail. `resolve` is typically `require.resolve` bound to the
|
|
124
|
-
* framework module location; it throws `MODULE_NOT_FOUND` when a package is
|
|
125
|
-
* absent from the resolvable `node_modules`.
|
|
126
|
-
*
|
|
127
87
|
* @param {{ required: string[], resolve: (specifier: string) => string }} opts
|
|
128
88
|
* @returns {{ ok: boolean, missing: string[] }}
|
|
129
89
|
*/
|