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,18 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* run
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* 1. Selects the cross-Story audit lens roster over the combined landed
|
|
6
|
-
* tip vs base (deterministic `selectAudits` — host walks lenses).
|
|
7
|
-
* 2. Rolls up friction follow-ups across every Story in the run and
|
|
8
|
-
* files/posts them on the primary Story.
|
|
9
|
-
* 3. Checks sibling Spec/acceptance coherence across Story bodies.
|
|
10
|
-
* 4. Reports what the per-Story land tails left the run's container Epics
|
|
11
|
-
* in — closed, or still open (Story #5139; read-only since #5280).
|
|
12
|
-
*
|
|
13
|
-
* There is no inert planner-only path: `planRunEpilogue` enumerates steps
|
|
14
|
-
* and `runPlanRunEpilogue` executes them. Single-Story runs skip the
|
|
15
|
-
* epilogue (`applicable: false`).
|
|
2
|
+
* Per-run closeout after the last Story of a multi-Story run lands: optional
|
|
3
|
+
* audit roster, friction roll-up, and a read-only container-Epic report.
|
|
4
|
+
* Single-Story runs are `applicable: false`.
|
|
16
5
|
*
|
|
17
6
|
* @module lib/orchestration/run-epilogue
|
|
18
7
|
*/
|
|
@@ -27,42 +16,28 @@ import {
|
|
|
27
16
|
assessRollupOutcome,
|
|
28
17
|
buildFollowUpsCommentBody,
|
|
29
18
|
gatherRunFrictionSignals,
|
|
19
|
+
publishFollowUpsRollup,
|
|
30
20
|
resolveFollowUpRepos,
|
|
31
21
|
summarizeSignalCategories,
|
|
32
22
|
} from './story-follow-ups.js';
|
|
33
23
|
import { upsertStructuredComment } from './ticketing.js';
|
|
34
24
|
|
|
35
25
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
26
|
+
* Step kinds in execution order. `audit-roster` is opt-in (`--audit-roster`)
|
|
27
|
+
* because it costs a sub-agent per lens; the other two are reporting.
|
|
28
|
+
*
|
|
29
|
+
* @type {readonly ['audit-roster', 'follow-up-rollup', 'epic-close']}
|
|
38
30
|
*/
|
|
39
31
|
export const RUN_EPILOGUE_STEP_KINDS = Object.freeze([
|
|
40
32
|
'audit-roster',
|
|
41
33
|
'follow-up-rollup',
|
|
42
|
-
'sibling-coherence',
|
|
43
34
|
'epic-close',
|
|
44
35
|
]);
|
|
45
36
|
|
|
46
37
|
/**
|
|
47
|
-
* Report which container Epics
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* **It derives nothing and writes nothing.** It used to: it walked every Story
|
|
51
|
-
* and re-ran the full rollup, closing containers itself. That made sense while
|
|
52
|
-
* the rollup only fired on the edges someone had wired, and the epilogue was
|
|
53
|
-
* the backstop for the ones that were missed. Every child state change is now
|
|
54
|
-
* an edge — init, post-land, the supersede close — so by the time the last
|
|
55
|
-
* Story of a run has landed, its container has already been derived from a
|
|
56
|
-
* complete child set by that Story's own land tail. Re-deriving here would ask
|
|
57
|
-
* the same question a second time and answer it identically, at the cost of a
|
|
58
|
-
* full re-read per Story and a second writer on the same issue.
|
|
59
|
-
*
|
|
60
|
-
* What survives is the report, which is why the step exists at all: one place
|
|
61
|
-
* an operator reads to see what a multi-Story run did to its containers. A
|
|
62
|
-
* pending Epic here is a real signal — it means a land tail's rollup declined
|
|
63
|
-
* to close, and the tail's own outcome says why.
|
|
64
|
-
*
|
|
65
|
-
* Non-fatal throughout: a container it cannot read is simply not reported.
|
|
38
|
+
* Report which container Epics are closed vs still open. Read-only: each land
|
|
39
|
+
* tail already derived its container, so a pending Epic here means a tail's
|
|
40
|
+
* rollup declined to close. Unreadable containers are omitted.
|
|
66
41
|
*
|
|
67
42
|
* @param {{ stories: string[], provider: object }} opts
|
|
68
43
|
* @returns {Promise<{ kind: string, closed: number[], pending: number[] }>}
|
|
@@ -70,8 +45,7 @@ export const RUN_EPILOGUE_STEP_KINDS = Object.freeze([
|
|
|
70
45
|
async function executeEpicClose({ stories, provider }) {
|
|
71
46
|
const closed = new Set();
|
|
72
47
|
const pending = new Set();
|
|
73
|
-
// Siblings share a container:
|
|
74
|
-
// of the run's Stories point at it.
|
|
48
|
+
// Siblings share a container: report each Epic once.
|
|
75
49
|
const seen = new Set();
|
|
76
50
|
|
|
77
51
|
for (const raw of stories) {
|
|
@@ -97,11 +71,8 @@ async function executeEpicClose({ stories, provider }) {
|
|
|
97
71
|
}
|
|
98
72
|
|
|
99
73
|
/**
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* One request per Story via the declared parent port. Degrades to null on any
|
|
103
|
-
* failure and on a provider without the port — this is a report, and a
|
|
104
|
-
* container it could not read is better omitted than guessed at.
|
|
74
|
+
* Null on any failure or a provider without `getParentIssue` — omitted, never
|
|
75
|
+
* guessed.
|
|
105
76
|
*
|
|
106
77
|
* @param {{ storyId: number, provider: object }} opts
|
|
107
78
|
* @returns {Promise<object|null>}
|
|
@@ -154,14 +125,17 @@ function normalizeStoryIds(stories) {
|
|
|
154
125
|
}
|
|
155
126
|
|
|
156
127
|
/**
|
|
157
|
-
* Enumerate the ordered epilogue steps for a completed run.
|
|
158
|
-
*
|
|
159
128
|
* @param {object} args
|
|
160
129
|
* @param {string} args.planRunId
|
|
161
130
|
* @param {Array<string|number|{ id?: string|number, slug?: string }>} args.stories
|
|
131
|
+
* @param {boolean} [args.auditRoster] Default `false`.
|
|
162
132
|
* @returns {object}
|
|
163
133
|
*/
|
|
164
|
-
export function planRunEpilogue({
|
|
134
|
+
export function planRunEpilogue({
|
|
135
|
+
planRunId,
|
|
136
|
+
stories,
|
|
137
|
+
auditRoster = false,
|
|
138
|
+
} = {}) {
|
|
165
139
|
const ids = normalizeStoryIds(stories);
|
|
166
140
|
const runId =
|
|
167
141
|
typeof planRunId === 'string' && planRunId.trim() !== ''
|
|
@@ -181,29 +155,26 @@ export function planRunEpilogue({ planRunId, stories } = {}) {
|
|
|
181
155
|
};
|
|
182
156
|
}
|
|
183
157
|
|
|
184
|
-
// Positional
|
|
185
|
-
// stable adhoc id from the sorted Story set so the epilogue still
|
|
186
|
-
// anchors comments / audit roster without requiring `--run`.
|
|
158
|
+
// Positional delivery has no plan-run label: synthesize a stable adhoc id.
|
|
187
159
|
const effectiveRunId =
|
|
188
160
|
runId ??
|
|
189
161
|
`adhoc-${[...ids].sort((a, b) => Number(a) - Number(b)).join('-')}`;
|
|
190
162
|
|
|
191
163
|
const steps = [
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
164
|
+
...(auditRoster
|
|
165
|
+
? [
|
|
166
|
+
{
|
|
167
|
+
kind: 'audit-roster',
|
|
168
|
+
description: `Select cross-Story audit lenses for run ${effectiveRunId}`,
|
|
169
|
+
stories: ids,
|
|
170
|
+
},
|
|
171
|
+
]
|
|
172
|
+
: []),
|
|
197
173
|
{
|
|
198
174
|
kind: 'follow-up-rollup',
|
|
199
175
|
description: `Friction follow-up roll-up for run ${effectiveRunId}`,
|
|
200
176
|
stories: ids,
|
|
201
177
|
},
|
|
202
|
-
{
|
|
203
|
-
kind: 'sibling-coherence',
|
|
204
|
-
description: `Sibling-coherence check across the ${ids.length} Story specs of run ${effectiveRunId}`,
|
|
205
|
-
stories: ids,
|
|
206
|
-
},
|
|
207
178
|
{
|
|
208
179
|
kind: 'epic-close',
|
|
209
180
|
description: `Report the container Epic state the land tails of run ${effectiveRunId} left behind`,
|
|
@@ -220,10 +191,7 @@ export function planRunEpilogue({ planRunId, stories } = {}) {
|
|
|
220
191
|
}
|
|
221
192
|
|
|
222
193
|
/**
|
|
223
|
-
*
|
|
224
|
-
* run's landed squash-merges. The epilogue fires immediately after the run's
|
|
225
|
-
* last Story lands, so the run's merges sit within the first handful of
|
|
226
|
-
* commits; the limit only bounds the pathological case.
|
|
194
|
+
* The run's merges sit near the tip; this only bounds the pathological case.
|
|
227
195
|
* @type {number}
|
|
228
196
|
*/
|
|
229
197
|
const BASE_SCAN_LIMIT = 500;
|
|
@@ -232,8 +200,7 @@ const BASE_SCAN_LIMIT = 500;
|
|
|
232
200
|
const FIELD_SEP = '\x1f';
|
|
233
201
|
|
|
234
202
|
/**
|
|
235
|
-
*
|
|
236
|
-
* records, newest-first.
|
|
203
|
+
* Newest-first.
|
|
237
204
|
*
|
|
238
205
|
* @param {object} args
|
|
239
206
|
* @param {string} args.cwd
|
|
@@ -283,35 +250,12 @@ function readFirstParentHistory({ cwd, baseRef, scanLimit, git }) {
|
|
|
283
250
|
return { ok: true, commits };
|
|
284
251
|
}
|
|
285
252
|
|
|
286
|
-
/**
|
|
287
|
-
* One trailing `(#<n>)` / `(refs #<n>)` marker, anchored at the end of what
|
|
288
|
-
* is left of a subject after the markers to its right have been peeled off.
|
|
289
|
-
*/
|
|
290
253
|
const TRAILING_MARKER_RE = /\s*\((?:refs\s+)?#(\d+)\)$/;
|
|
291
254
|
|
|
292
255
|
/**
|
|
293
|
-
* Peel the
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
* title `normalizePrTitle` writes ends with `(#<storyId>)`, and GitHub's
|
|
297
|
-
* squash appends ` (#<prNumber>)` to it — so a landed Story merge reads
|
|
298
|
-
* `<subject> (#<storyId>) (#<prNumber>)` and the Story's own marker is the
|
|
299
|
-
* *second-to-last* marker, not the last one. Both are returned; the caller
|
|
300
|
-
* decides which ids it cares about.
|
|
301
|
-
*
|
|
302
|
-
* Why the trailing run rather than a substring scan (the bug this replaces):
|
|
303
|
-
* `subject.includes('(#101)')` matched the id **anywhere**, so an unrelated
|
|
304
|
-
* later commit quoting an old marker — canonically a revert, whose subject
|
|
305
|
-
* embeds the reverted title verbatim: `revert: "fix: x (#101) (#900)" (#950)`
|
|
306
|
-
* — anchored the run on a far-older commit and inflated the roster diff with
|
|
307
|
-
* everything in between. Peeling from the right stops at the first character
|
|
308
|
-
* that is not part of a marker (the closing quote, above), so a quoted marker
|
|
309
|
-
* is structurally out of reach.
|
|
310
|
-
*
|
|
311
|
-
* The `refs #` form is accepted because it is the other PR-title shape this
|
|
312
|
-
* repo's own history carries (`feat(x): … (refs #4575) (#4582)`) — the
|
|
313
|
-
* `refs #<id>` convention from `rules/git-conventions.md`. A plain substring
|
|
314
|
-
* scan for `(#4575)` never matched those at all.
|
|
256
|
+
* Peel the trailing run of `(#<n>)` / `(refs #<n>)` markers off a squash
|
|
257
|
+
* subject (`<title> (#<storyId>) (#<prNumber>)`). Only the trailing run
|
|
258
|
+
* counts, so a revert quoting an old title can't anchor the run on an ancient commit.
|
|
315
259
|
*
|
|
316
260
|
* @param {string} subject
|
|
317
261
|
* @returns {number[]} Marker ids, right-to-left (PR number first).
|
|
@@ -328,27 +272,15 @@ function trailingMarkerIds(subject) {
|
|
|
328
272
|
}
|
|
329
273
|
|
|
330
274
|
/**
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
* *after* the run's last Story lands, so HEAD in the main checkout is either
|
|
336
|
-
* `origin/main` itself or an ancestor of it. The three-dot merge-base is then
|
|
337
|
-
* HEAD, and the diff is empty **by construction** — it never reported the
|
|
338
|
-
* run's real diff. Rolling HEAD back does not help, so branch-reaping /
|
|
339
|
-
* cleanup ordering is not the cause; the refs being compared are.
|
|
340
|
-
*
|
|
341
|
-
* The derivation walks the base ref's first-parent history for the run's
|
|
342
|
-
* landed squash-merges. Every Story PR title carries a `(#<storyId>)` suffix
|
|
343
|
-
* (guaranteed by `normalizePrTitle` in the close pipeline) and GitHub uses the
|
|
344
|
-
* PR title as the squash subject, so the marker is a reliable, offline handle
|
|
345
|
-
* that does **not** depend on the Story branches still existing. The earliest
|
|
346
|
-
* such merge's first parent is the pre-run base.
|
|
275
|
+
* The commit the base pointed at before the run's first Story landed: the
|
|
276
|
+
* first parent of the earliest first-parent squash-merge carrying a run
|
|
277
|
+
* Story's `(#<storyId>)` marker. `origin/main...HEAD` would be empty by
|
|
278
|
+
* construction, since the epilogue runs after the last land.
|
|
347
279
|
*
|
|
348
280
|
* @param {object} args
|
|
349
|
-
* @param {Array<string|number>} args.stories
|
|
281
|
+
* @param {Array<string|number>} args.stories
|
|
350
282
|
* @param {string} args.cwd
|
|
351
|
-
* @param {string} [args.baseRef] -
|
|
283
|
+
* @param {string} [args.baseRef] - e.g. `origin/main`.
|
|
352
284
|
* @param {number} [args.scanLimit]
|
|
353
285
|
* @param {{ gitSpawn: Function }} [args.git]
|
|
354
286
|
* @returns {{ resolved: true, baseSha: string, mergeSha: string, storyId: number, baseRef: string }
|
|
@@ -378,8 +310,7 @@ export function resolveRunBaseSha({
|
|
|
378
310
|
return { resolved: false, baseRef, reason: history.reason };
|
|
379
311
|
}
|
|
380
312
|
|
|
381
|
-
//
|
|
382
|
-
// *earliest* merge belonging to the run.
|
|
313
|
+
// Walk oldest-first so the first hit is the run's earliest merge.
|
|
383
314
|
const wanted = new Set(ids);
|
|
384
315
|
for (let i = history.commits.length - 1; i >= 0; i -= 1) {
|
|
385
316
|
const commit = history.commits[i];
|
|
@@ -414,8 +345,6 @@ export function resolveRunBaseSha({
|
|
|
414
345
|
}
|
|
415
346
|
|
|
416
347
|
/**
|
|
417
|
-
* List the files the run changed: `<pre-run base>...<baseRef>`.
|
|
418
|
-
*
|
|
419
348
|
* @returns {{ ok: true, files: string[] } | { ok: false, reason: string }}
|
|
420
349
|
*/
|
|
421
350
|
function listChangedFiles({ cwd, baseSha, headRef, git }) {
|
|
@@ -444,8 +373,7 @@ function listChangedFiles({ cwd, baseSha, headRef, git }) {
|
|
|
444
373
|
}
|
|
445
374
|
|
|
446
375
|
/**
|
|
447
|
-
*
|
|
448
|
-
* be computed. Never conflates "could not compute" with "zero files changed".
|
|
376
|
+
* Never conflates "could not compute" with "zero files changed".
|
|
449
377
|
*
|
|
450
378
|
* @returns {{ resolved: boolean, changedFiles: string[], baseSha: string|null,
|
|
451
379
|
* mergeSha: string|null, baseRef: string, reason: string|null }}
|
|
@@ -489,8 +417,7 @@ function resolveCombinedDiff({ stories, cwd, baseRef, git }) {
|
|
|
489
417
|
}
|
|
490
418
|
|
|
491
419
|
/**
|
|
492
|
-
*
|
|
493
|
-
* loud failure, never as `Changed files considered: 0`.
|
|
420
|
+
* An unresolved base reads as a loud failure, never as zero files.
|
|
494
421
|
*
|
|
495
422
|
* @param {ReturnType<typeof resolveCombinedDiff>} diff
|
|
496
423
|
* @returns {string[]}
|
|
@@ -526,48 +453,18 @@ function resolveBaseRef(config) {
|
|
|
526
453
|
return `origin/${branch}`;
|
|
527
454
|
}
|
|
528
455
|
|
|
529
|
-
|
|
456
|
+
/**
|
|
457
|
+
* @param {object} args
|
|
458
|
+
* @returns {string}
|
|
459
|
+
*/
|
|
460
|
+
function renderAuditRosterBody({
|
|
530
461
|
planRunId,
|
|
531
462
|
stories,
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
git,
|
|
536
|
-
selectAuditsFn,
|
|
463
|
+
diff,
|
|
464
|
+
lensGrounding,
|
|
465
|
+
selectedAudits,
|
|
537
466
|
}) {
|
|
538
|
-
|
|
539
|
-
const diff = resolveCombinedDiff({
|
|
540
|
-
stories,
|
|
541
|
-
cwd,
|
|
542
|
-
baseRef: resolveBaseRef(config),
|
|
543
|
-
git,
|
|
544
|
-
});
|
|
545
|
-
// Hand `selectAudits` the change set we just resolved — never a git range for
|
|
546
|
-
// it to re-derive. This function runs in the main checkout *after* the run's
|
|
547
|
-
// Stories merged, so every range it could name (`main...HEAD`) is empty by
|
|
548
|
-
// construction; asking for one is how the roster came to select lenses from
|
|
549
|
-
// zero files while printing the correct file list beside them (Story #4571).
|
|
550
|
-
const lensGrounding = diff.resolved ? 'diff' : 'keyword-only';
|
|
551
|
-
let selectedAudits = [];
|
|
552
|
-
if (Number.isInteger(primaryId) && primaryId > 0) {
|
|
553
|
-
const selected = await selectAuditsFn({
|
|
554
|
-
ticketId: primaryId,
|
|
555
|
-
gate: 'gate3',
|
|
556
|
-
provider,
|
|
557
|
-
changedFiles: diff.resolved ? diff.changedFiles : [],
|
|
558
|
-
});
|
|
559
|
-
selectedAudits = Array.isArray(selected?.selectedAudits)
|
|
560
|
-
? selected.selectedAudits
|
|
561
|
-
: Array.isArray(selected)
|
|
562
|
-
? selected
|
|
563
|
-
: [];
|
|
564
|
-
}
|
|
565
|
-
if (!diff.resolved) {
|
|
566
|
-
Logger.warn(
|
|
567
|
-
`[run-epilogue] plan-run ${planRunId}: combined landed diff unavailable — ${diff.reason}`,
|
|
568
|
-
);
|
|
569
|
-
}
|
|
570
|
-
const body = [
|
|
467
|
+
return [
|
|
571
468
|
'### plan-run-audit-roster',
|
|
572
469
|
'',
|
|
573
470
|
`Cross-Story audit roster for plan-run \`${planRunId}\`.`,
|
|
@@ -580,11 +477,7 @@ async function executeAuditRoster({
|
|
|
580
477
|
? selectedAudits.map((lens) => `- \`${lens}\``)
|
|
581
478
|
: ['- _(none — docs-only or no matching change-set lenses)_']),
|
|
582
479
|
'',
|
|
583
|
-
//
|
|
584
|
-
// how to dispatch them, which made a serial walk (and a nested
|
|
585
|
-
// coordinator) fully compliant with it. The lenses are read-only and share
|
|
586
|
-
// no write paths, so they are the textbook independent fan-out; naming the
|
|
587
|
-
// shape here is what turns that from an option into the instruction.
|
|
480
|
+
// Lenses are read-only and independent; state the fan-out shape explicitly.
|
|
588
481
|
'**Dispatch shape (MUST): flat, parallel, one turn.** Spawn one ' +
|
|
589
482
|
'`auditor` sub-agent per lens listed above and issue every one of those ' +
|
|
590
483
|
'spawns in a SINGLE turn — no nested fan-out, no serial walk. A ' +
|
|
@@ -613,6 +506,53 @@ async function executeAuditRoster({
|
|
|
613
506
|
),
|
|
614
507
|
'```',
|
|
615
508
|
].join('\n');
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
async function executeAuditRoster({
|
|
512
|
+
planRunId,
|
|
513
|
+
stories,
|
|
514
|
+
cwd,
|
|
515
|
+
provider,
|
|
516
|
+
config,
|
|
517
|
+
git,
|
|
518
|
+
selectAuditsFn,
|
|
519
|
+
}) {
|
|
520
|
+
const primaryId = Number(stories[0]);
|
|
521
|
+
const diff = resolveCombinedDiff({
|
|
522
|
+
stories,
|
|
523
|
+
cwd,
|
|
524
|
+
baseRef: resolveBaseRef(config),
|
|
525
|
+
git,
|
|
526
|
+
});
|
|
527
|
+
// Pass the resolved change set, never a range: post-merge, any range
|
|
528
|
+
// `selectAudits` could derive is empty by construction.
|
|
529
|
+
const lensGrounding = diff.resolved ? 'diff' : 'keyword-only';
|
|
530
|
+
let selectedAudits = [];
|
|
531
|
+
if (Number.isInteger(primaryId) && primaryId > 0) {
|
|
532
|
+
const selected = await selectAuditsFn({
|
|
533
|
+
ticketId: primaryId,
|
|
534
|
+
gate: 'gate3',
|
|
535
|
+
provider,
|
|
536
|
+
changedFiles: diff.resolved ? diff.changedFiles : [],
|
|
537
|
+
});
|
|
538
|
+
selectedAudits = Array.isArray(selected?.selectedAudits)
|
|
539
|
+
? selected.selectedAudits
|
|
540
|
+
: Array.isArray(selected)
|
|
541
|
+
? selected
|
|
542
|
+
: [];
|
|
543
|
+
}
|
|
544
|
+
if (!diff.resolved) {
|
|
545
|
+
Logger.warn(
|
|
546
|
+
`[run-epilogue] plan-run ${planRunId}: combined landed diff unavailable — ${diff.reason}`,
|
|
547
|
+
);
|
|
548
|
+
}
|
|
549
|
+
const body = renderAuditRosterBody({
|
|
550
|
+
planRunId,
|
|
551
|
+
stories,
|
|
552
|
+
diff,
|
|
553
|
+
lensGrounding,
|
|
554
|
+
selectedAudits,
|
|
555
|
+
});
|
|
616
556
|
if (Number.isInteger(primaryId) && primaryId > 0) {
|
|
617
557
|
await upsertStructuredComment(
|
|
618
558
|
provider,
|
|
@@ -624,14 +564,9 @@ async function executeAuditRoster({
|
|
|
624
564
|
return {
|
|
625
565
|
kind: 'audit-roster',
|
|
626
566
|
selectedAudits,
|
|
627
|
-
//
|
|
628
|
-
// (`diff`) or, with no resolvable base, from the primary Story's prose
|
|
629
|
-
// alone (`keyword-only`). The two are not interchangeable: a keyword-only
|
|
630
|
-
// roster cannot select a lens that declares no keywords, so its silence
|
|
631
|
-
// about a lens says nothing about the code.
|
|
567
|
+
// A keyword-only roster's silence about a lens says nothing about the code.
|
|
632
568
|
lensGrounding,
|
|
633
|
-
// `null
|
|
634
|
-
// "the run genuinely changed nothing".
|
|
569
|
+
// `null`, not `0`, when unresolved.
|
|
635
570
|
changedFileCount: diff.resolved ? diff.changedFiles.length : null,
|
|
636
571
|
changedFiles: diff.resolved ? diff.changedFiles : null,
|
|
637
572
|
baseResolution: {
|
|
@@ -644,31 +579,19 @@ async function executeAuditRoster({
|
|
|
644
579
|
};
|
|
645
580
|
}
|
|
646
581
|
|
|
647
|
-
|
|
582
|
+
/**
|
|
583
|
+
* @param {object} args
|
|
584
|
+
* @returns {object}
|
|
585
|
+
*/
|
|
586
|
+
function composeRunProposals({
|
|
587
|
+
primaryId,
|
|
648
588
|
planRunId,
|
|
649
589
|
stories,
|
|
650
|
-
|
|
590
|
+
signals,
|
|
651
591
|
config,
|
|
652
|
-
cwd,
|
|
653
|
-
graduateFn = graduateRetroProposals,
|
|
654
592
|
}) {
|
|
655
|
-
// Shared with the story-scoped gather (Story #4649): `storyId` + `details`
|
|
656
|
-
// are what the composer's recovery-netting keys on, and two hand-rolled
|
|
657
|
-
// copies of this loop are how they got dropped in the first place.
|
|
658
|
-
const { signals, window: frictionWindow } = await gatherRunFrictionSignals(
|
|
659
|
-
stories,
|
|
660
|
-
config,
|
|
661
|
-
);
|
|
662
593
|
const repos = resolveFollowUpRepos(config);
|
|
663
|
-
|
|
664
|
-
// Story #4850 — `runToken` and `anchorStoryIds` are INPUTS. This used to
|
|
665
|
-
// compose with the primary Story's numeric id standing in for the run and
|
|
666
|
-
// then rewrite the rendered title/body by regex over a `plan-run \d+`
|
|
667
|
-
// substring, which meant the composer's own wording could not be changed
|
|
668
|
-
// without silently breaking the patch. `anchorStoryIds` is what lets the
|
|
669
|
-
// composer tell a corpus confined to this run from one spanning the whole
|
|
670
|
-
// surviving window, so it never titles the latter as if it were the former.
|
|
671
|
-
const proposals = composeRoutedProposals({
|
|
594
|
+
return composeRoutedProposals({
|
|
672
595
|
anchorId: Number.isInteger(primaryId) ? primaryId : 1,
|
|
673
596
|
anchorKind: 'run',
|
|
674
597
|
runToken: String(planRunId ?? ''),
|
|
@@ -678,18 +601,61 @@ async function executeFollowUpRollup({
|
|
|
678
601
|
signals,
|
|
679
602
|
unresolvedBlockedEvents: [],
|
|
680
603
|
});
|
|
681
|
-
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* @param {object} args
|
|
608
|
+
* @returns {Promise<object>}
|
|
609
|
+
*/
|
|
610
|
+
function fileRunProposals({
|
|
611
|
+
primaryId,
|
|
612
|
+
proposals,
|
|
613
|
+
provider,
|
|
614
|
+
config,
|
|
615
|
+
cwd,
|
|
616
|
+
graduateFn,
|
|
617
|
+
}) {
|
|
618
|
+
const repos = resolveFollowUpRepos(config);
|
|
619
|
+
return graduateFn({
|
|
682
620
|
epicId: primaryId,
|
|
683
621
|
provider,
|
|
684
622
|
config,
|
|
685
623
|
currentRepo: repos.currentRepo,
|
|
686
|
-
// The resolved bucket object, not a re-split of the slug: routing is
|
|
687
|
-
// decided once in `github/framework-repo.js`.
|
|
688
624
|
frameworkRepo: repos.repos.framework,
|
|
689
625
|
platformRepo: repos.repos.platform,
|
|
690
626
|
routedProposals: proposals,
|
|
691
627
|
cwd,
|
|
692
628
|
});
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
async function executeFollowUpRollup({
|
|
632
|
+
planRunId,
|
|
633
|
+
stories,
|
|
634
|
+
provider,
|
|
635
|
+
config,
|
|
636
|
+
cwd,
|
|
637
|
+
graduateFn = graduateRetroProposals,
|
|
638
|
+
}) {
|
|
639
|
+
const { signals, window: frictionWindow } = await gatherRunFrictionSignals(
|
|
640
|
+
stories,
|
|
641
|
+
config,
|
|
642
|
+
);
|
|
643
|
+
const primaryId = Number(stories[0]);
|
|
644
|
+
const proposals = composeRunProposals({
|
|
645
|
+
primaryId,
|
|
646
|
+
planRunId,
|
|
647
|
+
stories,
|
|
648
|
+
signals,
|
|
649
|
+
config,
|
|
650
|
+
});
|
|
651
|
+
const graduated = await fileRunProposals({
|
|
652
|
+
primaryId,
|
|
653
|
+
proposals,
|
|
654
|
+
provider,
|
|
655
|
+
config,
|
|
656
|
+
cwd,
|
|
657
|
+
graduateFn,
|
|
658
|
+
});
|
|
693
659
|
const categories = summarizeSignalCategories(signals);
|
|
694
660
|
const proposalCount = proposals.framework.length + proposals.consumer.length;
|
|
695
661
|
const outcome = assessRollupOutcome({
|
|
@@ -700,55 +666,97 @@ async function executeFollowUpRollup({
|
|
|
700
666
|
filingErrors: graduated.errors,
|
|
701
667
|
filingSkipped: graduated.skipped,
|
|
702
668
|
});
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
669
|
+
await publishRunRollup({
|
|
670
|
+
primaryId,
|
|
671
|
+
planRunId,
|
|
672
|
+
provider,
|
|
673
|
+
config,
|
|
674
|
+
proposals,
|
|
675
|
+
graduated,
|
|
676
|
+
storyCount: stories.length,
|
|
677
|
+
signalCount: signals.length,
|
|
678
|
+
categories,
|
|
679
|
+
filedCount: graduated.filed?.length ?? 0,
|
|
680
|
+
});
|
|
681
|
+
return buildRollupStepResult({
|
|
682
|
+
signals,
|
|
683
|
+
storyCount: stories.length,
|
|
684
|
+
graduated,
|
|
685
|
+
proposals,
|
|
686
|
+
proposalCount,
|
|
687
|
+
categories,
|
|
688
|
+
outcome,
|
|
689
|
+
frictionWindow,
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* @param {object} args
|
|
695
|
+
* @returns {Promise<void>}
|
|
696
|
+
*/
|
|
697
|
+
async function publishRunRollup({
|
|
698
|
+
primaryId,
|
|
699
|
+
planRunId,
|
|
700
|
+
provider,
|
|
701
|
+
config,
|
|
702
|
+
proposals,
|
|
703
|
+
graduated,
|
|
704
|
+
storyCount,
|
|
705
|
+
signalCount,
|
|
706
|
+
categories,
|
|
707
|
+
filedCount,
|
|
708
|
+
}) {
|
|
709
|
+
if (!Number.isInteger(primaryId) || primaryId <= 0) return;
|
|
710
|
+
const body = buildFollowUpsCommentBody({
|
|
711
|
+
storyId: primaryId,
|
|
712
|
+
proposals,
|
|
713
|
+
graduated,
|
|
714
|
+
storyCount,
|
|
715
|
+
signalCount,
|
|
716
|
+
categories,
|
|
717
|
+
}).replace(
|
|
718
|
+
`from Story #${primaryId}`,
|
|
719
|
+
`from plan-run \`${planRunId}\` (primary Story #${primaryId})`,
|
|
720
|
+
);
|
|
721
|
+
await publishFollowUpsRollup({
|
|
722
|
+
anchorId: primaryId,
|
|
723
|
+
body,
|
|
724
|
+
filedCount,
|
|
725
|
+
provider,
|
|
726
|
+
config,
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* The step result carries every suspect flag so the CLI never regexes the
|
|
732
|
+
* comment body.
|
|
733
|
+
*
|
|
734
|
+
* @param {object} args
|
|
735
|
+
* @returns {object}
|
|
736
|
+
*/
|
|
737
|
+
function buildRollupStepResult({
|
|
738
|
+
signals,
|
|
739
|
+
storyCount,
|
|
740
|
+
graduated,
|
|
741
|
+
proposals,
|
|
742
|
+
proposalCount,
|
|
743
|
+
categories,
|
|
744
|
+
outcome,
|
|
745
|
+
frictionWindow,
|
|
746
|
+
}) {
|
|
722
747
|
return {
|
|
723
748
|
kind: 'follow-up-rollup',
|
|
724
749
|
signalCount: signals.length,
|
|
725
|
-
storyCount
|
|
750
|
+
storyCount,
|
|
726
751
|
filed: graduated.filed?.length ?? 0,
|
|
727
|
-
//
|
|
728
|
-
// it dropped. `signalCount` alone cannot distinguish "the window is bounded
|
|
729
|
-
// at 30 days and 40 rows aged out" from "nothing older exists", and an
|
|
730
|
-
// operator triaging a roll-up needs to know which corpus produced it.
|
|
752
|
+
// What the age window excluded, so a bounded corpus is distinguishable.
|
|
731
753
|
frictionWindow,
|
|
732
|
-
// Story #4828 — everything below is what the roll-up saw and what became
|
|
733
|
-
// of it. The pre-#4828 result reported `signalCount` and `filed` and
|
|
734
|
-
// nothing in between, so nine signals routing into one proposal whose
|
|
735
|
-
// every filing attempt errored rendered as `{signalCount: 9, filed: 0,
|
|
736
|
-
// discarded: []}` — arithmetically consistent, and indistinguishable from
|
|
737
|
-
// a run with nothing to do.
|
|
738
754
|
proposalCount,
|
|
739
|
-
// The categories the corpus actually contained, so a zero-proposal
|
|
740
|
-
// roll-up names its own input rather than asserting emptiness.
|
|
741
755
|
categories,
|
|
742
756
|
filingErrors: Array.isArray(graduated.errors) ? graduated.errors : [],
|
|
743
757
|
filingSkipped: outcome.blockingSkipReasons,
|
|
744
|
-
// Signals in, nothing out — not even a below-threshold row.
|
|
745
758
|
zeroProposalSuspect: outcome.zeroProposals,
|
|
746
|
-
// Proposals cleared the threshold and the filer produced none of them.
|
|
747
759
|
unfiledProposalSuspect: outcome.unfiledProposals,
|
|
748
|
-
// Story #4824 — a roll-up that discards every candidate must still name
|
|
749
|
-
// what it discarded. Rendering that as "nothing to follow up" is how a
|
|
750
|
-
// defect recurring once per Story survived eighteen consecutive Stories.
|
|
751
|
-
// Surfaced on the step result so the CLI need not regex the comment body.
|
|
752
760
|
discarded: proposals.discarded.map((item) => ({
|
|
753
761
|
category: item.category,
|
|
754
762
|
occurrences: item.occurrences,
|
|
@@ -757,93 +765,12 @@ async function executeFollowUpRollup({
|
|
|
757
765
|
tools: item.tools ?? [],
|
|
758
766
|
fingerprint: item.fingerprint ?? null,
|
|
759
767
|
})),
|
|
760
|
-
|
|
761
|
-
// clean bill of health. Surfaced on the step result so the CLI can warn
|
|
762
|
-
// the operator without re-deriving it from the comment prose.
|
|
763
|
-
emptyRollupSuspect: signals.length === 0 && stories.length > 1,
|
|
768
|
+
emptyRollupSuspect: signals.length === 0 && storyCount > 1,
|
|
764
769
|
};
|
|
765
770
|
}
|
|
766
771
|
|
|
767
|
-
function extractSection(body, heading) {
|
|
768
|
-
if (typeof body !== 'string') return '';
|
|
769
|
-
const re = new RegExp(
|
|
770
|
-
`(?:^|\\n)## ${heading}\\s*\\n([\\s\\S]*?)(?=\\n## |$)`,
|
|
771
|
-
'i',
|
|
772
|
-
);
|
|
773
|
-
const match = body.match(re);
|
|
774
|
-
return match ? match[1].trim() : '';
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
async function executeSiblingCoherence({ planRunId, stories, provider }) {
|
|
778
|
-
const findings = [];
|
|
779
|
-
const bodies = [];
|
|
780
|
-
for (const raw of stories) {
|
|
781
|
-
const sid = Number(raw);
|
|
782
|
-
if (!Number.isInteger(sid) || sid <= 0) continue;
|
|
783
|
-
const ticket = await provider.getTicket(sid);
|
|
784
|
-
bodies.push({
|
|
785
|
-
id: sid,
|
|
786
|
-
title: ticket?.title ?? '',
|
|
787
|
-
acceptance: extractSection(ticket?.body ?? '', 'Acceptance'),
|
|
788
|
-
spec: extractSection(ticket?.body ?? '', 'Spec'),
|
|
789
|
-
});
|
|
790
|
-
}
|
|
791
|
-
const withAcceptance = bodies.filter((b) => b.acceptance.length > 0);
|
|
792
|
-
if (withAcceptance.length > 0 && withAcceptance.length < bodies.length) {
|
|
793
|
-
const missing = bodies
|
|
794
|
-
.filter((b) => b.acceptance.length === 0)
|
|
795
|
-
.map((b) => `#${b.id}`);
|
|
796
|
-
findings.push(
|
|
797
|
-
`Stories missing ## Acceptance while siblings declare ACs: ${missing.join(', ')}`,
|
|
798
|
-
);
|
|
799
|
-
}
|
|
800
|
-
// Detect identical non-empty Spec blobs (likely copy-paste drift).
|
|
801
|
-
const specMap = new Map();
|
|
802
|
-
for (const b of bodies) {
|
|
803
|
-
if (!b.spec) continue;
|
|
804
|
-
const key = b.spec.replace(/\s+/g, ' ').slice(0, 400);
|
|
805
|
-
if (!specMap.has(key)) specMap.set(key, []);
|
|
806
|
-
specMap.get(key).push(b.id);
|
|
807
|
-
}
|
|
808
|
-
for (const ids of specMap.values()) {
|
|
809
|
-
if (ids.length > 1) {
|
|
810
|
-
findings.push(
|
|
811
|
-
`Duplicate ## Spec prose across Stories ${ids.map((id) => `#${id}`).join(', ')} — split or dedupe.`,
|
|
812
|
-
);
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
const primaryId = Number(stories[0]);
|
|
816
|
-
const body = [
|
|
817
|
-
'### plan-run-sibling-coherence',
|
|
818
|
-
'',
|
|
819
|
-
`Sibling-coherence check for plan-run \`${planRunId}\`.`,
|
|
820
|
-
'',
|
|
821
|
-
findings.length === 0
|
|
822
|
-
? '_No coherence findings._'
|
|
823
|
-
: findings.map((f) => `- ${f}`).join('\n'),
|
|
824
|
-
'',
|
|
825
|
-
'```json',
|
|
826
|
-
JSON.stringify(
|
|
827
|
-
{ planRunId, stories: stories.map(Number), findings },
|
|
828
|
-
null,
|
|
829
|
-
2,
|
|
830
|
-
),
|
|
831
|
-
'```',
|
|
832
|
-
].join('\n');
|
|
833
|
-
if (Number.isInteger(primaryId) && primaryId > 0) {
|
|
834
|
-
await upsertStructuredComment(
|
|
835
|
-
provider,
|
|
836
|
-
primaryId,
|
|
837
|
-
'plan-run-sibling-coherence',
|
|
838
|
-
body,
|
|
839
|
-
);
|
|
840
|
-
}
|
|
841
|
-
return { kind: 'sibling-coherence', findings };
|
|
842
|
-
}
|
|
843
|
-
|
|
844
772
|
/**
|
|
845
|
-
*
|
|
846
|
-
* failures are collected into `errors[]`.
|
|
773
|
+
* Throws only on programmer misuse; step failures collect into `errors[]`.
|
|
847
774
|
*
|
|
848
775
|
* @param {object} args
|
|
849
776
|
* @param {string} args.planRunId
|
|
@@ -851,11 +778,10 @@ async function executeSiblingCoherence({ planRunId, stories, provider }) {
|
|
|
851
778
|
* @param {object} args.provider
|
|
852
779
|
* @param {object} [args.config]
|
|
853
780
|
* @param {string} [args.cwd]
|
|
854
|
-
* @param {{ gitSpawn: Function }} [args.git]
|
|
855
|
-
* @param {typeof selectAudits} [args.selectAuditsFn]
|
|
856
|
-
* @param {typeof graduateRetroProposals} [args.graduateFn]
|
|
857
|
-
*
|
|
858
|
-
* (Story #4828) without spawning a real `gh`.
|
|
781
|
+
* @param {{ gitSpawn: Function }} [args.git]
|
|
782
|
+
* @param {typeof selectAudits} [args.selectAuditsFn]
|
|
783
|
+
* @param {typeof graduateRetroProposals} [args.graduateFn]
|
|
784
|
+
* @param {boolean} [args.auditRoster] Default `false`.
|
|
859
785
|
* @returns {Promise<object>}
|
|
860
786
|
*/
|
|
861
787
|
export async function runPlanRunEpilogue({
|
|
@@ -867,8 +793,9 @@ export async function runPlanRunEpilogue({
|
|
|
867
793
|
git = { gitSpawn },
|
|
868
794
|
selectAuditsFn = selectAudits,
|
|
869
795
|
graduateFn = graduateRetroProposals,
|
|
796
|
+
auditRoster = false,
|
|
870
797
|
} = {}) {
|
|
871
|
-
const plan = planRunEpilogue({ planRunId, stories });
|
|
798
|
+
const plan = planRunEpilogue({ planRunId, stories, auditRoster });
|
|
872
799
|
if (!plan.applicable) {
|
|
873
800
|
return { ...plan, results: [], errors: [] };
|
|
874
801
|
}
|
|
@@ -903,14 +830,6 @@ export async function runPlanRunEpilogue({
|
|
|
903
830
|
graduateFn,
|
|
904
831
|
}),
|
|
905
832
|
);
|
|
906
|
-
} else if (step.kind === 'sibling-coherence') {
|
|
907
|
-
results.push(
|
|
908
|
-
await executeSiblingCoherence({
|
|
909
|
-
planRunId: plan.planRunId,
|
|
910
|
-
stories: plan.stories,
|
|
911
|
-
provider,
|
|
912
|
-
}),
|
|
913
|
-
);
|
|
914
833
|
} else if (step.kind === 'epic-close') {
|
|
915
834
|
results.push(
|
|
916
835
|
await executeEpicClose({ stories: plan.stories, provider }),
|