mandrel 2.60.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 +10 -10
- package/.agents/agents/story-worker.md +1 -1
- package/.agents/docs/agentrc-reference.json +4 -82
- package/.agents/docs/configuration.md +20 -87
- package/.agents/docs/workflows.md +1 -1
- package/.agents/instructions.md +1 -3
- package/.agents/rules/gherkin-standards.md +4 -0
- package/.agents/schemas/agentrc.schema.json +11 -486
- package/.agents/schemas/story-deliver-terminal.schema.json +10 -0
- package/.agents/schemas/validation-evidence.schema.json +2 -1
- package/.agents/scripts/README.md +14 -14
- package/.agents/scripts/acceptance-eval.js +32 -164
- package/.agents/scripts/agents-bootstrap-github.js +27 -129
- package/.agents/scripts/apply-quality-bootstrap.js +4 -40
- package/.agents/scripts/audit-baselines.js +6 -27
- package/.agents/scripts/audit-labels-bootstrap.js +5 -29
- package/.agents/scripts/audit-to-stories.js +91 -361
- package/.agents/scripts/boot-sweep.js +19 -72
- package/.agents/scripts/bootstrap.js +74 -395
- package/.agents/scripts/ceremony-derive.js +9 -45
- package/.agents/scripts/check-arch-cycles.js +14 -64
- package/.agents/scripts/check-baselines.js +8 -48
- package/.agents/scripts/check-context-budget.js +46 -172
- package/.agents/scripts/check-cyclomatic.js +12 -44
- package/.agents/scripts/check-dead-exports.js +13 -64
- package/.agents/scripts/check-doc-links.js +38 -186
- package/.agents/scripts/check-gherkin-corpus.js +24 -127
- package/.agents/scripts/check-test-temp-hygiene.js +28 -169
- package/.agents/scripts/coverage-capture.js +32 -99
- package/.agents/scripts/deliver-light.js +14 -101
- package/.agents/scripts/deliver-recover.js +6 -42
- package/.agents/scripts/deliver-run.js +36 -133
- package/.agents/scripts/diagnose-friction.js +24 -116
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +23 -85
- package/.agents/scripts/file-ci-gap.js +10 -50
- package/.agents/scripts/generate-config-docs.js +30 -170
- package/.agents/scripts/generate-lens-checklists.js +8 -52
- package/.agents/scripts/generate-skills-index.js +14 -112
- package/.agents/scripts/generate-workflows-doc.js +10 -70
- package/.agents/scripts/git-cleanup.js +2 -34
- package/.agents/scripts/lib/Graph.js +24 -81
- package/.agents/scripts/lib/ITicketingProvider.js +47 -143
- package/.agents/scripts/lib/Logger.js +14 -76
- package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
- package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
- package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
- package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
- package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
- package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
- package/.agents/scripts/lib/audit-baselines/read.js +3 -16
- package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
- package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
- package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
- package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
- package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
- package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
- package/.agents/scripts/lib/audit-suite/findings.js +12 -52
- package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
- package/.agents/scripts/lib/audit-suite/index.js +1 -15
- package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
- package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
- package/.agents/scripts/lib/audit-suite/runner.js +13 -43
- package/.agents/scripts/lib/audit-suite/selector.js +49 -349
- package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
- package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
- package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
- package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
- package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
- package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
- package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
- package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
- package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
- package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
- package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
- package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
- package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
- package/.agents/scripts/lib/baseline-loader.js +12 -51
- package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
- package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
- package/.agents/scripts/lib/baselines/components.js +10 -61
- package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
- package/.agents/scripts/lib/baselines/crap-preview-incremental.js +5 -21
- package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
- package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
- package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
- package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
- package/.agents/scripts/lib/baselines/envelope.js +13 -129
- package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
- package/.agents/scripts/lib/baselines/git-base.js +23 -142
- package/.agents/scripts/lib/baselines/kernel.js +11 -111
- package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
- package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
- package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
- package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
- package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
- package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
- package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
- package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
- package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
- package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
- package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
- package/.agents/scripts/lib/baselines/path-canon.js +19 -128
- package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
- package/.agents/scripts/lib/baselines/reader.js +14 -107
- package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
- package/.agents/scripts/lib/baselines/scope.js +11 -135
- package/.agents/scripts/lib/baselines/writer.js +16 -149
- package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
- package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
- package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
- package/.agents/scripts/lib/bdd-step-index.js +26 -100
- package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
- package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
- package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
- package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
- package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
- package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
- package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
- package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
- package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
- package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
- package/.agents/scripts/lib/bootstrap/summary.js +1 -8
- package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
- package/.agents/scripts/lib/branch-name-guard.js +4 -23
- package/.agents/scripts/lib/changed-files.js +31 -143
- package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
- package/.agents/scripts/lib/checks/index.js +18 -101
- package/.agents/scripts/lib/checks/loop-health.js +11 -53
- package/.agents/scripts/lib/checks/state.js +16 -91
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
- package/.agents/scripts/lib/child-exec.js +39 -108
- package/.agents/scripts/lib/cli/standard-args.js +9 -116
- package/.agents/scripts/lib/cli-args.js +31 -146
- package/.agents/scripts/lib/cli-usage.js +5 -27
- package/.agents/scripts/lib/cli-utils.js +2 -12
- package/.agents/scripts/lib/close-validation/commands.js +13 -76
- package/.agents/scripts/lib/close-validation/gates.js +92 -331
- package/.agents/scripts/lib/close-validation/process.js +121 -151
- package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
- package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
- package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
- package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
- package/.agents/scripts/lib/close-validation/runner.js +53 -110
- package/.agents/scripts/lib/command-header.js +6 -28
- package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
- package/.agents/scripts/lib/config/baselines.js +3 -14
- package/.agents/scripts/lib/config/ci.js +8 -38
- package/.agents/scripts/lib/config/commands.js +1 -15
- package/.agents/scripts/lib/config/defaults.js +4 -33
- package/.agents/scripts/lib/config/delivery-routing.js +6 -35
- package/.agents/scripts/lib/config/explain.js +9 -80
- package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +2 -30
- package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
- package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
- package/.agents/scripts/lib/config/gates/index.js +2 -17
- package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
- package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
- package/.agents/scripts/lib/config/gates/shared.js +4 -64
- package/.agents/scripts/lib/config/github.js +4 -22
- package/.agents/scripts/lib/config/limits.js +4 -57
- package/.agents/scripts/lib/config/paths.js +2 -21
- package/.agents/scripts/lib/config/qa.js +4 -38
- package/.agents/scripts/lib/config/quality.js +76 -432
- package/.agents/scripts/lib/config/runners.js +12 -56
- package/.agents/scripts/lib/config/runtime.js +13 -57
- package/.agents/scripts/lib/config/shared.js +2 -16
- package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
- package/.agents/scripts/lib/config/temp-paths.js +40 -280
- package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
- package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
- package/.agents/scripts/lib/config-resolver.js +10 -52
- package/.agents/scripts/lib/config-schema-shared.js +1 -4
- package/.agents/scripts/lib/config-settings-schema-delivery.js +12 -294
- package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
- package/.agents/scripts/lib/config-settings-schema.js +37 -274
- package/.agents/scripts/lib/coverage-baseline.js +20 -110
- package/.agents/scripts/lib/coverage-capture-fullscope.js +12 -37
- package/.agents/scripts/lib/coverage-capture-incremental.js +12 -43
- package/.agents/scripts/lib/coverage-capture-usage.js +4 -24
- package/.agents/scripts/lib/coverage-capture.js +99 -224
- package/.agents/scripts/lib/coverage-utils.js +14 -79
- package/.agents/scripts/lib/cpu-pool.js +17 -123
- package/.agents/scripts/lib/crap-baseline-join.js +16 -88
- package/.agents/scripts/lib/crap-coordinates.js +6 -25
- package/.agents/scripts/lib/crap-engine.js +40 -153
- package/.agents/scripts/lib/crap-method-identity.js +16 -78
- package/.agents/scripts/lib/crap-utils.js +31 -155
- package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
- package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
- package/.agents/scripts/lib/dead-exports-knip.js +18 -56
- package/.agents/scripts/lib/dead-exports-mode.js +5 -24
- package/.agents/scripts/lib/degraded-mode.js +3 -26
- package/.agents/scripts/lib/dependency-parser.js +8 -40
- package/.agents/scripts/lib/dependency-version.js +13 -35
- package/.agents/scripts/lib/detect-package-manager.js +6 -36
- package/.agents/scripts/lib/doc-tiers.js +22 -126
- package/.agents/scripts/lib/duplicate-search.js +8 -72
- package/.agents/scripts/lib/env-loader.js +5 -27
- package/.agents/scripts/lib/error-redactor.js +6 -31
- package/.agents/scripts/lib/errors/index.js +2 -22
- package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
- package/.agents/scripts/lib/escomplex-kernel.js +21 -123
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +93 -419
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -151
- package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
- package/.agents/scripts/lib/findings/classify-finding.js +14 -69
- package/.agents/scripts/lib/findings/promote-finding.js +14 -112
- package/.agents/scripts/lib/findings/provenance-field.js +11 -52
- package/.agents/scripts/lib/findings/route-finding.js +37 -255
- package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
- package/.agents/scripts/lib/findings/severity.js +18 -104
- package/.agents/scripts/lib/format-generated-json.js +12 -44
- package/.agents/scripts/lib/full-suite-lock.js +160 -429
- package/.agents/scripts/lib/full-suite-queue.js +213 -0
- package/.agents/scripts/lib/gates/baseline-store.js +5 -9
- package/.agents/scripts/lib/gates/friction.js +1 -3
- package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
- package/.agents/scripts/lib/gh-exec.js +31 -259
- package/.agents/scripts/lib/git/cached-fetch.js +9 -52
- package/.agents/scripts/lib/git/sync-from-base.js +15 -107
- package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
- package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
- package/.agents/scripts/lib/git-utils.js +37 -161
- package/.agents/scripts/lib/github/framework-repo.js +8 -71
- package/.agents/scripts/lib/github-url.js +2 -17
- package/.agents/scripts/lib/import-graph.js +11 -38
- package/.agents/scripts/lib/install-cmd-parser.js +4 -13
- package/.agents/scripts/lib/json-utils.js +3 -18
- package/.agents/scripts/lib/label-constants.js +16 -111
- package/.agents/scripts/lib/label-taxonomy.js +4 -30
- package/.agents/scripts/lib/maintainability-engine.js +12 -80
- package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
- package/.agents/scripts/lib/maintainability-utils.js +16 -92
- package/.agents/scripts/lib/mandrel-catalog.js +12 -70
- package/.agents/scripts/lib/notifications/notifier.js +13 -38
- package/.agents/scripts/lib/npm-scripts.js +4 -23
- package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
- package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
- package/.agents/scripts/lib/observability/signal-validator.js +5 -37
- package/.agents/scripts/lib/observability/signals-writer.js +11 -121
- package/.agents/scripts/lib/observability/source-classifier.js +21 -203
- package/.agents/scripts/lib/observability/terse-result.js +14 -47
- package/.agents/scripts/lib/onboard/init-tail.js +13 -74
- package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
- package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
- package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +5 -75
- package/.agents/scripts/lib/orchestration/change-set.js +7 -36
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
- package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
- package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
- package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
- package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
- package/.agents/scripts/lib/orchestration/check-state.js +92 -0
- package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +42 -189
- package/.agents/scripts/lib/orchestration/code-review.js +24 -128
- package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
- package/.agents/scripts/lib/orchestration/complexity-gate.js +42 -214
- package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
- package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
- package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
- package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
- package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
- package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
- package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
- package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
- package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
- package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
- package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
- package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
- package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
- package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
- package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
- package/.agents/scripts/lib/orchestration/light-suitability.js +26 -231
- package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
- package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
- package/.agents/scripts/lib/orchestration/plan-context.js +52 -303
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
- package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
- package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
- package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
- package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
- package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +14 -78
- package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
- package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
- package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
- package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +49 -248
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
- package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
- package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
- package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
- package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
- package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
- package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
- package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
- package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
- package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
- package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
- package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
- package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
- package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
- package/.agents/scripts/lib/orchestration/review-depth.js +12 -94
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
- package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
- package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
- package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
- package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
- package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
- package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
- package/.agents/scripts/lib/orchestration/run-epilogue.js +40 -199
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
- package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
- package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
- package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +18 -80
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +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 +9 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +110 -290
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
- package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
- package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
- package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
- package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -201
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
- package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
- package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
- package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
- package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -126
- package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
- package/.agents/scripts/lib/orchestration/ticket-validator.js +39 -181
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
- package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
- package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
- package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
- package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
- package/.agents/scripts/lib/path-security.js +3 -6
- package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
- package/.agents/scripts/lib/preflight-runner.js +13 -69
- package/.agents/scripts/lib/process-group.js +143 -0
- package/.agents/scripts/lib/project-root.js +2 -8
- package/.agents/scripts/lib/provider-factory.js +2 -25
- package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
- package/.agents/scripts/lib/qa/qa-session.js +15 -69
- package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
- package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
- package/.agents/scripts/lib/reserved-test-ids.js +9 -47
- package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
- package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
- package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
- package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
- package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
- package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
- package/.agents/scripts/lib/signals/detectors/common.js +12 -38
- package/.agents/scripts/lib/signals/index.js +2 -19
- package/.agents/scripts/lib/signals/schema.js +14 -109
- package/.agents/scripts/lib/signals/write.js +2 -11
- package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
- package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
- package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
- package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
- package/.agents/scripts/lib/single-story-sweep.js +14 -97
- package/.agents/scripts/lib/skills/parse-skill.js +13 -59
- package/.agents/scripts/lib/skills/skills-index.js +8 -29
- package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
- package/.agents/scripts/lib/source-extensions.js +11 -42
- package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
- package/.agents/scripts/lib/stdio-flush.js +9 -36
- package/.agents/scripts/lib/story-adjacency.js +8 -40
- package/.agents/scripts/lib/story-body/body-format-lints.js +22 -83
- package/.agents/scripts/lib/story-body/footer-block.js +11 -44
- package/.agents/scripts/lib/story-body/story-body.js +83 -358
- package/.agents/scripts/lib/temp-retention.js +42 -143
- package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
- package/.agents/scripts/lib/test-env.js +12 -65
- package/.agents/scripts/lib/test-run-credit.js +10 -65
- package/.agents/scripts/lib/test-runner-contract.js +19 -74
- package/.agents/scripts/lib/test-temp.js +38 -184
- package/.agents/scripts/lib/test-tiers.js +12 -96
- package/.agents/scripts/lib/ticket-body-sections.js +21 -96
- package/.agents/scripts/lib/transpile.js +15 -74
- package/.agents/scripts/lib/util/concurrent-map.js +6 -25
- package/.agents/scripts/lib/util/parse-id-list.js +8 -34
- package/.agents/scripts/lib/util/poll-loop.js +8 -28
- package/.agents/scripts/lib/util/with-timeout.js +2 -11
- package/.agents/scripts/lib/validation-evidence.js +21 -96
- package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
- package/.agents/scripts/lib/wave-runner/live-probe.js +53 -221
- package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
- package/.agents/scripts/lib/workers/crap-worker.js +11 -64
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
- package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
- package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
- package/.agents/scripts/lib/workflow-closure.js +22 -105
- package/.agents/scripts/lib/workspace-provisioner.js +16 -54
- package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
- package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
- package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
- package/.agents/scripts/lib/worktree-manager.js +15 -40
- package/.agents/scripts/lint-issue-body.js +12 -68
- package/.agents/scripts/mandrel-update-preflight.js +10 -70
- package/.agents/scripts/merge-baseline.js +30 -104
- package/.agents/scripts/nav-registry-diff.js +22 -108
- package/.agents/scripts/notify.js +12 -69
- package/.agents/scripts/plan-context.js +27 -111
- package/.agents/scripts/plan-critics.js +12 -66
- package/.agents/scripts/plan-persist.js +31 -148
- package/.agents/scripts/plan-run-epilogue.js +11 -37
- package/.agents/scripts/pr-watch-with-update.js +76 -267
- package/.agents/scripts/providers/github/auth.js +3 -8
- package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
- package/.agents/scripts/providers/github/board-add.js +5 -21
- package/.agents/scripts/providers/github/branch-protection.js +11 -43
- package/.agents/scripts/providers/github/cache.js +2 -14
- package/.agents/scripts/providers/github/comments.js +7 -40
- package/.agents/scripts/providers/github/compose.js +3 -19
- package/.agents/scripts/providers/github/errors.js +22 -125
- package/.agents/scripts/providers/github/issues.js +31 -123
- package/.agents/scripts/providers/github/labels.js +24 -124
- package/.agents/scripts/providers/github/mappers.js +5 -27
- package/.agents/scripts/providers/github/merge-methods.js +3 -22
- package/.agents/scripts/providers/github/project-board.js +2 -17
- package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
- package/.agents/scripts/providers/github/request-helpers.js +5 -32
- package/.agents/scripts/providers/github/search-budget.js +9 -39
- package/.agents/scripts/providers/github/search-query.js +5 -26
- package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
- package/.agents/scripts/providers/github/sub-issues.js +7 -36
- package/.agents/scripts/providers/github/tickets.js +32 -134
- package/.agents/scripts/providers/github.js +18 -59
- package/.agents/scripts/prune-plan-run-labels.js +12 -46
- package/.agents/scripts/quality-preview.js +35 -220
- package/.agents/scripts/resolve-doc-tiers.js +3 -26
- package/.agents/scripts/resolve-stories.js +16 -67
- package/.agents/scripts/resync-status-column.js +6 -25
- package/.agents/scripts/run-tests.js +29 -104
- package/.agents/scripts/single-story-close.js +23 -135
- package/.agents/scripts/single-story-confirm-merge.js +32 -139
- package/.agents/scripts/single-story-init.js +47 -209
- package/.agents/scripts/stories-wave-tick.js +102 -472
- package/.agents/scripts/sync-agentrc.js +3 -21
- package/.agents/scripts/sync-claude-agents.js +9 -55
- package/.agents/scripts/sync-claude-commands.js +20 -110
- package/.agents/scripts/test-wrapper.js +6 -43
- package/.agents/scripts/update-coverage-baseline.js +5 -22
- package/.agents/scripts/update-crap-baseline.js +7 -30
- package/.agents/scripts/update-duplication-baseline.js +16 -92
- package/.agents/scripts/update-maintainability-baseline.js +8 -62
- package/.agents/scripts/update-ticket-state.js +1 -7
- package/.agents/scripts/validate-skills.js +6 -26
- package/.agents/templates/agent-protocol.md +2 -2
- package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
- package/.agents/workflows/audit-accessibility.md +4 -7
- package/.agents/workflows/audit-adrs.md +3 -6
- package/.agents/workflows/audit-architecture.md +3 -11
- package/.agents/workflows/audit-baselines.md +6 -9
- package/.agents/workflows/audit-clean-code.md +8 -12
- package/.agents/workflows/audit-data-model.md +3 -7
- package/.agents/workflows/audit-dependencies.md +4 -7
- package/.agents/workflows/audit-devops.md +4 -8
- package/.agents/workflows/audit-documentation.md +1 -4
- package/.agents/workflows/audit-mobile.md +4 -7
- package/.agents/workflows/audit-navigability.md +3 -6
- package/.agents/workflows/audit-performance.md +2 -4
- package/.agents/workflows/audit-privacy.md +4 -7
- package/.agents/workflows/audit-quality.md +4 -7
- package/.agents/workflows/audit-security.md +4 -7
- package/.agents/workflows/audit-seo.md +4 -7
- package/.agents/workflows/audit-sre.md +4 -7
- package/.agents/workflows/audit-to-stories.md +17 -30
- package/.agents/workflows/audit-ux-ui.md +4 -7
- package/.agents/workflows/helpers/audit-lens-core.md +1 -1
- package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
- package/.agents/workflows/helpers/deliver-digest.md +6 -4
- package/.agents/workflows/helpers/deliver-reference.md +114 -188
- package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
- package/.agents/workflows/helpers/plan-reference.md +86 -139
- package/.agents/workflows/helpers/qa-core.md +12 -0
- package/.agents/workflows/memory-consolidate.md +1 -1
- package/.agents/workflows/qa-assist.md +27 -71
- package/.agents/workflows/qa-explore.md +19 -59
- package/.agents/workflows/qa-run.md +11 -33
- package/README.md +1 -1
- package/bin/mandrel.js +5 -46
- package/bin/postinstall.js +18 -107
- package/docs/CHANGELOG.md +25 -0
- package/lib/cli/doctor.js +11 -71
- package/lib/cli/init.js +26 -165
- package/lib/cli/migrate.js +5 -64
- package/lib/cli/registry.js +84 -467
- package/lib/cli/sync-agents.js +4 -64
- package/lib/cli/sync-commands.js +11 -64
- package/lib/cli/sync.js +34 -213
- package/lib/cli/uninstall.js +40 -219
- package/lib/cli/update.js +105 -661
- package/lib/cli/version-check.js +8 -72
- package/lib/cli/version-helpers.js +14 -87
- package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
- package/lib/migrations/index.js +15 -92
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
- package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
- package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
- package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
- package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
- package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
- package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
- package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +2 -21
- package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
- package/package.json +16 -14
- package/.agents/docs/SDLC.md +0 -590
- package/.agents/docs/quality-gates.md +0 -1183
- package/.agents/rules/known-tooling-behavior.md +0 -200
- package/.agents/rules/orchestration-error-handling.md +0 -61
- package/.agents/rules/test-seams.md +0 -59
- package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
- package/.agents/schemas/baselines/lint.schema.json +0 -47
- package/.agents/scripts/check-action-pinning.js +0 -260
- package/.agents/scripts/check-audit-attribution.js +0 -302
- package/.agents/scripts/check-baseline-drift.js +0 -211
- package/.agents/scripts/check-baseline-scope.js +0 -362
- package/.agents/scripts/check-generated-validator.js +0 -202
- package/.agents/scripts/check-knip-entries.js +0 -159
- package/.agents/scripts/check-lifecycle-lint.js +0 -294
- package/.agents/scripts/check-pinned-override-notes.js +0 -102
- package/.agents/scripts/check-schema-references.js +0 -368
- package/.agents/scripts/check-test-portability.js +0 -512
- package/.agents/scripts/check-workflow-citations.js +0 -218
- package/.agents/scripts/check-workflow-cli-lint.js +0 -299
- package/.agents/scripts/check-workflow-timeouts.js +0 -291
- package/.agents/scripts/install-matrix-assert.js +0 -326
- package/.agents/scripts/lib/audit-advisories.js +0 -195
- package/.agents/scripts/lib/audit-attribution.js +0 -134
- package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
- package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
- package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
- package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
- package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
- package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
- package/.agents/scripts/lib/c8-cli-path.js +0 -21
- package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
- package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
- package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
- package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
- package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
- package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
- package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
- package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
- package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
- package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
- package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
- package/.agents/scripts/lib/fs-walk.js +0 -52
- package/.agents/scripts/lib/knip-config-resolver.js +0 -181
- package/.agents/scripts/lib/knip-entry-sync.js +0 -452
- package/.agents/scripts/lib/pinned-override-notes.js +0 -88
- package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
- package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
- package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
- package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
- package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
- package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
- package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
- package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
- package/.agents/scripts/lib/test-isolate/runner.js +0 -483
- package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
- package/.agents/scripts/lib/test-profile/render-report.js +0 -45
- package/.agents/scripts/lint-label-vocabulary.js +0 -214
- package/.agents/scripts/post-structured-comment.js +0 -127
- package/.agents/scripts/provision-git-hooks.js +0 -85
- package/.agents/scripts/prune-baseline-orphans.js +0 -181
- package/.agents/scripts/run-coverage.js +0 -197
- package/.agents/scripts/run-lint.js +0 -133
- package/.agents/scripts/run-test-profile.js +0 -129
- package/.agents/scripts/run-verify.js +0 -125
- package/.agents/scripts/test-isolate.js +0 -55
- package/.agents/scripts/update-dead-exports-baseline.js +0 -321
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* CLI: keep the committed `.agentrc` validator in step with its schema
|
|
4
|
-
* (Story #5109).
|
|
5
|
-
*
|
|
6
|
-
* `getAgentrcValidator()` used to compile `AGENTRC_SCHEMA` with AJV in every
|
|
7
|
-
* process that touched configuration — 36 of the 79 entry scripts, at ~35 ms
|
|
8
|
-
* each — to produce a function that is a pure derivative of a literal already
|
|
9
|
-
* committed to the repository. The compile is now done **once, here**, and its
|
|
10
|
-
* output is committed as `lib/generated/agentrc-validator.js`; the runtime
|
|
11
|
-
* imports that module and only falls back to a live compile behind
|
|
12
|
-
* `MANDREL_AGENTRC_VALIDATOR=dynamic`.
|
|
13
|
-
*
|
|
14
|
-
* A generated artifact that nothing re-derives is a lie waiting to happen, so
|
|
15
|
-
* this script joins the standalone-ratchet family — `check-arch-cycles.js`,
|
|
16
|
-
* `check-cyclomatic.js`, `check-dead-exports.js` — and follows their contract:
|
|
17
|
-
*
|
|
18
|
-
* - `--check` regenerates in memory and compares against the committed
|
|
19
|
-
* file. Exit 0 when they agree, exit 1 (naming the fix) when they do not.
|
|
20
|
-
* `npm run lint` runs this, so a schema edit that skips regeneration is
|
|
21
|
-
* refused before it can ship a validator that accepts the wrong config.
|
|
22
|
-
* - No flag rewrites the file. That is the sanctioned motion after a
|
|
23
|
-
* deliberate schema change.
|
|
24
|
-
*
|
|
25
|
-
* The comparison is over the exact bytes, which is what makes the gate
|
|
26
|
-
* meaningful: AJV's standalone emit is deterministic for a given schema and
|
|
27
|
-
* AJV version, so a diff means either the schema moved or the compiler did,
|
|
28
|
-
* and both demand a fresh artifact.
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
import fs from 'node:fs';
|
|
32
|
-
import { createRequire } from 'node:module';
|
|
33
|
-
import path from 'node:path';
|
|
34
|
-
import process from 'node:process';
|
|
35
|
-
import { runAsCli } from './lib/cli-utils.js';
|
|
36
|
-
import { AGENTRC_SCHEMA } from './lib/config-settings-schema.js';
|
|
37
|
-
|
|
38
|
-
const require = createRequire(import.meta.url);
|
|
39
|
-
|
|
40
|
-
/** Repo-relative home of the committed artifact. */
|
|
41
|
-
export const GENERATED_VALIDATOR_PATH =
|
|
42
|
-
'.agents/scripts/lib/generated/agentrc-validator.js';
|
|
43
|
-
|
|
44
|
-
/** The command that rewrites it — quoted in every failure message. */
|
|
45
|
-
const REGEN_COMMAND = 'npm run validator:gen';
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* AJV options for the generated validator.
|
|
49
|
-
*
|
|
50
|
-
* `allErrors: true` MUST match the runtime fallback in
|
|
51
|
-
* `config-settings-schema.js#getAgentrcValidator` — it is the difference
|
|
52
|
-
* between reporting one error and reporting all of them, and every caller
|
|
53
|
-
* that renders `validate.errors` would change behaviour if the two diverged.
|
|
54
|
-
* `code.source` is what makes the instance emittable; `code.esm` selects the
|
|
55
|
-
* ES-module emit. Neither touches validation semantics.
|
|
56
|
-
*/
|
|
57
|
-
const AJV_OPTIONS = Object.freeze({
|
|
58
|
-
allErrors: true,
|
|
59
|
-
code: { source: true, esm: true },
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Banner prepended to the emitted module.
|
|
64
|
-
*
|
|
65
|
-
* The `createRequire` shim is load-bearing: AJV's `esm` emit still reaches for
|
|
66
|
-
* its shared runtime helpers (`ajv/dist/runtime/*`) with `require(...)`, which
|
|
67
|
-
* is not defined inside an ES module. Handing the generated code a real
|
|
68
|
-
* `require` is the smallest fix that keeps the emit verbatim — rewriting those
|
|
69
|
-
* calls into imports would mean re-deriving AJV's own codegen by hand, and
|
|
70
|
-
* would silently rot the next time it changes shape.
|
|
71
|
-
*
|
|
72
|
-
* The coverage pragma matches `config-settings-schema.js`: generated code has
|
|
73
|
-
* no branches anyone authored, so a coverage figure over it measures nothing.
|
|
74
|
-
*/
|
|
75
|
-
const BANNER = `/* node:coverage ignore file -- generated artifact; see check-generated-validator.js */
|
|
76
|
-
/**
|
|
77
|
-
* GENERATED FILE — DO NOT EDIT.
|
|
78
|
-
*
|
|
79
|
-
* Precompiled AJV validator for \`AGENTRC_SCHEMA\`
|
|
80
|
-
* (.agents/scripts/lib/config-settings-schema.js), emitted by
|
|
81
|
-
* .agents/scripts/check-generated-validator.js.
|
|
82
|
-
*
|
|
83
|
-
* Regenerate with \`${REGEN_COMMAND}\`; \`npm run lint\` fails when this file
|
|
84
|
-
* and the schema disagree.
|
|
85
|
-
*/
|
|
86
|
-
import { createRequire } from 'node:module';
|
|
87
|
-
|
|
88
|
-
const require = createRequire(import.meta.url);
|
|
89
|
-
`;
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Emit the standalone validator source for `AGENTRC_SCHEMA`.
|
|
93
|
-
*
|
|
94
|
-
* Exported so the parity test can assert the committed artifact and a fresh
|
|
95
|
-
* emit agree without shelling out to this CLI.
|
|
96
|
-
*
|
|
97
|
-
* @returns {string} Complete module source, newline-terminated.
|
|
98
|
-
*/
|
|
99
|
-
export function generateValidatorSource() {
|
|
100
|
-
const ajvModule = require('ajv');
|
|
101
|
-
const Ajv = ajvModule.default ?? ajvModule;
|
|
102
|
-
const standaloneModule = require('ajv/dist/standalone');
|
|
103
|
-
const standaloneCode = standaloneModule.default ?? standaloneModule;
|
|
104
|
-
const ajv = new Ajv(AJV_OPTIONS);
|
|
105
|
-
const validate = ajv.compile(AGENTRC_SCHEMA);
|
|
106
|
-
const body = standaloneCode(ajv, validate);
|
|
107
|
-
return `${BANNER}\n${body.trim()}\n`;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Read the committed artifact, or `null` when it is absent.
|
|
112
|
-
*
|
|
113
|
-
* @param {string} absPath
|
|
114
|
-
* @returns {string | null}
|
|
115
|
-
*/
|
|
116
|
-
function readCommitted(absPath) {
|
|
117
|
-
try {
|
|
118
|
-
return fs.readFileSync(absPath, 'utf-8');
|
|
119
|
-
} catch {
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Top-level CLI entry. Exported so tests can drive both modes through the
|
|
126
|
-
* injected seams rather than by spawning a process.
|
|
127
|
-
*
|
|
128
|
-
* @param {{
|
|
129
|
-
* argv?: string[],
|
|
130
|
-
* cwd?: string,
|
|
131
|
-
* stdout?: { write: (s: string) => void },
|
|
132
|
-
* stderr?: { write: (s: string) => void },
|
|
133
|
-
* generateImpl?: () => string,
|
|
134
|
-
* writeFileImpl?: (p: string, data: string) => void,
|
|
135
|
-
* }} [opts]
|
|
136
|
-
* @returns {number} 0 = in step (or written); 1 = stale artifact.
|
|
137
|
-
*/
|
|
138
|
-
export function runCli({
|
|
139
|
-
argv = process.argv.slice(2),
|
|
140
|
-
cwd = process.cwd(),
|
|
141
|
-
stdout = process.stdout,
|
|
142
|
-
stderr = process.stderr,
|
|
143
|
-
generateImpl = generateValidatorSource,
|
|
144
|
-
writeFileImpl = (p, data) => fs.writeFileSync(p, data),
|
|
145
|
-
} = {}) {
|
|
146
|
-
const checkOnly = argv.includes('--check');
|
|
147
|
-
const absPath = path.resolve(cwd, GENERATED_VALIDATOR_PATH);
|
|
148
|
-
const expected = generateImpl();
|
|
149
|
-
|
|
150
|
-
if (!checkOnly) {
|
|
151
|
-
fs.mkdirSync(path.dirname(absPath), { recursive: true });
|
|
152
|
-
writeFileImpl(absPath, expected);
|
|
153
|
-
stdout.write(
|
|
154
|
-
`[generated-validator] wrote ${expected.length} bytes to ${GENERATED_VALIDATOR_PATH}\n`,
|
|
155
|
-
);
|
|
156
|
-
return 0;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const actual = readCommitted(absPath);
|
|
160
|
-
if (actual === null) {
|
|
161
|
-
stderr.write(
|
|
162
|
-
`[generated-validator] ❌ ${GENERATED_VALIDATOR_PATH} is missing — run \`${REGEN_COMMAND}\`\n`,
|
|
163
|
-
);
|
|
164
|
-
return 1;
|
|
165
|
-
}
|
|
166
|
-
if (actual !== expected) {
|
|
167
|
-
stderr.write(
|
|
168
|
-
`[generated-validator] ❌ ${GENERATED_VALIDATOR_PATH} is stale against AGENTRC_SCHEMA ` +
|
|
169
|
-
`(committed ${actual.length} bytes, regenerated ${expected.length}) — run \`${REGEN_COMMAND}\`\n`,
|
|
170
|
-
);
|
|
171
|
-
return 1;
|
|
172
|
-
}
|
|
173
|
-
stdout.write(
|
|
174
|
-
`[generated-validator] ✅ ${GENERATED_VALIDATOR_PATH} is in step with AGENTRC_SCHEMA\n`,
|
|
175
|
-
);
|
|
176
|
-
return 0;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
async function main() {
|
|
180
|
-
return runCli();
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
runAsCli(import.meta.url, main, {
|
|
184
|
-
source: 'generated-validator',
|
|
185
|
-
propagateExitCode: true,
|
|
186
|
-
errorPrefix: '[generated-validator] ❌ Fatal error',
|
|
187
|
-
usage: {
|
|
188
|
-
invocation: 'node .agents/scripts/check-generated-validator.js [--check]',
|
|
189
|
-
summary:
|
|
190
|
-
'Regenerate the committed AJV validator for `AGENTRC_SCHEMA`, or (with --check) fail when the committed artifact is stale against the schema.',
|
|
191
|
-
flags: [
|
|
192
|
-
[
|
|
193
|
-
'--check',
|
|
194
|
-
'Compare only: exit 1 when the committed artifact differs from a fresh emit. Writes nothing.',
|
|
195
|
-
],
|
|
196
|
-
],
|
|
197
|
-
notes: [
|
|
198
|
-
'Exit codes:\n 0 artifact written, or already in step\n 1 committed artifact is missing or stale',
|
|
199
|
-
`Regenerate with \`${REGEN_COMMAND}\`. The runtime falls back to a live AJV compile when MANDREL_AGENTRC_VALIDATOR=dynamic.`,
|
|
200
|
-
],
|
|
201
|
-
},
|
|
202
|
-
});
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// .agents/scripts/check-knip-entries.js — the guard #5001 left unbuilt.
|
|
4
|
-
//
|
|
5
|
-
// Story #5001 made two changes that are individually right and jointly unsafe:
|
|
6
|
-
// it replaced knip's blanket `.agents/scripts/*.js!` entry glob with an
|
|
7
|
-
// explicit list (so an uninvoked CLI surfaces as dead), and it promoted knip's
|
|
8
|
-
// `files` rule to `error` (so whole-file death produces baseline rows). The
|
|
9
|
-
// explicit list is hand-maintained; nothing checked it.
|
|
10
|
-
//
|
|
11
|
-
// So any CLI added after #5001 is, by default, invisible to knip: absent from
|
|
12
|
-
// the entry list, it reads as unreachable, emits a `{ file, symbol: '*' }` row,
|
|
13
|
-
// and drags every lib module only it imports into the dead set with it. Story
|
|
14
|
-
// #5012 hit exactly this — 5 false rows — and the ratchet's natural remedy
|
|
15
|
-
// (accept the diff) would have written live operator CLIs into
|
|
16
|
-
// `baselines/dead-exports-production.json` as expected-dead, permanently. It
|
|
17
|
-
// was caught by luck: a base-sync conflict forced a manual read of the diff.
|
|
18
|
-
//
|
|
19
|
-
// This gate removes the luck. It derives the invoked set from the executable
|
|
20
|
-
// surfaces #5001's own acceptance criterion named — package.json scripts, husky
|
|
21
|
-
// hooks, `.github/workflows`, `.agents` workflow/skill/agent/rule markdown, and
|
|
22
|
-
// script-to-script spawns — and asserts it matches the entry array of whatever
|
|
23
|
-
// configuration knip itself would load, in both directions. See
|
|
24
|
-
// `lib/knip-entry-sync.js` for why liveness means *invoked* rather than
|
|
25
|
-
// *present*, and why documentation prose does not count.
|
|
26
|
-
//
|
|
27
|
-
// Analysis-free by construction: knip's config resolver is loaded (a
|
|
28
|
-
// `knip.config.ts` has to be evaluated, not parsed), but nothing is scanned —
|
|
29
|
-
// no knip run, no scorer, no coverage artifact. Past that it is a directory
|
|
30
|
-
// read and a handful of regexes, which is what keeps it cheap enough to sit in
|
|
31
|
-
// the required-check set next to `check-baseline-scope.js`.
|
|
32
|
-
//
|
|
33
|
-
// Not-applicable is not failure (Story #5039). A repository with no knip
|
|
34
|
-
// configuration at all — and one where `knip` is not installed — exits 0 with a
|
|
35
|
-
// skip line, the same opt-in posture `qa.gherkinLint` uses. Without that, the
|
|
36
|
-
// gate could not be wired into a consumer that does not run knip, and #5001's
|
|
37
|
-
// guard stayed unbuilt everywhere it was most needed. A configuration that
|
|
38
|
-
// EXISTS but cannot be resolved still exits 2: absence and breakage are
|
|
39
|
-
// different answers.
|
|
40
|
-
//
|
|
41
|
-
// Exit codes:
|
|
42
|
-
// 0 entry list matches the invoked set, or there is no configuration to check
|
|
43
|
-
// 1 divergence — a missing, stale, phantom, or unsuffixed entry
|
|
44
|
-
// 2 the check could not run (unresolvable configuration, unusable repository)
|
|
45
|
-
|
|
46
|
-
import process from 'node:process';
|
|
47
|
-
import { runAsCli } from './lib/cli-utils.js';
|
|
48
|
-
import {
|
|
49
|
-
countDivergences,
|
|
50
|
-
renderEntrySyncReport,
|
|
51
|
-
resolveEntrySync,
|
|
52
|
-
} from './lib/knip-entry-sync.js';
|
|
53
|
-
|
|
54
|
-
const EXIT_PASS = 0;
|
|
55
|
-
const EXIT_DIVERGED = 1;
|
|
56
|
-
const EXIT_CANNOT_RUN = 2;
|
|
57
|
-
|
|
58
|
-
const HELP = {
|
|
59
|
-
invocation:
|
|
60
|
-
'node .agents/scripts/check-knip-entries.js [--cwd <dir>] [--json]',
|
|
61
|
-
summary:
|
|
62
|
-
"Assert the explicit .agents/scripts entry list in knip's resolved configuration matches the set of CLIs something actually invokes.",
|
|
63
|
-
flags: [
|
|
64
|
-
['--cwd <dir>', 'Repository root to check. Default: process.cwd().'],
|
|
65
|
-
['--json', 'Emit the report as JSON instead of text.'],
|
|
66
|
-
],
|
|
67
|
-
notes: [
|
|
68
|
-
'Resolves the config through knip itself, so every location knip supports works\n(knip.json/.jsonc, .knip.json(c), knip.ts/.js, knip.config.ts/.js,\npackage.json#knip). A TS config is evaluated, so a computed entry array reads\ncorrectly, and per-workspace entries count alongside the top-level array.',
|
|
69
|
-
'Exit codes:\n 0 entry list matches, or there is no config to check (skip)\n 1 divergence\n 2 the check could not run — a config that EXISTS but will not resolve',
|
|
70
|
-
'A missing entry is the dangerous one: knip calls the CLI dead, and accepting\nthe dead-exports diff would record a live CLI as expected-dead (Story #5012).',
|
|
71
|
-
],
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* The gate's single exit-code decision, shared by the text and `--json` paths.
|
|
76
|
-
*
|
|
77
|
-
* Kept in one place for the same reason `countDivergences` is: a direction
|
|
78
|
-
* added to the report must not be able to change one path's verdict and not
|
|
79
|
-
* the other's. Skip outranks error outranks divergence — a repository with no
|
|
80
|
-
* configuration has nothing to diverge from.
|
|
81
|
-
*
|
|
82
|
-
* @param {Awaited<ReturnType<typeof resolveEntrySync>>} report
|
|
83
|
-
* @returns {number}
|
|
84
|
-
*/
|
|
85
|
-
function exitCodeFor(report) {
|
|
86
|
-
if (report.skipped) return EXIT_PASS;
|
|
87
|
-
if (report.error) return EXIT_CANNOT_RUN;
|
|
88
|
-
return countDivergences(report) > 0 ? EXIT_DIVERGED : EXIT_PASS;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Parse argv into an options bag. An unknown flag is a config error rather than
|
|
93
|
-
* a silent no-op, matching `check-baseline-scope.js`.
|
|
94
|
-
*
|
|
95
|
-
* @param {string[]} argv
|
|
96
|
-
* @returns {{ cwd: string | null, json: boolean }}
|
|
97
|
-
*/
|
|
98
|
-
export function parseArgs(argv = []) {
|
|
99
|
-
const out = { cwd: null, json: false };
|
|
100
|
-
let i = 0;
|
|
101
|
-
while (i < argv.length) {
|
|
102
|
-
const arg = argv[i];
|
|
103
|
-
i += 1;
|
|
104
|
-
if (arg === '--json') out.json = true;
|
|
105
|
-
else if (arg === '--cwd') {
|
|
106
|
-
out.cwd = argv[i];
|
|
107
|
-
i += 1;
|
|
108
|
-
} else throw new Error(`unknown flag "${arg}" (try --help)`);
|
|
109
|
-
}
|
|
110
|
-
return out;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Top-level CLI entry. Exported so tests can drive it against a fixture tree
|
|
115
|
-
* without spawning a process.
|
|
116
|
-
*
|
|
117
|
-
* @param {{
|
|
118
|
-
* argv?: string[],
|
|
119
|
-
* cwd?: string,
|
|
120
|
-
* stdout?: { write: (s: string) => void },
|
|
121
|
-
* stderr?: { write: (s: string) => void },
|
|
122
|
-
* }} [opts]
|
|
123
|
-
* @returns {Promise<number>} 0 pass, 1 divergence, 2 cannot run
|
|
124
|
-
*/
|
|
125
|
-
export async function runCli({
|
|
126
|
-
argv = process.argv.slice(2),
|
|
127
|
-
cwd = process.cwd(),
|
|
128
|
-
stdout = process.stdout,
|
|
129
|
-
stderr = process.stderr,
|
|
130
|
-
} = {}) {
|
|
131
|
-
let args;
|
|
132
|
-
try {
|
|
133
|
-
args = parseArgs(argv);
|
|
134
|
-
} catch (err) {
|
|
135
|
-
stderr.write(`[knip-entries] ❌ ${err?.message ?? String(err)}\n`);
|
|
136
|
-
return EXIT_CANNOT_RUN;
|
|
137
|
-
}
|
|
138
|
-
const report = await resolveEntrySync({ repoRoot: args.cwd ?? cwd });
|
|
139
|
-
|
|
140
|
-
if (args.json) {
|
|
141
|
-
stdout.write(
|
|
142
|
-
`${JSON.stringify({ kind: 'knip-entry-sync', ...report }, null, 2)}\n`,
|
|
143
|
-
);
|
|
144
|
-
} else if (report.skipped) {
|
|
145
|
-
stdout.write(`[knip-entries] ⏭️ not applicable: ${report.skipped}\n`);
|
|
146
|
-
} else if (report.error) {
|
|
147
|
-
stderr.write(`[knip-entries] ❌ ${report.error}\n`);
|
|
148
|
-
} else {
|
|
149
|
-
stdout.write(`\n--- knip-entries ---\n${renderEntrySyncReport(report)}\n`);
|
|
150
|
-
}
|
|
151
|
-
return exitCodeFor(report);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
runAsCli(import.meta.url, async () => runCli(), {
|
|
155
|
-
source: 'knip-entries',
|
|
156
|
-
propagateExitCode: true,
|
|
157
|
-
errorPrefix: '[knip-entries] ❌ Fatal error',
|
|
158
|
-
usage: HELP,
|
|
159
|
-
});
|
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/* node:coverage ignore file */
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* check-lifecycle-lint.js — enforce the lifecycle lint rules that biome's
|
|
6
|
-
* stock ruleset cannot express.
|
|
7
|
-
*
|
|
8
|
-
* Rule 1 — "No Promise.all over the lifecycle surface".
|
|
9
|
-
* Files under `.agents/scripts/lib/orchestration/lifecycle/**` MUST NOT
|
|
10
|
-
* contain `Promise.all(`. The surface is the append-only ledger writer, and
|
|
11
|
-
* record ordering is the whole point of an append-only trail: a parallel
|
|
12
|
-
* write interleaves records and breaks the ordering a reader relies on.
|
|
13
|
-
* Tests under `tests/lifecycle/**` are exempt — fixtures that prove the rule
|
|
14
|
-
* bites need to carry the pattern.
|
|
15
|
-
*
|
|
16
|
-
* (Story #5024 narrowed the rationale. It was "the bus is a strictly
|
|
17
|
-
* sequential mediator; parallelizing listeners breaks repeatability", which
|
|
18
|
-
* stopped being the reason when the bus was deleted. The rule still guards a
|
|
19
|
-
* real property of what remains.)
|
|
20
|
-
*
|
|
21
|
-
* The old Rule 2 — "wildcard-observer firewall", gating any module under
|
|
22
|
-
* `lifecycle/listeners/**` that called `bus.on('*', …)` — was deleted by
|
|
23
|
-
* Story #5024 along with the bus. Both halves of its predicate became
|
|
24
|
-
* unsatisfiable in the same commit (the directory is gone and there is no
|
|
25
|
-
* `bus` to call `.on` on), so it returned zero violations by construction
|
|
26
|
-
* rather than by verification: a gate that cannot fire, of exactly the class
|
|
27
|
-
* Story #5004 retired `check-gherkin-placeholders.js` for.
|
|
28
|
-
*
|
|
29
|
-
* Rule 3 — "Auto-merge lockout" (Story #2253 / Task #2255, Epic #2172
|
|
30
|
-
* review High-1).
|
|
31
|
-
* String literals containing the substring `gh pr merge` MUST NOT
|
|
32
|
-
* appear in any file under `.agents/scripts/**` EXCEPT
|
|
33
|
-
* `lib/orchestration/single-story-close/phases/auto-merge.js` — the v2
|
|
34
|
-
* close path that replaced the Epic-era `AutomergeArmer` listener the rule
|
|
35
|
-
* was originally written against. The original safety hole was an
|
|
36
|
-
* unconditional `gh pr merge <pr> --auto --squash --delete-branch`
|
|
37
|
-
* call in `epic-deliver-finalize.js` that armed GitHub's native
|
|
38
|
-
* auto-merge BEFORE the framework's automerge predicate evaluated
|
|
39
|
-
* blocker / review state; the lockout backstops the deletion so a
|
|
40
|
-
* future refactor cannot quietly re-add it outside the armer.
|
|
41
|
-
*
|
|
42
|
-
* The rule scans STRING LITERALS only (single-quoted, double-quoted,
|
|
43
|
-
* or back-ticked) — comments are exempt because the deletion site
|
|
44
|
-
* needs prose explaining what was removed and why.
|
|
45
|
-
*
|
|
46
|
-
* The exempt path is matched by suffix so it bites even before the
|
|
47
|
-
* armer file lands (Wave 7); pre-existence is not required.
|
|
48
|
-
*
|
|
49
|
-
* Scan root:
|
|
50
|
-
* --root <dir> Scan <dir> instead of this checkout. Both surfaces are
|
|
51
|
-
* derived from it, so one flag moves the whole scan.
|
|
52
|
-
* Defaults to the repository this script ships in, which is
|
|
53
|
-
* what `npm run lint` gets by passing nothing.
|
|
54
|
-
*
|
|
55
|
-
* The seam exists for tests (Story #5052). The CLI test that proves a
|
|
56
|
-
* violation is *caught* has to plant one, and it used to plant into the
|
|
57
|
-
* live `.agents/` tree — which `tests/e2e/sync-prune.integration.test.js`
|
|
58
|
-
* copies with the real binary, so the two raced: the sync either lost the
|
|
59
|
-
* file between enumeration and `copyfile` (ENOENT) or copied it once and
|
|
60
|
-
* pruned it on the second pass, tripping an idempotence assertion. Pointing
|
|
61
|
-
* the planting test at a temp root keeps what that test was written for —
|
|
62
|
-
* discovery is still the CLI's own walk, not an injected file list — while
|
|
63
|
-
* leaving the shared tree untouched. Mirrors the `--root` seam
|
|
64
|
-
* `check-test-temp-hygiene.js` already ships for the same reason.
|
|
65
|
-
*
|
|
66
|
-
* Exit codes:
|
|
67
|
-
* 0 — clean.
|
|
68
|
-
* 1 — at least one violation; offending file + line printed to stderr.
|
|
69
|
-
*
|
|
70
|
-
* This script ships as part of `npm run lint`. It is intentionally
|
|
71
|
-
* Node-only (no ESLint dependency) because the repo's lint surface is
|
|
72
|
-
* biome + markdownlint; a custom rule fits cleanly alongside.
|
|
73
|
-
*/
|
|
74
|
-
|
|
75
|
-
import { readFileSync } from 'node:fs';
|
|
76
|
-
import path from 'node:path';
|
|
77
|
-
import { fileURLToPath } from 'node:url';
|
|
78
|
-
|
|
79
|
-
import { runAsCli } from './lib/cli-utils.js';
|
|
80
|
-
import { walkFilesByExtension } from './lib/fs-walk.js';
|
|
81
|
-
import { stripJsComments } from './lib/source-text/strip-js-comments.js';
|
|
82
|
-
|
|
83
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
84
|
-
const REPO_ROOT = path.resolve(__dirname, '..', '..');
|
|
85
|
-
|
|
86
|
-
/** Rule 1's scan surface for a given repository root. */
|
|
87
|
-
function lifecycleDirFor(root) {
|
|
88
|
-
return path.join(
|
|
89
|
-
root,
|
|
90
|
-
'.agents',
|
|
91
|
-
'scripts',
|
|
92
|
-
'lib',
|
|
93
|
-
'orchestration',
|
|
94
|
-
'lifecycle',
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/** Rule 3's scan surface for a given repository root. */
|
|
99
|
-
function scriptsDirFor(root) {
|
|
100
|
-
return path.join(root, '.agents', 'scripts');
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Files exempt from the merge-lockout rule. The path is matched by
|
|
105
|
-
* suffix against the absolute file path so the entry bites even before
|
|
106
|
-
* the file lands (Wave 7, Story #2256 / Task 8-3 adds
|
|
107
|
-
* `automerge-armer.js`; the rule still has to be in place beforehand
|
|
108
|
-
* so the lockout is enforced from the moment the deletion ships).
|
|
109
|
-
*
|
|
110
|
-
* Maintainers: do NOT widen this list without an architectural review
|
|
111
|
-
* — every additional exempt path is a new place an unauthorized
|
|
112
|
-
* auto-merge call could re-enter the codebase.
|
|
113
|
-
*/
|
|
114
|
-
const MERGE_LOCKOUT_ALLOWED_SUFFIXES = Object.freeze([
|
|
115
|
-
// v2 Story close path — the sole production code path authorized to
|
|
116
|
-
// call `gh pr merge` after the Epic AutomergeArmer listener was removed.
|
|
117
|
-
path.join(
|
|
118
|
-
'lib',
|
|
119
|
-
'orchestration',
|
|
120
|
-
'single-story-close',
|
|
121
|
-
'phases',
|
|
122
|
-
'auto-merge.js',
|
|
123
|
-
),
|
|
124
|
-
]);
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Files exempt from the merge-lockout rule because they ARE the rule
|
|
128
|
-
* (fixtures + the lint runner itself necessarily carry the literal so
|
|
129
|
-
* they can match against it). Maintainers: do NOT add production code
|
|
130
|
-
* here — see `MERGE_LOCKOUT_ALLOWED_SUFFIXES`.
|
|
131
|
-
*/
|
|
132
|
-
const MERGE_LOCKOUT_INFRASTRUCTURE_SUFFIXES = Object.freeze([
|
|
133
|
-
// The lint script itself (this file).
|
|
134
|
-
path.join('.agents', 'scripts', 'check-lifecycle-lint.js'),
|
|
135
|
-
]);
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Rule 1 enforcement. Returns an array of `{ file, line, hint }`
|
|
139
|
-
* violations. Inline disable comments (`// lint-lifecycle-disable`) on
|
|
140
|
-
* the same line opt out — but reviewers should require justification.
|
|
141
|
-
*/
|
|
142
|
-
export function findPromiseAllViolations(
|
|
143
|
-
rootDir,
|
|
144
|
-
{ read = readFileSync } = {},
|
|
145
|
-
) {
|
|
146
|
-
const violations = [];
|
|
147
|
-
for (const file of walkFilesByExtension(rootDir, '.js')) {
|
|
148
|
-
const text = read(file, 'utf8');
|
|
149
|
-
const lines = text.split('\n');
|
|
150
|
-
for (let i = 0; i < lines.length; i += 1) {
|
|
151
|
-
const line = lines[i];
|
|
152
|
-
// skip lines explicitly opting out
|
|
153
|
-
if (line.includes('lint-lifecycle-disable')) continue;
|
|
154
|
-
if (/\bPromise\.all\s*\(/.test(line)) {
|
|
155
|
-
violations.push({
|
|
156
|
-
file,
|
|
157
|
-
line: i + 1,
|
|
158
|
-
hint: 'Promise.all on the lifecycle surface interleaves ledger writes. The ledger is append-only; writes must stay sequential.',
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
return violations;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Rule 3 enforcement (Story #2253 / Task #2255, Epic #2172 review
|
|
168
|
-
* High-1). Returns an array of `{ file, line, hint }` violations for
|
|
169
|
-
* any file under `rootDir` (recursively) whose source — with comments
|
|
170
|
-
* stripped — contains a string literal carrying the substring
|
|
171
|
-
* `gh pr merge`. The allow-list (`automerge-armer.js`) and the
|
|
172
|
-
* infrastructure list (the lint script + fixtures it owns) are
|
|
173
|
-
* matched by absolute-path suffix.
|
|
174
|
-
*
|
|
175
|
-
* Exposed for unit tests so the lockout contract can be exercised
|
|
176
|
-
* against synthetic fixture trees without polluting the live source.
|
|
177
|
-
*/
|
|
178
|
-
export function findMergeLockoutViolations(
|
|
179
|
-
rootDir,
|
|
180
|
-
{
|
|
181
|
-
read = readFileSync,
|
|
182
|
-
allowSuffixes = MERGE_LOCKOUT_ALLOWED_SUFFIXES,
|
|
183
|
-
infrastructureSuffixes = MERGE_LOCKOUT_INFRASTRUCTURE_SUFFIXES,
|
|
184
|
-
} = {},
|
|
185
|
-
) {
|
|
186
|
-
const violations = [];
|
|
187
|
-
// The literal we forbid. Kept in a constant so we can refer to it in
|
|
188
|
-
// the violation `hint` without the literal appearing as a string in
|
|
189
|
-
// arbitrary positions. The space matters — `gh-pr-merge` is not the
|
|
190
|
-
// CLI, only the space-delimited form is.
|
|
191
|
-
const FORBIDDEN = 'gh pr merge';
|
|
192
|
-
const lineRe = /(['"`])((?:\\.|(?!\1).)*)\1/g;
|
|
193
|
-
for (const file of walkFilesByExtension(rootDir, '.js')) {
|
|
194
|
-
// Skip the armer (intentional carrier) and the lint infrastructure.
|
|
195
|
-
const allExempt = [...allowSuffixes, ...infrastructureSuffixes];
|
|
196
|
-
if (allExempt.some((suffix) => file.endsWith(suffix))) continue;
|
|
197
|
-
|
|
198
|
-
const raw = read(file, 'utf8');
|
|
199
|
-
const rawLines = raw.split('\n');
|
|
200
|
-
const stripped = stripJsComments(raw);
|
|
201
|
-
const lines = stripped.split('\n');
|
|
202
|
-
for (let i = 0; i < lines.length; i += 1) {
|
|
203
|
-
const line = lines[i];
|
|
204
|
-
// Honour the opt-out marker; it lives in a comment (and is
|
|
205
|
-
// therefore stripped above), so consult the RAW line for the
|
|
206
|
-
// marker check. Kept consistent with Rule 1.
|
|
207
|
-
const rawLine = rawLines[i] ?? '';
|
|
208
|
-
if (rawLine.includes('lint-lifecycle-disable')) continue;
|
|
209
|
-
// Find every string literal on the (comment-stripped) line and
|
|
210
|
-
// inspect its body.
|
|
211
|
-
lineRe.lastIndex = 0;
|
|
212
|
-
let match = lineRe.exec(line);
|
|
213
|
-
while (match !== null) {
|
|
214
|
-
const literalBody = match[2];
|
|
215
|
-
if (literalBody.includes(FORBIDDEN)) {
|
|
216
|
-
violations.push({
|
|
217
|
-
file,
|
|
218
|
-
line: i + 1,
|
|
219
|
-
hint: `String literal containing '${FORBIDDEN}' is forbidden outside single-story-close/phases/auto-merge.js. Auto-merge enablement must flow through the Story close path.`,
|
|
220
|
-
});
|
|
221
|
-
break; // one violation per line is enough
|
|
222
|
-
}
|
|
223
|
-
match = lineRe.exec(line);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
return violations;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Parse the argument vector. The only option is the scan root; anything
|
|
232
|
-
* else is ignored so an extra flag can never silently narrow the scan.
|
|
233
|
-
*
|
|
234
|
-
* @param {string[]} argv Arguments without the node/script entries.
|
|
235
|
-
* @returns {{ root: string }}
|
|
236
|
-
*/
|
|
237
|
-
function parseArgv(argv) {
|
|
238
|
-
let root = REPO_ROOT;
|
|
239
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
240
|
-
if (argv[i] === '--root') {
|
|
241
|
-
i += 1;
|
|
242
|
-
root = path.resolve(String(argv[i] ?? '.'));
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
return { root };
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
async function main() {
|
|
249
|
-
const { root } = parseArgv(process.argv.slice(2));
|
|
250
|
-
// Per-rule discovery. Both rules' exemptions match by absolute-path
|
|
251
|
-
// SUFFIX, which is what lets an injected root keep the same allow-list
|
|
252
|
-
// semantics as the live tree — do not re-anchor them to `root`.
|
|
253
|
-
const v1 = findPromiseAllViolations(lifecycleDirFor(root));
|
|
254
|
-
const v3 = findMergeLockoutViolations(scriptsDirFor(root));
|
|
255
|
-
const all = [
|
|
256
|
-
...v1.map((v) => ({ rule: 'no-promise-all-lifecycle', ...v })),
|
|
257
|
-
...v3.map((v) => ({ rule: 'merge-lockout', ...v })),
|
|
258
|
-
];
|
|
259
|
-
if (all.length === 0) {
|
|
260
|
-
process.stdout.write(
|
|
261
|
-
'[lifecycle-lint] clean: no Promise.all on the lifecycle surface; no merge-lockout violations.\n',
|
|
262
|
-
);
|
|
263
|
-
return 0;
|
|
264
|
-
}
|
|
265
|
-
for (const v of all) {
|
|
266
|
-
// Both finders always stamp a 1-based `line`, so there is no file-only
|
|
267
|
-
// fallback to render — the ternary that used to guard this was an
|
|
268
|
-
// unreachable branch (Story #5024).
|
|
269
|
-
process.stderr.write(
|
|
270
|
-
`[lifecycle-lint][${v.rule}] ${v.file}:${v.line}\n ${v.hint}\n`,
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
return 1;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
await runAsCli(import.meta.url, main, {
|
|
277
|
-
source: 'check-lifecycle-lint',
|
|
278
|
-
propagateExitCode: true,
|
|
279
|
-
usage: {
|
|
280
|
-
invocation: 'node .agents/scripts/check-lifecycle-lint.js [--root <dir>]',
|
|
281
|
-
summary:
|
|
282
|
-
'Enforce the two lifecycle lint rules biome cannot express: no Promise.all on the append-only lifecycle surface, and the auto-merge lockout on string literals under .agents/scripts/.',
|
|
283
|
-
flags: [
|
|
284
|
-
[
|
|
285
|
-
'--root <dir>',
|
|
286
|
-
'Repository root to scan (default: the checkout this script ships in). Both rule surfaces derive from it; used by tests so a planted violation never touches the shared tree.',
|
|
287
|
-
],
|
|
288
|
-
],
|
|
289
|
-
notes: [
|
|
290
|
-
'Ships as part of `npm run lint`, which invokes it with no arguments.',
|
|
291
|
-
'Exit codes:\n 0 clean\n 1 at least one violation; offending file and line printed to stderr',
|
|
292
|
-
],
|
|
293
|
-
},
|
|
294
|
-
});
|