mandrel 2.60.0 → 2.62.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/README.md +10 -10
- package/.agents/agents/story-worker.md +1 -1
- package/.agents/docs/agentrc-reference.json +4 -82
- package/.agents/docs/configuration.md +20 -87
- package/.agents/docs/workflows.md +1 -1
- package/.agents/instructions.md +1 -3
- package/.agents/rules/gherkin-standards.md +4 -0
- package/.agents/schemas/agentrc.schema.json +11 -486
- package/.agents/schemas/story-deliver-terminal.schema.json +10 -0
- package/.agents/schemas/validation-evidence.schema.json +2 -1
- package/.agents/scripts/README.md +14 -14
- package/.agents/scripts/acceptance-eval.js +32 -164
- package/.agents/scripts/agents-bootstrap-github.js +27 -129
- package/.agents/scripts/apply-quality-bootstrap.js +4 -40
- package/.agents/scripts/audit-baselines.js +6 -27
- package/.agents/scripts/audit-labels-bootstrap.js +5 -29
- package/.agents/scripts/audit-to-stories.js +91 -361
- package/.agents/scripts/boot-sweep.js +19 -72
- package/.agents/scripts/bootstrap.js +74 -395
- package/.agents/scripts/ceremony-derive.js +9 -45
- package/.agents/scripts/check-arch-cycles.js +14 -64
- package/.agents/scripts/check-baselines.js +8 -48
- package/.agents/scripts/check-context-budget.js +46 -172
- package/.agents/scripts/check-cyclomatic.js +12 -44
- package/.agents/scripts/check-dead-exports.js +13 -64
- package/.agents/scripts/check-doc-links.js +38 -186
- package/.agents/scripts/check-gherkin-corpus.js +24 -127
- package/.agents/scripts/check-test-temp-hygiene.js +28 -169
- package/.agents/scripts/coverage-capture.js +32 -99
- package/.agents/scripts/deliver-light.js +14 -101
- package/.agents/scripts/deliver-recover.js +6 -42
- package/.agents/scripts/deliver-run.js +36 -133
- package/.agents/scripts/diagnose-friction.js +24 -116
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +23 -85
- package/.agents/scripts/file-ci-gap.js +10 -50
- package/.agents/scripts/generate-config-docs.js +30 -170
- package/.agents/scripts/generate-lens-checklists.js +8 -52
- package/.agents/scripts/generate-skills-index.js +14 -112
- package/.agents/scripts/generate-workflows-doc.js +10 -70
- package/.agents/scripts/git-cleanup.js +2 -34
- package/.agents/scripts/lib/Graph.js +24 -81
- package/.agents/scripts/lib/ITicketingProvider.js +47 -143
- package/.agents/scripts/lib/Logger.js +14 -76
- package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
- package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
- package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
- package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
- package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
- package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
- package/.agents/scripts/lib/audit-baselines/read.js +3 -16
- package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
- package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
- package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
- package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
- package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
- package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
- package/.agents/scripts/lib/audit-suite/findings.js +12 -52
- package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
- package/.agents/scripts/lib/audit-suite/index.js +1 -15
- package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
- package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
- package/.agents/scripts/lib/audit-suite/runner.js +13 -43
- package/.agents/scripts/lib/audit-suite/selector.js +49 -349
- package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
- package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
- package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
- package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
- package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
- package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
- package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
- package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
- package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
- package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
- package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
- package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
- package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
- package/.agents/scripts/lib/baseline-loader.js +12 -51
- package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
- package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
- package/.agents/scripts/lib/baselines/components.js +10 -61
- package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
- package/.agents/scripts/lib/baselines/crap-preview-incremental.js +5 -21
- package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
- package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
- package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
- package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
- package/.agents/scripts/lib/baselines/envelope.js +13 -129
- package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
- package/.agents/scripts/lib/baselines/git-base.js +23 -142
- package/.agents/scripts/lib/baselines/kernel.js +11 -111
- package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
- package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
- package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
- package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
- package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
- package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
- package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
- package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
- package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
- package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
- package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
- package/.agents/scripts/lib/baselines/path-canon.js +19 -128
- package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
- package/.agents/scripts/lib/baselines/reader.js +14 -107
- package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
- package/.agents/scripts/lib/baselines/scope.js +11 -135
- package/.agents/scripts/lib/baselines/writer.js +16 -149
- package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
- package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
- package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
- package/.agents/scripts/lib/bdd-step-index.js +26 -100
- package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
- package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
- package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
- package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
- package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
- package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
- package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
- package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
- package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
- package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
- package/.agents/scripts/lib/bootstrap/summary.js +1 -8
- package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
- package/.agents/scripts/lib/branch-name-guard.js +4 -23
- package/.agents/scripts/lib/changed-files.js +31 -143
- package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
- package/.agents/scripts/lib/checks/index.js +18 -101
- package/.agents/scripts/lib/checks/loop-health.js +11 -53
- package/.agents/scripts/lib/checks/state.js +16 -91
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
- package/.agents/scripts/lib/child-exec.js +39 -108
- package/.agents/scripts/lib/cli/standard-args.js +9 -116
- package/.agents/scripts/lib/cli-args.js +31 -146
- package/.agents/scripts/lib/cli-usage.js +5 -27
- package/.agents/scripts/lib/cli-utils.js +2 -12
- package/.agents/scripts/lib/close-validation/commands.js +13 -76
- package/.agents/scripts/lib/close-validation/gates.js +92 -331
- package/.agents/scripts/lib/close-validation/process.js +121 -151
- package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
- package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
- package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
- package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
- package/.agents/scripts/lib/close-validation/runner.js +53 -110
- package/.agents/scripts/lib/command-header.js +6 -28
- package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
- package/.agents/scripts/lib/config/baselines.js +3 -14
- package/.agents/scripts/lib/config/ci.js +8 -38
- package/.agents/scripts/lib/config/commands.js +1 -15
- package/.agents/scripts/lib/config/defaults.js +4 -33
- package/.agents/scripts/lib/config/delivery-routing.js +6 -35
- package/.agents/scripts/lib/config/explain.js +9 -80
- package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +2 -30
- package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
- package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
- package/.agents/scripts/lib/config/gates/index.js +2 -17
- package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
- package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
- package/.agents/scripts/lib/config/gates/shared.js +4 -64
- package/.agents/scripts/lib/config/github.js +4 -22
- package/.agents/scripts/lib/config/limits.js +4 -57
- package/.agents/scripts/lib/config/paths.js +2 -21
- package/.agents/scripts/lib/config/qa.js +4 -38
- package/.agents/scripts/lib/config/quality.js +76 -432
- package/.agents/scripts/lib/config/runners.js +12 -56
- package/.agents/scripts/lib/config/runtime.js +13 -57
- package/.agents/scripts/lib/config/shared.js +2 -16
- package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
- package/.agents/scripts/lib/config/temp-paths.js +40 -280
- package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
- package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
- package/.agents/scripts/lib/config-resolver.js +10 -52
- package/.agents/scripts/lib/config-schema-shared.js +1 -4
- package/.agents/scripts/lib/config-settings-schema-delivery.js +12 -294
- package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
- package/.agents/scripts/lib/config-settings-schema.js +37 -274
- package/.agents/scripts/lib/coverage-baseline.js +20 -110
- package/.agents/scripts/lib/coverage-capture-fullscope.js +12 -37
- package/.agents/scripts/lib/coverage-capture-incremental.js +12 -43
- package/.agents/scripts/lib/coverage-capture-usage.js +4 -24
- package/.agents/scripts/lib/coverage-capture.js +99 -224
- package/.agents/scripts/lib/coverage-utils.js +14 -79
- package/.agents/scripts/lib/cpu-pool.js +17 -123
- package/.agents/scripts/lib/crap-baseline-join.js +16 -88
- package/.agents/scripts/lib/crap-coordinates.js +6 -25
- package/.agents/scripts/lib/crap-engine.js +40 -153
- package/.agents/scripts/lib/crap-method-identity.js +16 -78
- package/.agents/scripts/lib/crap-utils.js +31 -155
- package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
- package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
- package/.agents/scripts/lib/dead-exports-knip.js +18 -56
- package/.agents/scripts/lib/dead-exports-mode.js +5 -24
- package/.agents/scripts/lib/degraded-mode.js +3 -26
- package/.agents/scripts/lib/dependency-parser.js +8 -40
- package/.agents/scripts/lib/dependency-version.js +13 -35
- package/.agents/scripts/lib/detect-package-manager.js +6 -36
- package/.agents/scripts/lib/doc-tiers.js +22 -126
- package/.agents/scripts/lib/duplicate-search.js +8 -72
- package/.agents/scripts/lib/env-loader.js +5 -27
- package/.agents/scripts/lib/error-redactor.js +6 -31
- package/.agents/scripts/lib/errors/index.js +2 -22
- package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
- package/.agents/scripts/lib/escomplex-kernel.js +21 -123
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +93 -419
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -151
- package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
- package/.agents/scripts/lib/findings/classify-finding.js +14 -69
- package/.agents/scripts/lib/findings/promote-finding.js +14 -112
- package/.agents/scripts/lib/findings/provenance-field.js +11 -52
- package/.agents/scripts/lib/findings/route-finding.js +37 -255
- package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
- package/.agents/scripts/lib/findings/severity.js +18 -104
- package/.agents/scripts/lib/format-generated-json.js +12 -44
- package/.agents/scripts/lib/full-suite-lock.js +160 -429
- package/.agents/scripts/lib/full-suite-queue.js +213 -0
- package/.agents/scripts/lib/gates/baseline-store.js +5 -9
- package/.agents/scripts/lib/gates/friction.js +1 -3
- package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
- package/.agents/scripts/lib/gh-exec.js +31 -259
- package/.agents/scripts/lib/git/cached-fetch.js +9 -52
- package/.agents/scripts/lib/git/sync-from-base.js +15 -107
- package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
- package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
- package/.agents/scripts/lib/git-utils.js +37 -161
- package/.agents/scripts/lib/github/framework-repo.js +8 -71
- package/.agents/scripts/lib/github-url.js +2 -17
- package/.agents/scripts/lib/import-graph.js +11 -38
- package/.agents/scripts/lib/install-cmd-parser.js +4 -13
- package/.agents/scripts/lib/json-utils.js +3 -18
- package/.agents/scripts/lib/label-constants.js +16 -111
- package/.agents/scripts/lib/label-taxonomy.js +4 -30
- package/.agents/scripts/lib/maintainability-engine.js +12 -80
- package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
- package/.agents/scripts/lib/maintainability-utils.js +16 -92
- package/.agents/scripts/lib/mandrel-catalog.js +12 -70
- package/.agents/scripts/lib/notifications/notifier.js +13 -38
- package/.agents/scripts/lib/npm-scripts.js +4 -23
- package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
- package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
- package/.agents/scripts/lib/observability/signal-validator.js +5 -37
- package/.agents/scripts/lib/observability/signals-writer.js +11 -121
- package/.agents/scripts/lib/observability/source-classifier.js +21 -203
- package/.agents/scripts/lib/observability/terse-result.js +14 -47
- package/.agents/scripts/lib/onboard/init-tail.js +13 -74
- package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
- package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
- package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +5 -75
- package/.agents/scripts/lib/orchestration/change-set.js +7 -36
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
- package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
- package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
- package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
- package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
- package/.agents/scripts/lib/orchestration/check-state.js +92 -0
- package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +42 -189
- package/.agents/scripts/lib/orchestration/code-review.js +24 -128
- package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
- package/.agents/scripts/lib/orchestration/complexity-gate.js +42 -214
- package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
- package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
- package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
- package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
- package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
- package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
- package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
- package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
- package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
- package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
- package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
- package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
- package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
- package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
- package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
- package/.agents/scripts/lib/orchestration/light-suitability.js +26 -231
- package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
- package/.agents/scripts/lib/orchestration/merge-queue.js +158 -0
- package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
- package/.agents/scripts/lib/orchestration/plan-context.js +52 -303
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
- package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
- package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
- package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
- package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
- package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +14 -78
- package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
- package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
- package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
- package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +49 -248
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
- package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
- package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
- package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
- package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
- package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
- package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
- package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
- package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
- package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
- package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
- package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
- package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
- package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
- package/.agents/scripts/lib/orchestration/review-depth.js +12 -94
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
- package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
- package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
- package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
- package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
- package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
- package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
- package/.agents/scripts/lib/orchestration/run-epilogue.js +40 -199
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
- package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
- package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
- package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +190 -280
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +18 -80
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +183 -485
- package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
- package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +9 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +110 -290
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
- package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
- package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
- package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
- package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -201
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
- package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
- package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
- package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
- package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -126
- package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
- package/.agents/scripts/lib/orchestration/ticket-validator.js +39 -181
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
- package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
- package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
- package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
- package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
- package/.agents/scripts/lib/path-security.js +3 -6
- package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
- package/.agents/scripts/lib/preflight-runner.js +13 -69
- package/.agents/scripts/lib/process-group.js +143 -0
- package/.agents/scripts/lib/project-root.js +2 -8
- package/.agents/scripts/lib/provider-factory.js +2 -25
- package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
- package/.agents/scripts/lib/qa/qa-session.js +15 -69
- package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
- package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
- package/.agents/scripts/lib/reserved-test-ids.js +9 -47
- package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
- package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
- package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
- package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
- package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
- package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
- package/.agents/scripts/lib/signals/detectors/common.js +12 -38
- package/.agents/scripts/lib/signals/index.js +2 -19
- package/.agents/scripts/lib/signals/schema.js +14 -109
- package/.agents/scripts/lib/signals/write.js +2 -11
- package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
- package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
- package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
- package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
- package/.agents/scripts/lib/single-story-sweep.js +14 -97
- package/.agents/scripts/lib/skills/parse-skill.js +13 -59
- package/.agents/scripts/lib/skills/skills-index.js +8 -29
- package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
- package/.agents/scripts/lib/source-extensions.js +11 -42
- package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
- package/.agents/scripts/lib/stdio-flush.js +9 -36
- package/.agents/scripts/lib/story-adjacency.js +8 -40
- package/.agents/scripts/lib/story-body/body-format-lints.js +22 -83
- package/.agents/scripts/lib/story-body/footer-block.js +11 -44
- package/.agents/scripts/lib/story-body/story-body.js +83 -358
- package/.agents/scripts/lib/temp-retention.js +42 -143
- package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
- package/.agents/scripts/lib/test-env.js +12 -65
- package/.agents/scripts/lib/test-run-credit.js +10 -65
- package/.agents/scripts/lib/test-runner-contract.js +19 -74
- package/.agents/scripts/lib/test-temp.js +38 -184
- package/.agents/scripts/lib/test-tiers.js +12 -96
- package/.agents/scripts/lib/ticket-body-sections.js +21 -96
- package/.agents/scripts/lib/transpile.js +15 -74
- package/.agents/scripts/lib/util/concurrent-map.js +6 -25
- package/.agents/scripts/lib/util/parse-id-list.js +8 -34
- package/.agents/scripts/lib/util/poll-loop.js +8 -28
- package/.agents/scripts/lib/util/with-timeout.js +2 -11
- package/.agents/scripts/lib/validation-evidence.js +21 -96
- package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
- package/.agents/scripts/lib/wave-runner/live-probe.js +53 -221
- package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
- package/.agents/scripts/lib/workers/crap-worker.js +11 -64
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
- package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
- package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
- package/.agents/scripts/lib/workflow-closure.js +22 -105
- package/.agents/scripts/lib/workspace-provisioner.js +16 -54
- package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
- package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
- package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
- package/.agents/scripts/lib/worktree-manager.js +15 -40
- package/.agents/scripts/lint-issue-body.js +12 -68
- package/.agents/scripts/mandrel-update-preflight.js +10 -70
- package/.agents/scripts/merge-baseline.js +30 -104
- package/.agents/scripts/nav-registry-diff.js +22 -108
- package/.agents/scripts/notify.js +12 -69
- package/.agents/scripts/plan-context.js +27 -111
- package/.agents/scripts/plan-critics.js +12 -66
- package/.agents/scripts/plan-persist.js +31 -148
- package/.agents/scripts/plan-run-epilogue.js +11 -37
- package/.agents/scripts/pr-watch-with-update.js +76 -267
- package/.agents/scripts/providers/github/auth.js +3 -8
- package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
- package/.agents/scripts/providers/github/board-add.js +5 -21
- package/.agents/scripts/providers/github/branch-protection.js +11 -43
- package/.agents/scripts/providers/github/cache.js +2 -14
- package/.agents/scripts/providers/github/comments.js +7 -40
- package/.agents/scripts/providers/github/compose.js +3 -19
- package/.agents/scripts/providers/github/errors.js +22 -125
- package/.agents/scripts/providers/github/issues.js +31 -123
- package/.agents/scripts/providers/github/labels.js +24 -124
- package/.agents/scripts/providers/github/mappers.js +5 -27
- package/.agents/scripts/providers/github/merge-methods.js +3 -22
- package/.agents/scripts/providers/github/project-board.js +2 -17
- package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
- package/.agents/scripts/providers/github/request-helpers.js +5 -32
- package/.agents/scripts/providers/github/search-budget.js +9 -39
- package/.agents/scripts/providers/github/search-query.js +5 -26
- package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
- package/.agents/scripts/providers/github/sub-issues.js +7 -36
- package/.agents/scripts/providers/github/tickets.js +32 -134
- package/.agents/scripts/providers/github.js +18 -59
- package/.agents/scripts/prune-plan-run-labels.js +12 -46
- package/.agents/scripts/quality-preview.js +35 -220
- package/.agents/scripts/resolve-doc-tiers.js +3 -26
- package/.agents/scripts/resolve-stories.js +16 -67
- package/.agents/scripts/resync-status-column.js +6 -25
- package/.agents/scripts/run-tests.js +29 -104
- package/.agents/scripts/single-story-close.js +23 -135
- package/.agents/scripts/single-story-confirm-merge.js +32 -139
- package/.agents/scripts/single-story-init.js +47 -209
- package/.agents/scripts/stories-wave-tick.js +102 -472
- package/.agents/scripts/sync-agentrc.js +3 -21
- package/.agents/scripts/sync-claude-agents.js +9 -55
- package/.agents/scripts/sync-claude-commands.js +20 -110
- package/.agents/scripts/test-wrapper.js +6 -43
- package/.agents/scripts/update-coverage-baseline.js +5 -22
- package/.agents/scripts/update-crap-baseline.js +7 -30
- package/.agents/scripts/update-duplication-baseline.js +16 -92
- package/.agents/scripts/update-maintainability-baseline.js +8 -62
- package/.agents/scripts/update-ticket-state.js +1 -7
- package/.agents/scripts/validate-skills.js +6 -26
- package/.agents/templates/agent-protocol.md +2 -2
- package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
- package/.agents/workflows/audit-accessibility.md +4 -7
- package/.agents/workflows/audit-adrs.md +3 -6
- package/.agents/workflows/audit-architecture.md +3 -11
- package/.agents/workflows/audit-baselines.md +6 -9
- package/.agents/workflows/audit-clean-code.md +8 -12
- package/.agents/workflows/audit-data-model.md +3 -7
- package/.agents/workflows/audit-dependencies.md +4 -7
- package/.agents/workflows/audit-devops.md +4 -8
- package/.agents/workflows/audit-documentation.md +1 -4
- package/.agents/workflows/audit-mobile.md +4 -7
- package/.agents/workflows/audit-navigability.md +3 -6
- package/.agents/workflows/audit-performance.md +2 -4
- package/.agents/workflows/audit-privacy.md +4 -7
- package/.agents/workflows/audit-quality.md +4 -7
- package/.agents/workflows/audit-security.md +4 -7
- package/.agents/workflows/audit-seo.md +4 -7
- package/.agents/workflows/audit-sre.md +4 -7
- package/.agents/workflows/audit-to-stories.md +17 -30
- package/.agents/workflows/audit-ux-ui.md +4 -7
- package/.agents/workflows/helpers/audit-lens-core.md +1 -1
- package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
- package/.agents/workflows/helpers/deliver-digest.md +6 -4
- package/.agents/workflows/helpers/deliver-reference.md +114 -188
- package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
- package/.agents/workflows/helpers/plan-reference.md +86 -139
- package/.agents/workflows/helpers/qa-core.md +12 -0
- package/.agents/workflows/memory-consolidate.md +1 -1
- package/.agents/workflows/qa-assist.md +27 -71
- package/.agents/workflows/qa-explore.md +19 -59
- package/.agents/workflows/qa-run.md +11 -33
- package/README.md +1 -1
- package/bin/mandrel.js +5 -46
- package/bin/postinstall.js +18 -107
- package/docs/CHANGELOG.md +32 -0
- package/lib/cli/doctor.js +11 -71
- package/lib/cli/init.js +26 -165
- package/lib/cli/migrate.js +5 -64
- package/lib/cli/registry.js +84 -467
- package/lib/cli/sync-agents.js +4 -64
- package/lib/cli/sync-commands.js +11 -64
- package/lib/cli/sync.js +34 -213
- package/lib/cli/uninstall.js +40 -219
- package/lib/cli/update.js +105 -661
- package/lib/cli/version-check.js +8 -72
- package/lib/cli/version-helpers.js +14 -87
- package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
- package/lib/migrations/index.js +15 -92
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
- package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
- package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
- package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
- package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
- package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
- package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
- package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +2 -21
- package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
- package/package.json +16 -14
- package/.agents/docs/SDLC.md +0 -590
- package/.agents/docs/quality-gates.md +0 -1183
- package/.agents/rules/known-tooling-behavior.md +0 -200
- package/.agents/rules/orchestration-error-handling.md +0 -61
- package/.agents/rules/test-seams.md +0 -59
- package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
- package/.agents/schemas/baselines/lint.schema.json +0 -47
- package/.agents/scripts/check-action-pinning.js +0 -260
- package/.agents/scripts/check-audit-attribution.js +0 -302
- package/.agents/scripts/check-baseline-drift.js +0 -211
- package/.agents/scripts/check-baseline-scope.js +0 -362
- package/.agents/scripts/check-generated-validator.js +0 -202
- package/.agents/scripts/check-knip-entries.js +0 -159
- package/.agents/scripts/check-lifecycle-lint.js +0 -294
- package/.agents/scripts/check-pinned-override-notes.js +0 -102
- package/.agents/scripts/check-schema-references.js +0 -368
- package/.agents/scripts/check-test-portability.js +0 -512
- package/.agents/scripts/check-workflow-citations.js +0 -218
- package/.agents/scripts/check-workflow-cli-lint.js +0 -299
- package/.agents/scripts/check-workflow-timeouts.js +0 -291
- package/.agents/scripts/install-matrix-assert.js +0 -326
- package/.agents/scripts/lib/audit-advisories.js +0 -195
- package/.agents/scripts/lib/audit-attribution.js +0 -134
- package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
- package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
- package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
- package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
- package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
- package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
- package/.agents/scripts/lib/c8-cli-path.js +0 -21
- package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
- package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
- package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
- package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
- package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
- package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
- package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
- package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
- package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
- package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
- package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
- package/.agents/scripts/lib/fs-walk.js +0 -52
- package/.agents/scripts/lib/knip-config-resolver.js +0 -181
- package/.agents/scripts/lib/knip-entry-sync.js +0 -452
- package/.agents/scripts/lib/pinned-override-notes.js +0 -88
- package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
- package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
- package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
- package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
- package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
- package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
- package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
- package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
- package/.agents/scripts/lib/test-isolate/runner.js +0 -483
- package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
- package/.agents/scripts/lib/test-profile/render-report.js +0 -45
- package/.agents/scripts/lint-label-vocabulary.js +0 -214
- package/.agents/scripts/post-structured-comment.js +0 -127
- package/.agents/scripts/provision-git-hooks.js +0 -85
- package/.agents/scripts/prune-baseline-orphans.js +0 -181
- package/.agents/scripts/run-coverage.js +0 -197
- package/.agents/scripts/run-lint.js +0 -133
- package/.agents/scripts/run-test-profile.js +0 -129
- package/.agents/scripts/run-verify.js +0 -125
- package/.agents/scripts/test-isolate.js +0 -55
- package/.agents/scripts/update-dead-exports-baseline.js +0 -321
|
@@ -31,6 +31,7 @@ import { runCloseValidationPhase } from './phases/close-validation.js';
|
|
|
31
31
|
import { parsePrNumber, runStoryScopeReview } from './phases/code-review.js';
|
|
32
32
|
import { runConfirmMergePhase } from './phases/confirm-merge.js';
|
|
33
33
|
import { runGraphqlPreflight } from './phases/graphql-preflight.js';
|
|
34
|
+
import { lockWaitPending } from './phases/lock-wait-pending.js';
|
|
34
35
|
import { parseCloseOptions, resolveWaitForMerge } from './phases/options.js';
|
|
35
36
|
import { ensurePullRequestWith } from './phases/pull-request.js';
|
|
36
37
|
import { pushStoryBranch } from './phases/push.js';
|
|
@@ -42,29 +43,11 @@ import { runWrongTreeGuardPhase } from './phases/wrong-tree-guard.js';
|
|
|
42
43
|
const progress = Logger.createProgress('single-story-close', { stderr: true });
|
|
43
44
|
|
|
44
45
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* #4543), while `STORY CLOSE RESULT` stays byte-compatible for the existing
|
|
49
|
-
* surfaces that grep it. One writer, one place — so the envelope can never
|
|
50
|
-
* be emitted from a path that forgot it.
|
|
51
|
-
*
|
|
52
|
-
* Story #4578 — the same one-place property is why the runtime-derived
|
|
53
|
-
* friction emit hangs here: a close that ends `failed`, or parks `pending`
|
|
54
|
-
* on an exhausted merge-wait budget, is friction the retro must see, and
|
|
55
|
-
* routing it through the single emitter means no terminal path can forget
|
|
56
|
-
* it. `emitTerminalFriction` decides what (if anything) is worth a record —
|
|
57
|
-
* see `frictionForTerminal` for why `blocked` and a `--no-wait-merge`
|
|
58
|
-
* `pending` are deliberately NOT flagged here.
|
|
59
|
-
*
|
|
60
|
-
* Async, and awaited by every caller: the CLI exits via `process.exit` the
|
|
61
|
-
* moment `main` resolves, so a fire-and-forget append would be discarded.
|
|
62
|
-
* The emit is best-effort internally and cannot throw.
|
|
46
|
+
* The single terminal writer: the result summary, the envelope callers parse,
|
|
47
|
+
* and terminal friction — so no ending can forget one. Must be awaited: the
|
|
48
|
+
* CLI `process.exit`s as soon as `main` resolves.
|
|
63
49
|
*/
|
|
64
50
|
async function emitTerminal({ terminal, result, config }) {
|
|
65
|
-
// Story #4685 — the human-facing result dump goes to a temp log; the agent
|
|
66
|
-
// acts on the (separate, unsuppressible) terminal envelope emitted below.
|
|
67
|
-
// The single summary line keeps the fields worth an at-a-glance read.
|
|
68
51
|
if (result) {
|
|
69
52
|
emitTerseResult({
|
|
70
53
|
label: 'STORY CLOSE RESULT',
|
|
@@ -84,23 +67,9 @@ async function emitTerminal({ terminal, result, config }) {
|
|
|
84
67
|
}
|
|
85
68
|
|
|
86
69
|
/**
|
|
87
|
-
* Terminal for
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* issue as `completed` (the `Closes #<id>` footer firing on merge — the work
|
|
91
|
-
* IS on the base branch) or as `not_planned` (superseded by a re-plan,
|
|
92
|
-
* abandoned — nothing ever merged). Reporting the second as `landed` told
|
|
93
|
-
* `/mandrel-deliver` that work had reached `main` when no PR ever merged, which would
|
|
94
|
-
* also satisfy any dependent Story waiting on it. Fail loudly instead: being
|
|
95
|
-
* handed an abandoned Story is an input error only the operator can resolve.
|
|
96
|
-
*
|
|
97
|
-
* A null `stateReason` keeps the `completed` reading — GitHub defaults to it,
|
|
98
|
-
* and issues closed before the field existed carry null.
|
|
99
|
-
*
|
|
100
|
-
* The operator-facing `NOOP` line is emitted here rather than at the call
|
|
101
|
-
* site: both halves read the same field, and deciding what `not_planned`
|
|
102
|
-
* means in two places is how the log and the envelope come to disagree about
|
|
103
|
-
* one Story.
|
|
70
|
+
* Terminal for an already-closed Story. `not_planned` means nothing merged,
|
|
71
|
+
* so it fails rather than reporting `landed` (which would also unblock
|
|
72
|
+
* dependents); `completed` or null (GitHub's default) reads as landed.
|
|
104
73
|
*/
|
|
105
74
|
async function alreadyClosedResult(storyId, stateReason = null, config) {
|
|
106
75
|
if (stateReason === 'not_planned') {
|
|
@@ -137,9 +106,6 @@ async function alreadyClosedResult(storyId, stateReason = null, config) {
|
|
|
137
106
|
action: 'noop',
|
|
138
107
|
reason: 'already-closed',
|
|
139
108
|
};
|
|
140
|
-
// Idempotent re-run against a Story closed as completed. `landed` is the
|
|
141
|
-
// honest status — the issue closed on merge, so the work is on the base
|
|
142
|
-
// branch — and there is nothing left to command.
|
|
143
109
|
const terminal = buildTerminalEnvelope({
|
|
144
110
|
storyId,
|
|
145
111
|
status: 'landed',
|
|
@@ -152,27 +118,14 @@ async function alreadyClosedResult(storyId, stateReason = null, config) {
|
|
|
152
118
|
}
|
|
153
119
|
|
|
154
120
|
/**
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
* `api-race-other` is the shared classifier's documented fallback for "a
|
|
158
|
-
* transient GraphQL/API error, an ambiguous probe result, or a genuinely
|
|
159
|
-
* novel condition", and a preflight refusal is the third of those. It is
|
|
160
|
-
* reused rather than joined by a new class on purpose: the class vocabulary
|
|
161
|
-
* is pinned by `story-deliver-terminal.schema.json`, and this refusal is
|
|
162
|
-
* required to validate against the shipped schema unchanged. The `reason`
|
|
163
|
-
* string — not the class — is what names the blocker and its remedy.
|
|
121
|
+
* Reuses the classifier's fallback class: the vocabulary is pinned by the
|
|
122
|
+
* terminal schema, so `reason` names the blocker instead.
|
|
164
123
|
*/
|
|
165
124
|
const PREFLIGHT_BLOCK_CLASS = 'api-race-other';
|
|
166
125
|
|
|
167
126
|
/**
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* Returned rather than thrown: a throw would surface as `failed` at the CLI
|
|
171
|
-
* boundary, and this is not a crash — it is a classified block detected
|
|
172
|
-
* before the pipeline spent anything, with the Story already flipped to
|
|
173
|
-
* `agent::blocked` and a friction comment carrying the remedy. The next
|
|
174
|
-
* command is the same close, which is exactly right: from a session that can
|
|
175
|
-
* reach GraphQL it runs to completion from where the Story stands now.
|
|
127
|
+
* Returned, not thrown: a classified block, not a crash (a throw surfaces as
|
|
128
|
+
* `failed`). The next command is the same close.
|
|
176
129
|
*
|
|
177
130
|
* @param {{ storyId: number, preflight: { verdict: string, reason: string },
|
|
178
131
|
* config: object, startedAtMs: number }} args
|
|
@@ -207,16 +160,7 @@ async function preflightBlockedResult({
|
|
|
207
160
|
}
|
|
208
161
|
|
|
209
162
|
/**
|
|
210
|
-
*
|
|
211
|
-
* keyed by the gate's own name (Story #5172).
|
|
212
|
-
*
|
|
213
|
-
* The envelope's `gates` map used to roll the whole gate chain up into a
|
|
214
|
-
* single `validation` verdict, which was fine while the baselines gate was
|
|
215
|
-
* one entry and stopped being fine when it became two: a reader of a failed
|
|
216
|
-
* close could not tell whether the cheap coverage-independent baselines had
|
|
217
|
-
* breached or the expensive coverage-consuming ones had. Only registered
|
|
218
|
-
* entries are reported — a consumer whose config registers just one of the
|
|
219
|
-
* pair gets just that one, never a phantom key for a gate that never existed.
|
|
163
|
+
* The split baselines gates, by name; only registered ones, never a phantom key.
|
|
220
164
|
*
|
|
221
165
|
* @param {Record<string, string>|null|undefined} validationGates
|
|
222
166
|
* @returns {Record<string, string>}
|
|
@@ -230,6 +174,22 @@ function baselinesEnvelopeGates(validationGates) {
|
|
|
230
174
|
return out;
|
|
231
175
|
}
|
|
232
176
|
|
|
177
|
+
/**
|
|
178
|
+
* @param {{ skipValidation?: boolean, skipSync?: boolean }} options
|
|
179
|
+
* @param {Record<string, string>|null} validationGates
|
|
180
|
+
* @param {object|null} reviewOverride
|
|
181
|
+
* @returns {Record<string, string>}
|
|
182
|
+
*/
|
|
183
|
+
function closeEnvelopeGates(options, validationGates, reviewOverride) {
|
|
184
|
+
return {
|
|
185
|
+
validation: options.skipValidation ? 'skipped' : 'passed',
|
|
186
|
+
...baselinesEnvelopeGates(validationGates),
|
|
187
|
+
baseSync: options.skipSync ? 'skipped' : 'passed',
|
|
188
|
+
// The review did fail; the envelope records the human override.
|
|
189
|
+
codeReview: reviewOverride ? 'overridden' : 'passed',
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
233
193
|
function resolveWorktreePath({ cwd, config, storyId }) {
|
|
234
194
|
const root = config.delivery?.worktreeIsolation?.root ?? '.worktrees';
|
|
235
195
|
const candidate = path.resolve(cwd, root, `story-${storyId}`);
|
|
@@ -237,25 +197,16 @@ function resolveWorktreePath({ cwd, config, storyId }) {
|
|
|
237
197
|
}
|
|
238
198
|
|
|
239
199
|
/**
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
* Story #5172 put base-sync AHEAD of close-validation, for two reasons that
|
|
244
|
-
* are really one. The cheap one: a base-sync conflict is a hard block that
|
|
245
|
-
* costs nothing to detect, so paying for the full gate chain before
|
|
246
|
-
* discovering it burns the pipeline's most expensive minutes on a tree that
|
|
247
|
-
* was never going to be pushed. The load-bearing one: with the gates last,
|
|
248
|
-
* **the validated tree is the pushed tree**. Under the old order the merge
|
|
249
|
-
* commit base-sync writes landed AFTER validation, so every close pushed a
|
|
250
|
-
* tree no gate had ever seen.
|
|
251
|
-
*
|
|
252
|
-
* `--skip-sync` and `--skip-validation` stay independent — either, both or
|
|
253
|
-
* neither may be set, and each still elides exactly its own phase.
|
|
200
|
+
* wrong-tree guard → base-sync → close-validation. Validation runs last so
|
|
201
|
+
* the validated tree is the pushed tree (base-sync's merge commit included),
|
|
202
|
+
* and a cheap conflict is found before the expensive gates.
|
|
254
203
|
*
|
|
255
|
-
* @returns {Promise<{
|
|
256
|
-
*
|
|
257
|
-
*
|
|
258
|
-
*
|
|
204
|
+
* @returns {Promise<{
|
|
205
|
+
* validationGates: Record<string, string>|null,
|
|
206
|
+
* lockWait: { waitedSeconds: number, expired: boolean }|null,
|
|
207
|
+
* pending: boolean,
|
|
208
|
+
* }>} `validationGates` is null when skipped; `pending` means a full-suite
|
|
209
|
+
* lock wait expired and the gates deferred.
|
|
259
210
|
*/
|
|
260
211
|
async function runPrePushPhases({
|
|
261
212
|
cwd,
|
|
@@ -301,7 +252,7 @@ async function runPrePushPhases({
|
|
|
301
252
|
}
|
|
302
253
|
if (skipValidation) {
|
|
303
254
|
progress('VALIDATE', '⏭ Skipped (--skip-validation).');
|
|
304
|
-
return { validationGates: null };
|
|
255
|
+
return { validationGates: null, lockWait: null, pending: false };
|
|
305
256
|
}
|
|
306
257
|
setPhase('close-validation');
|
|
307
258
|
let validation;
|
|
@@ -318,12 +269,7 @@ async function runPrePushPhases({
|
|
|
318
269
|
buildDefaultGates,
|
|
319
270
|
});
|
|
320
271
|
} catch (err) {
|
|
321
|
-
//
|
|
322
|
-
// reconstructing them, so hand it what this run observed. The phase tags
|
|
323
|
-
// `closeGate` with the entry that died; that one name is the whole of
|
|
324
|
-
// what the run observed about gate outcomes, and therefore the whole of
|
|
325
|
-
// what the envelope may claim. Anything else it might have named is a
|
|
326
|
-
// gate the run never proved ran at all.
|
|
272
|
+
// The gate that died is all this run observed; the envelope claims no more.
|
|
327
273
|
if (typeof err?.closeGate === 'string') {
|
|
328
274
|
setObservedGates({ [err.closeGate]: 'failed' });
|
|
329
275
|
}
|
|
@@ -331,7 +277,11 @@ async function runPrePushPhases({
|
|
|
331
277
|
}
|
|
332
278
|
const gates = validation?.gates ?? null;
|
|
333
279
|
setObservedGates(gates);
|
|
334
|
-
return {
|
|
280
|
+
return {
|
|
281
|
+
validationGates: gates,
|
|
282
|
+
lockWait: validation?.lockWait ?? null,
|
|
283
|
+
pending: validation?.pending === true,
|
|
284
|
+
};
|
|
335
285
|
}
|
|
336
286
|
|
|
337
287
|
async function openAndReviewPr({
|
|
@@ -349,17 +299,14 @@ async function openAndReviewPr({
|
|
|
349
299
|
setPhase = () => {},
|
|
350
300
|
}) {
|
|
351
301
|
setPhase('push');
|
|
352
|
-
//
|
|
353
|
-
//
|
|
354
|
-
// caller's `cwd`: they read the shared `.git`, so they resolve identically
|
|
355
|
-
// from either tree.
|
|
302
|
+
// Push from the worktree so `pre-push` measures the tree being sent; the
|
|
303
|
+
// ref-based reads below resolve identically from the shared `.git`.
|
|
356
304
|
pushStoryBranch({ cwd, worktreePath, storyBranch, gitSync, progress });
|
|
357
305
|
setPhase('pull-request');
|
|
358
306
|
const { url: prUrl, alreadyMerged } = await ensurePullRequestWith({
|
|
359
307
|
cwd,
|
|
360
308
|
storyId,
|
|
361
309
|
storyTitle: story.title,
|
|
362
|
-
// Scanned for a declared `BREAKING CHANGE:` footer — see pull-request.js.
|
|
363
310
|
storyBody: story.body,
|
|
364
311
|
storyBranch,
|
|
365
312
|
baseBranch,
|
|
@@ -367,10 +314,7 @@ async function openAndReviewPr({
|
|
|
367
314
|
progress,
|
|
368
315
|
});
|
|
369
316
|
const prNumber = parsePrNumber(prUrl);
|
|
370
|
-
//
|
|
371
|
-
// a previous close invocation was between phases). There is nothing left to
|
|
372
|
-
// review and nothing left to arm; the confirm phase probes the PR, observes
|
|
373
|
-
// MERGED, and lands the Story on the merge that actually happened.
|
|
317
|
+
// Already merged (landed between invocations): skip review and arm; confirm observes it.
|
|
374
318
|
if (alreadyMerged) {
|
|
375
319
|
return { prUrl, prNumber, alreadyMerged: true };
|
|
376
320
|
}
|
|
@@ -384,19 +328,12 @@ async function openAndReviewPr({
|
|
|
384
328
|
prNumber,
|
|
385
329
|
provider,
|
|
386
330
|
runCodeReviewFn: injectedRunCodeReview ?? runCodeReviewDefault,
|
|
387
|
-
// The runner owns the git seam it hands its phases (same as `gitSync` to
|
|
388
|
-
// `pushStoryBranch`). The review needs it to resolve `origin/<base>` —
|
|
389
|
-
// the ref base-sync merged from — before it will score anything
|
|
390
|
-
// (Story #5325).
|
|
391
331
|
gitSpawnFn: gitSpawn,
|
|
392
332
|
progress,
|
|
393
333
|
});
|
|
394
334
|
if (reviewOutcome.halted) {
|
|
395
335
|
const criticalCount = reviewOutcome.severity?.critical ?? 0;
|
|
396
|
-
//
|
|
397
|
-
// transition so an overridden run never touches `agent::blocked`: the
|
|
398
|
-
// Story is proceeding, and parking it would make the label lie for the
|
|
399
|
-
// rest of the close.
|
|
336
|
+
// Checked before the blocked transition: an overridden Story proceeds.
|
|
400
337
|
if (overrideReviewBlock) {
|
|
401
338
|
const override = await handleOverriddenReviewBlock({
|
|
402
339
|
provider,
|
|
@@ -456,30 +393,12 @@ async function releaseLease({
|
|
|
456
393
|
}
|
|
457
394
|
|
|
458
395
|
/**
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
* The two recoverable-blocked close exits (base-sync conflict in
|
|
463
|
-
* `runBaseSyncPhase`, and a critical-blocker review halt in
|
|
464
|
-
* `openAndReviewPr`) throw before the clean-close lease release at the
|
|
465
|
-
* tail of `runSingleStoryClose`, stranding the operator's lease
|
|
466
|
-
* indefinitely. The standalone lease has **no** TTL to expire by (Story
|
|
467
|
-
* #5006 deleted it): `acquireLease` refuses any foreign assignee outright,
|
|
468
|
-
* so a stranded claim is cleared only by `--steal` or de-assignment. That fail-closed-refuses a different operator who picks up
|
|
469
|
-
* the blocked Story — exactly the hand-off case. Releasing here closes
|
|
470
|
-
* that gap.
|
|
471
|
-
*
|
|
472
|
-
* The original throw is preserved verbatim (per
|
|
473
|
-
* `rules/orchestration-error-handling.md` — throw, never `Logger.fatal`),
|
|
474
|
-
* so the CLI boundary still maps it to a non-zero exit; the lease release
|
|
475
|
-
* must not swallow it. `releaseLease` is itself best-effort and never
|
|
476
|
-
* throws, so it cannot mask the real failure. Fail-closed re-acquire
|
|
477
|
-
* semantics are preserved: `releaseStoryLease` no-ops when the operator no
|
|
478
|
-
* longer holds the claim, and a self-held re-acquire on a re-run still
|
|
479
|
-
* succeeds against the now-unclaimed ticket.
|
|
396
|
+
* Release the lease best-effort before re-throwing a blocked-prone phase's
|
|
397
|
+
* error verbatim. The lease has no TTL, so a stranded claim would refuse the
|
|
398
|
+
* next operator who picks up the blocked Story.
|
|
480
399
|
*
|
|
481
400
|
* @template T
|
|
482
|
-
* @param {() => Promise<T>} run
|
|
401
|
+
* @param {() => Promise<T>} run
|
|
483
402
|
* @param {{ provider: object, storyId: number, config: object, injectedReleaseLease?: Function }} leaseArgs
|
|
484
403
|
* @returns {Promise<T>}
|
|
485
404
|
*/
|
|
@@ -493,25 +412,8 @@ async function releaseLeaseOnBlock(run, leaseArgs) {
|
|
|
493
412
|
}
|
|
494
413
|
|
|
495
414
|
/**
|
|
496
|
-
* Did this run OBSERVE the
|
|
497
|
-
*
|
|
498
|
-
* `merged` used to be whatever the caller happened to pass, and the two
|
|
499
|
-
* finishers passed different halves of the truth. Three observations say a
|
|
500
|
-
* merge happened, and each of them reported `merged: false` on at least one
|
|
501
|
-
* path:
|
|
502
|
-
*
|
|
503
|
-
* - the confirm phase watched it land (`waitOutcome.confirmed`);
|
|
504
|
-
* - it landed and only the `agent::done` label write failed
|
|
505
|
-
* (`merged-flip-failed`) — the terminal envelope for that same run
|
|
506
|
-
* already reports `pr.state: MERGED` from the probe, so a result denying
|
|
507
|
-
* the merge made the two halves of one run contradict each other;
|
|
508
|
-
* - the arm phase direct-squash-merged it synchronously because the
|
|
509
|
-
* repository has no native auto-merge (`directMerged`), which the
|
|
510
|
-
* no-wait finisher never consulted at all.
|
|
511
|
-
*
|
|
512
|
-
* Deliberately observation-only: it reads what the run saw, never what the
|
|
513
|
-
* run intended. A `null`/absent `waitOutcome` is the no-wait finisher, whose
|
|
514
|
-
* sole observation is the direct merge.
|
|
415
|
+
* Did this run OBSERVE the merge — confirmed, merged-but-flip-failed, or
|
|
416
|
+
* direct-merged? Observation only, never intent.
|
|
515
417
|
*
|
|
516
418
|
* @param {{ waitOutcome?: object|null, directMerged?: boolean }} args
|
|
517
419
|
* @returns {boolean}
|
|
@@ -552,25 +454,13 @@ function closeResult({
|
|
|
552
454
|
autoMergeReason,
|
|
553
455
|
worktreeReaped,
|
|
554
456
|
leaseReleased,
|
|
555
|
-
//
|
|
556
|
-
// merge/arm stood. Surfaced so the land is auditable as
|
|
557
|
-
// merged-with-deferred-cleanup rather than silently degraded.
|
|
457
|
+
// `gh`'s local branch delete failed while the remote merge/arm stood.
|
|
558
458
|
localCleanupDeferred,
|
|
559
|
-
//
|
|
560
|
-
// an already-clean PR), so the PR was landed by a direct squash-merge.
|
|
561
|
-
// Surfaced so a checks-less land is auditable rather than looking like a
|
|
562
|
-
// queued auto-merge that never fired.
|
|
459
|
+
// No native auto-merge, so the arm squash-merged directly.
|
|
563
460
|
directMerged,
|
|
564
461
|
waitedForMerge,
|
|
565
462
|
merged,
|
|
566
|
-
//
|
|
567
|
-
// never from `waitedForMerge`. A wait that expired unmerged used to write
|
|
568
|
-
// "PR merge confirmed" beside `merged: false`, and this log is what the
|
|
569
|
-
// operator reads first. See close-note.js for the invariant.
|
|
570
|
-
// Story #5279 — `landCompleted` keeps that invariant intact now that
|
|
571
|
-
// `merged: true` no longer implies the flip and the tail ran: a direct
|
|
572
|
-
// merge under `--no-wait-merge`, and a `merged-flip-failed` block, are
|
|
573
|
-
// both merged WITHOUT a completed land.
|
|
463
|
+
// Never from `waitedForMerge`; `merged` can be true without a completed land.
|
|
574
464
|
note: deriveCloseNote({
|
|
575
465
|
merged,
|
|
576
466
|
directMerged,
|
|
@@ -621,18 +511,10 @@ export async function runSingleStoryClose({
|
|
|
621
511
|
);
|
|
622
512
|
}
|
|
623
513
|
|
|
624
|
-
//
|
|
625
|
-
//
|
|
626
|
-
//
|
|
627
|
-
// the error with the phase it died in, and the CLI boundary turns that into
|
|
628
|
-
// the `failed` terminal envelope. Tagging rather than swallowing is what
|
|
629
|
-
// lets `failed` name its phase without inventing a second success path.
|
|
514
|
+
// The runner keeps THROWING; it only tags the error with its phase and the
|
|
515
|
+
// gates it observed (null until validation reports), and the CLI boundary
|
|
516
|
+
// builds the `failed` envelope from those tags.
|
|
630
517
|
let phase = 'init';
|
|
631
|
-
// Story #5279 — the per-gate outcomes this run OBSERVED, tagged onto a
|
|
632
|
-
// throwing error alongside the phase so `failedTerminalFor` reports gates
|
|
633
|
-
// instead of reconstructing which ones "must have" run. Stays null until
|
|
634
|
-
// close-validation reports, so a run that died before it claims no gates at
|
|
635
|
-
// all rather than inventing names for gates that were never registered.
|
|
636
518
|
let observedGates = null;
|
|
637
519
|
const setPhase = (next) => {
|
|
638
520
|
phase = next;
|
|
@@ -665,10 +547,7 @@ export async function runSingleStoryClose({
|
|
|
665
547
|
}
|
|
666
548
|
|
|
667
549
|
/**
|
|
668
|
-
*
|
|
669
|
-
* to arm — `gh pr merge` against it fails, which would report the arm as a
|
|
670
|
-
* fault and block a Story whose work is already on the base branch. Skip the
|
|
671
|
-
* arm and let the confirm phase observe the merge that happened.
|
|
550
|
+
* An already-merged PR skips the arm (`gh pr merge` would fail and block it).
|
|
672
551
|
*
|
|
673
552
|
* @param {object} args
|
|
674
553
|
* @returns {Promise<{ autoMergeEnabled: boolean, autoMergeReason: string|null,
|
|
@@ -688,10 +567,6 @@ async function resolveAutoMergeOutcome({ alreadyMerged, ...phaseArgs }) {
|
|
|
688
567
|
}
|
|
689
568
|
|
|
690
569
|
/**
|
|
691
|
-
* Report the merge-wait terminal on the progress channel. Three endings, each
|
|
692
|
-
* with its own operator-facing shape — `landed` is done, `pending` is
|
|
693
|
-
* resumable and NOT a failure, anything else is a block naming its class.
|
|
694
|
-
*
|
|
695
570
|
* @param {{ status: string, nextCommand: string, blocked?: {blockClass?: string} }} terminal
|
|
696
571
|
* @param {{ storyId: number, prUrl: string|null }} ctx
|
|
697
572
|
* @returns {void}
|
|
@@ -702,9 +577,7 @@ function reportWaitTerminal(terminal, { storyId, prUrl }) {
|
|
|
702
577
|
return;
|
|
703
578
|
}
|
|
704
579
|
if (terminal.status === 'pending') {
|
|
705
|
-
//
|
|
706
|
-
// host slot with the PR healthy and in flight. The CLI maps this to
|
|
707
|
-
// its own exit code so a caller can resume without classifying.
|
|
580
|
+
// Not a failure: resumable, with its own CLI exit code.
|
|
708
581
|
progress(
|
|
709
582
|
'PENDING',
|
|
710
583
|
`⏸ Story #${storyId}: PR ${prUrl} still in flight — resume with: ${terminal.nextCommand}`,
|
|
@@ -720,11 +593,8 @@ function reportWaitTerminal(terminal, { storyId, prUrl }) {
|
|
|
720
593
|
}
|
|
721
594
|
|
|
722
595
|
/**
|
|
723
|
-
*
|
|
724
|
-
*
|
|
725
|
-
*
|
|
726
|
-
* @param {object} prCtx The shared PR/gate context built by the pipeline.
|
|
727
|
-
* @param {object} deps Runtime seams the confirm phase needs.
|
|
596
|
+
* @param {object} prCtx
|
|
597
|
+
* @param {object} deps
|
|
728
598
|
* @returns {Promise<{ success: boolean, result: object, terminal: object }>}
|
|
729
599
|
*/
|
|
730
600
|
async function finishWithMergeWait(prCtx, deps) {
|
|
@@ -757,6 +627,7 @@ async function finishWithMergeWait(prCtx, deps) {
|
|
|
757
627
|
prUrl: prCtx.prUrl,
|
|
758
628
|
autoMergeEnabled: prCtx.autoMergeEnabled,
|
|
759
629
|
gates: prCtx.gates,
|
|
630
|
+
lockWait: prCtx.lockWait,
|
|
760
631
|
elapsedSeconds: elapsedSecondsSince(prCtx.startedAtMs),
|
|
761
632
|
});
|
|
762
633
|
const result = closeResult({
|
|
@@ -768,22 +639,15 @@ async function finishWithMergeWait(prCtx, deps) {
|
|
|
768
639
|
autoMergeEnabled: prCtx.autoMergeEnabled,
|
|
769
640
|
autoMergeReason: prCtx.autoMergeReason,
|
|
770
641
|
worktreeReaped: prCtx.worktreeReaped,
|
|
771
|
-
//
|
|
772
|
-
// own per-step boolean IS the answer. A wait that ended anything other
|
|
773
|
-
// than landed never ran the tail, and correctly reports `false`: the
|
|
774
|
-
// claim is still held, by design.
|
|
642
|
+
// Released by the post-land tail only; any other ending keeps the claim.
|
|
775
643
|
leaseReleased: waitOutcome.tail?.leaseRelease === true,
|
|
776
644
|
localCleanupDeferred: prCtx.localCleanupDeferred,
|
|
777
645
|
directMerged: prCtx.directMerged,
|
|
778
646
|
waitedForMerge: true,
|
|
779
|
-
// Story #5279 — `confirmed` alone denied the merge behind a
|
|
780
|
-
// `merged-flip-failed` block, whose own envelope (above) reports
|
|
781
|
-
// `pr.state: MERGED` off the probe.
|
|
782
647
|
merged: deriveObservedMerge({
|
|
783
648
|
waitOutcome,
|
|
784
649
|
directMerged: prCtx.directMerged,
|
|
785
650
|
}),
|
|
786
|
-
// Only the confirmed ending runs the flip, the issue close and the tail.
|
|
787
651
|
landCompleted: waitOutcome.confirmed === true,
|
|
788
652
|
});
|
|
789
653
|
await emitTerminal({ terminal, result, config: prCtx.config });
|
|
@@ -792,20 +656,14 @@ async function finishWithMergeWait(prCtx, deps) {
|
|
|
792
656
|
}
|
|
793
657
|
|
|
794
658
|
/**
|
|
795
|
-
* The no-wait ending
|
|
796
|
-
*
|
|
797
|
-
* is not done, nothing is broken, and one named command finishes it — rather
|
|
798
|
-
* than a fourth status invented for this one case.
|
|
659
|
+
* The no-wait ending: a human owns the land, so it is `pending` with one
|
|
660
|
+
* command to finish it. A direct merge by the arm is still observed.
|
|
799
661
|
*
|
|
800
662
|
* @param {object} prCtx
|
|
801
663
|
* @param {string} waitForMergeReason
|
|
802
664
|
* @returns {Promise<{ success: boolean, result: object, terminal: object }>}
|
|
803
665
|
*/
|
|
804
666
|
async function finishWithoutMergeWait(prCtx, waitForMergeReason) {
|
|
805
|
-
// Story #5279 — a repository with no native auto-merge is direct
|
|
806
|
-
// squash-merged synchronously by the arm phase, so this ending can and does
|
|
807
|
-
// hold an OBSERVED merge. It used to report `merged: false` and hard-code
|
|
808
|
-
// `pr.state: 'OPEN'` for a PR the same run had just merged.
|
|
809
667
|
const merged = deriveObservedMerge({ directMerged: prCtx.directMerged });
|
|
810
668
|
const result = closeResult({
|
|
811
669
|
storyId: prCtx.storyId,
|
|
@@ -816,15 +674,11 @@ async function finishWithoutMergeWait(prCtx, waitForMergeReason) {
|
|
|
816
674
|
autoMergeEnabled: prCtx.autoMergeEnabled,
|
|
817
675
|
autoMergeReason: prCtx.autoMergeReason,
|
|
818
676
|
worktreeReaped: prCtx.worktreeReaped,
|
|
819
|
-
// Story #4860 — this is the no-wait ending: the PR is open and a human
|
|
820
|
-
// owns the merge, so the Story stays assigned until the confirm-merge
|
|
821
|
-
// surface lands it and runs the tail.
|
|
822
677
|
leaseReleased: false,
|
|
823
678
|
localCleanupDeferred: prCtx.localCleanupDeferred,
|
|
824
679
|
directMerged: prCtx.directMerged,
|
|
825
680
|
merged,
|
|
826
|
-
//
|
|
827
|
-
// closes the issue and never runs the tail — `nextCommand` does.
|
|
681
|
+
// The flip, issue close and tail belong to `nextCommand`.
|
|
828
682
|
landCompleted: false,
|
|
829
683
|
});
|
|
830
684
|
const terminal = buildTerminalEnvelope({
|
|
@@ -840,6 +694,7 @@ async function finishWithoutMergeWait(prCtx, waitForMergeReason) {
|
|
|
840
694
|
autoMergeEnabled: Boolean(prCtx.autoMergeEnabled),
|
|
841
695
|
},
|
|
842
696
|
gates: prCtx.gates,
|
|
697
|
+
lockWait: prCtx.lockWait,
|
|
843
698
|
nextCommand: NEXT_COMMANDS.confirmMerge(prCtx.storyId),
|
|
844
699
|
elapsedSeconds: elapsedSecondsSince(prCtx.startedAtMs),
|
|
845
700
|
});
|
|
@@ -852,9 +707,25 @@ async function finishWithoutMergeWait(prCtx, waitForMergeReason) {
|
|
|
852
707
|
}
|
|
853
708
|
|
|
854
709
|
/**
|
|
855
|
-
*
|
|
856
|
-
* envelope's `elapsedSeconds`.
|
|
710
|
+
* A full-suite lock wait expired: `pending`, nothing pushed.
|
|
857
711
|
*
|
|
712
|
+
* @param {{ waitedSeconds: number, expired: boolean }|null} lockWait
|
|
713
|
+
* @param {{ storyId: number, storyBranch: string, baseBranch: string,
|
|
714
|
+
* config: object, startedAtMs: number }} ctx
|
|
715
|
+
* @returns {Promise<{ success: false, result: object, terminal: object }>}
|
|
716
|
+
*/
|
|
717
|
+
async function finishDeferred(lockWait, { config, startedAtMs, ...ids }) {
|
|
718
|
+
const { result, terminal, note } = lockWaitPending({
|
|
719
|
+
...ids,
|
|
720
|
+
lockWait,
|
|
721
|
+
elapsedSeconds: elapsedSecondsSince(startedAtMs),
|
|
722
|
+
});
|
|
723
|
+
await emitTerminal({ terminal, result, config });
|
|
724
|
+
progress('PENDING', note);
|
|
725
|
+
return { success: false, result, terminal };
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
/**
|
|
858
729
|
* @param {number} startedAtMs
|
|
859
730
|
* @returns {number}
|
|
860
731
|
*/
|
|
@@ -863,10 +734,6 @@ function elapsedSecondsSince(startedAtMs) {
|
|
|
863
734
|
}
|
|
864
735
|
|
|
865
736
|
/**
|
|
866
|
-
* Announce the operator-merge skip: the PR was deliberately left un-armed, so
|
|
867
|
-
* nothing here can land it and the Story rests at `agent::closing`. No-op on
|
|
868
|
-
* every other wait reason.
|
|
869
|
-
*
|
|
870
737
|
* @param {{ waitForMergeReason: string, autoMergeReason: string|null,
|
|
871
738
|
* storyId: number, waitForMergeExplicit?: boolean }} args
|
|
872
739
|
* @returns {void}
|
|
@@ -888,11 +755,6 @@ function reportOperatorMergeSkip({
|
|
|
888
755
|
);
|
|
889
756
|
}
|
|
890
757
|
|
|
891
|
-
/**
|
|
892
|
-
* The close pipeline proper. Split out of `runSingleStoryClose` so the
|
|
893
|
-
* phase-tagging wrapper above stays a thin, obviously-correct boundary rather
|
|
894
|
-
* than a try block wrapped around a hundred lines of pipeline.
|
|
895
|
-
*/
|
|
896
758
|
async function runClosePipeline({
|
|
897
759
|
options,
|
|
898
760
|
setPhase,
|
|
@@ -922,10 +784,6 @@ async function runClosePipeline({
|
|
|
922
784
|
);
|
|
923
785
|
}
|
|
924
786
|
|
|
925
|
-
// Story #4257 — the base-sync conflict and review-critical exits throw
|
|
926
|
-
// before the clean-close lease release at the tail of this function.
|
|
927
|
-
// Built here, ahead of the first blocked-prone step, so the preflight
|
|
928
|
-
// refusal below releases the lease on the same terms those exits do.
|
|
929
787
|
const leaseArgs = {
|
|
930
788
|
provider,
|
|
931
789
|
storyId: options.storyId,
|
|
@@ -933,11 +791,7 @@ async function runClosePipeline({
|
|
|
933
791
|
injectedReleaseLease,
|
|
934
792
|
};
|
|
935
793
|
|
|
936
|
-
//
|
|
937
|
-
// validated, committed or pushed. `gh` routes the whole `gh pr` surface
|
|
938
|
-
// through GraphQL, so a session that cannot reach it cannot land this
|
|
939
|
-
// Story however green its gates are; discovering that here costs one API
|
|
940
|
-
// call instead of the entire close-validation chain plus a push.
|
|
794
|
+
// `gh pr` needs GraphQL; one cheap read here beats the gate chain plus a push.
|
|
941
795
|
const preflight = await runGraphqlPreflight({
|
|
942
796
|
storyId: options.storyId,
|
|
943
797
|
provider,
|
|
@@ -955,13 +809,8 @@ async function runClosePipeline({
|
|
|
955
809
|
});
|
|
956
810
|
}
|
|
957
811
|
|
|
958
|
-
//
|
|
959
|
-
//
|
|
960
|
-
// may have changed during the whole implementation window. Throws (fail
|
|
961
|
-
// closed, naming both values) when the pin and current config disagree —
|
|
962
|
-
// deliberately here, before the gate chain, format-autofix and base-sync,
|
|
963
|
-
// so a wrong base is never merged into the Story branch. `baseConfirmed`
|
|
964
|
-
// gates the base-merge remediation advice further down.
|
|
812
|
+
// The base the run was SEEDED from (init receipt); throws before any merge
|
|
813
|
+
// when it disagrees with current config.
|
|
965
814
|
const { values: runScoped, confirmed: baseConfirmed } =
|
|
966
815
|
await resolveRunScopedConfig({
|
|
967
816
|
storyId: options.storyId,
|
|
@@ -975,9 +824,7 @@ async function runClosePipeline({
|
|
|
975
824
|
config,
|
|
976
825
|
storyId: options.storyId,
|
|
977
826
|
});
|
|
978
|
-
|
|
979
|
-
// best-effort before the throw propagates; the original error is preserved.
|
|
980
|
-
const { validationGates } = await releaseLeaseOnBlock(
|
|
827
|
+
const prePush = await releaseLeaseOnBlock(
|
|
981
828
|
() =>
|
|
982
829
|
runPrePushPhases({
|
|
983
830
|
...options,
|
|
@@ -994,6 +841,15 @@ async function runClosePipeline({
|
|
|
994
841
|
}),
|
|
995
842
|
leaseArgs,
|
|
996
843
|
);
|
|
844
|
+
if (prePush.pending) {
|
|
845
|
+
return await finishDeferred(prePush.lockWait, {
|
|
846
|
+
storyId: options.storyId,
|
|
847
|
+
storyBranch,
|
|
848
|
+
baseBranch,
|
|
849
|
+
config,
|
|
850
|
+
startedAtMs,
|
|
851
|
+
});
|
|
852
|
+
}
|
|
997
853
|
|
|
998
854
|
const { prUrl, prNumber, alreadyMerged, reviewOverride } =
|
|
999
855
|
await releaseLeaseOnBlock(
|
|
@@ -1014,16 +870,9 @@ async function runClosePipeline({
|
|
|
1014
870
|
}),
|
|
1015
871
|
leaseArgs,
|
|
1016
872
|
);
|
|
1017
|
-
// Reap the
|
|
1018
|
-
//
|
|
1019
|
-
//
|
|
1020
|
-
// `git` to drop `story-<id>`. A live worktree still holding that ref makes
|
|
1021
|
-
// the local delete fail, `gh` exit non-zero, and the arm read as failed,
|
|
1022
|
-
// which used to strand a genuinely merged PR at `agent::blocked`.
|
|
1023
|
-
// Pre-empting the hold is the ordering half of the fix (the tolerate half
|
|
1024
|
-
// lives in `phases/auto-merge.js`); it is safe here because push and PR
|
|
1025
|
-
// creation already made the work durable off-machine, and `isSafeToRemove`
|
|
1026
|
-
// still refuses a dirty tree.
|
|
873
|
+
// Reap BEFORE the arm: `gh pr merge --delete-branch` may merge at once and
|
|
874
|
+
// then fail deleting a branch a live worktree holds, reading as a failed
|
|
875
|
+
// arm. Safe — the work is pushed, and a dirty tree is still refused.
|
|
1027
876
|
const worktreeReaped = await reapWorktreePhase({
|
|
1028
877
|
cwd: options.cwd,
|
|
1029
878
|
storyId: options.storyId,
|
|
@@ -1047,7 +896,6 @@ async function runClosePipeline({
|
|
|
1047
896
|
prUrl,
|
|
1048
897
|
noAutoMerge: options.noAutoMerge,
|
|
1049
898
|
autoMergePolicy: ciDelivery.autoMerge,
|
|
1050
|
-
// Story #5096 — the pre-arm advisory-gate refusal.
|
|
1051
899
|
blockOnAdvisoryFailure: ciDelivery.blockOnAdvisoryFailure,
|
|
1052
900
|
advisoryAllowlist: ciDelivery.advisoryAllowlist,
|
|
1053
901
|
gh: injectedGh,
|
|
@@ -1064,30 +912,11 @@ async function runClosePipeline({
|
|
|
1064
912
|
config,
|
|
1065
913
|
progress,
|
|
1066
914
|
});
|
|
1067
|
-
//
|
|
1068
|
-
//
|
|
1069
|
-
// claim the moment the PR opened, so a ticket read unassigned for the whole
|
|
1070
|
-
// time its PR was in flight — and forever on the operator-merge path, where
|
|
1071
|
-
// nothing downstream ever re-claimed it. The release now belongs to the
|
|
1072
|
-
// post-land tail, which runs only on a CONFIRMED merge and which both
|
|
1073
|
-
// landing surfaces reach. Every non-merged ending below — the
|
|
1074
|
-
// `merge.unlanded` block, an exhausted wait budget, `--no-wait-merge`,
|
|
1075
|
-
// `--no-auto-merge` — deliberately RETAINS the claim: the PR is open and the
|
|
1076
|
-
// work still has an owner. The only releases that survive here are
|
|
1077
|
-
// `releaseLeaseOnBlock`'s two throwing exits above, which fire before the PR
|
|
1078
|
-
// is ever armed (Story #4257's hand-off property).
|
|
915
|
+
// No lease release here: only the post-land tail (confirmed merge) releases
|
|
916
|
+
// it; every non-merged ending keeps the claim while the PR is open.
|
|
1079
917
|
|
|
1080
|
-
//
|
|
1081
|
-
//
|
|
1082
|
-
// explicitly with `merge.unlanded`, instead of resting at `agent::closing`.
|
|
1083
|
-
// This is the DEFAULT path for attended and headless runs alike.
|
|
1084
|
-
//
|
|
1085
|
-
// Resolved here rather than at parse time because two inputs do not exist
|
|
1086
|
-
// until now: the resolved config (whose cwd the parse produces) and the
|
|
1087
|
-
// actual arm outcome. A PR the operator deliberately left un-armed
|
|
1088
|
-
// (`--no-auto-merge` / `autoMerge: "strict"`) has nothing to land, so it
|
|
1089
|
-
// rests at `agent::closing` for the human instead of burning the poll
|
|
1090
|
-
// budget and then blocking a healthy Story.
|
|
918
|
+
// Resolved now, not at parse time: it needs the config and the arm outcome
|
|
919
|
+
// (an un-armed PR rests at `agent::closing` rather than waiting).
|
|
1091
920
|
const { waitForMerge, reason: waitForMergeReason } = resolveWaitForMerge({
|
|
1092
921
|
waitForMergeExplicit: options.waitForMergeExplicit,
|
|
1093
922
|
noWaitForMerge: options.noWaitForMerge,
|
|
@@ -1114,17 +943,8 @@ async function runClosePipeline({
|
|
|
1114
943
|
directMerged,
|
|
1115
944
|
config,
|
|
1116
945
|
startedAtMs,
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
// Story #5172 — the split baselines entries, named individually so a
|
|
1120
|
-
// reader can tell the two apart. Absent when validation was skipped.
|
|
1121
|
-
...baselinesEnvelopeGates(validationGates),
|
|
1122
|
-
baseSync: options.skipSync ? 'skipped' : 'passed',
|
|
1123
|
-
// An overridden blocker reports `overridden`, never
|
|
1124
|
-
// `passed`. The review DID fail; a human authorized shipping anyway, and
|
|
1125
|
-
// the envelope is the machine-readable trail that says so.
|
|
1126
|
-
codeReview: reviewOverride ? 'overridden' : 'passed',
|
|
1127
|
-
},
|
|
946
|
+
lockWait: prePush.lockWait,
|
|
947
|
+
gates: closeEnvelopeGates(options, prePush.validationGates, reviewOverride),
|
|
1128
948
|
};
|
|
1129
949
|
|
|
1130
950
|
if (waitForMerge) {
|