mandrel 2.60.0 → 2.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/README.md +10 -10
- package/.agents/agents/story-worker.md +1 -1
- package/.agents/docs/agentrc-reference.json +4 -82
- package/.agents/docs/configuration.md +20 -87
- package/.agents/docs/workflows.md +1 -1
- package/.agents/instructions.md +1 -3
- package/.agents/rules/gherkin-standards.md +4 -0
- package/.agents/schemas/agentrc.schema.json +11 -486
- package/.agents/schemas/story-deliver-terminal.schema.json +10 -0
- package/.agents/schemas/validation-evidence.schema.json +2 -1
- package/.agents/scripts/README.md +14 -14
- package/.agents/scripts/acceptance-eval.js +32 -164
- package/.agents/scripts/agents-bootstrap-github.js +27 -129
- package/.agents/scripts/apply-quality-bootstrap.js +4 -40
- package/.agents/scripts/audit-baselines.js +6 -27
- package/.agents/scripts/audit-labels-bootstrap.js +5 -29
- package/.agents/scripts/audit-to-stories.js +91 -361
- package/.agents/scripts/boot-sweep.js +19 -72
- package/.agents/scripts/bootstrap.js +74 -395
- package/.agents/scripts/ceremony-derive.js +9 -45
- package/.agents/scripts/check-arch-cycles.js +14 -64
- package/.agents/scripts/check-baselines.js +8 -48
- package/.agents/scripts/check-context-budget.js +46 -172
- package/.agents/scripts/check-cyclomatic.js +12 -44
- package/.agents/scripts/check-dead-exports.js +13 -64
- package/.agents/scripts/check-doc-links.js +38 -186
- package/.agents/scripts/check-gherkin-corpus.js +24 -127
- package/.agents/scripts/check-test-temp-hygiene.js +28 -169
- package/.agents/scripts/coverage-capture.js +32 -99
- package/.agents/scripts/deliver-light.js +14 -101
- package/.agents/scripts/deliver-recover.js +6 -42
- package/.agents/scripts/deliver-run.js +36 -133
- package/.agents/scripts/diagnose-friction.js +24 -116
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +23 -85
- package/.agents/scripts/file-ci-gap.js +10 -50
- package/.agents/scripts/generate-config-docs.js +30 -170
- package/.agents/scripts/generate-lens-checklists.js +8 -52
- package/.agents/scripts/generate-skills-index.js +14 -112
- package/.agents/scripts/generate-workflows-doc.js +10 -70
- package/.agents/scripts/git-cleanup.js +2 -34
- package/.agents/scripts/lib/Graph.js +24 -81
- package/.agents/scripts/lib/ITicketingProvider.js +47 -143
- package/.agents/scripts/lib/Logger.js +14 -76
- package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
- package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
- package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
- package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
- package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
- package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
- package/.agents/scripts/lib/audit-baselines/read.js +3 -16
- package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
- package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
- package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
- package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
- package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
- package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
- package/.agents/scripts/lib/audit-suite/findings.js +12 -52
- package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
- package/.agents/scripts/lib/audit-suite/index.js +1 -15
- package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
- package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
- package/.agents/scripts/lib/audit-suite/runner.js +13 -43
- package/.agents/scripts/lib/audit-suite/selector.js +49 -349
- package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
- package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
- package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
- package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
- package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
- package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
- package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
- package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
- package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
- package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
- package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
- package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
- package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
- package/.agents/scripts/lib/baseline-loader.js +12 -51
- package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
- package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
- package/.agents/scripts/lib/baselines/components.js +10 -61
- package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
- package/.agents/scripts/lib/baselines/crap-preview-incremental.js +5 -21
- package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
- package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
- package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
- package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
- package/.agents/scripts/lib/baselines/envelope.js +13 -129
- package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
- package/.agents/scripts/lib/baselines/git-base.js +23 -142
- package/.agents/scripts/lib/baselines/kernel.js +11 -111
- package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
- package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
- package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
- package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
- package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
- package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
- package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
- package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
- package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
- package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
- package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
- package/.agents/scripts/lib/baselines/path-canon.js +19 -128
- package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
- package/.agents/scripts/lib/baselines/reader.js +14 -107
- package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
- package/.agents/scripts/lib/baselines/scope.js +11 -135
- package/.agents/scripts/lib/baselines/writer.js +16 -149
- package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
- package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
- package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
- package/.agents/scripts/lib/bdd-step-index.js +26 -100
- package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
- package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
- package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
- package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
- package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
- package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
- package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
- package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
- package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
- package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
- package/.agents/scripts/lib/bootstrap/summary.js +1 -8
- package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
- package/.agents/scripts/lib/branch-name-guard.js +4 -23
- package/.agents/scripts/lib/changed-files.js +31 -143
- package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
- package/.agents/scripts/lib/checks/index.js +18 -101
- package/.agents/scripts/lib/checks/loop-health.js +11 -53
- package/.agents/scripts/lib/checks/state.js +16 -91
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
- package/.agents/scripts/lib/child-exec.js +39 -108
- package/.agents/scripts/lib/cli/standard-args.js +9 -116
- package/.agents/scripts/lib/cli-args.js +31 -146
- package/.agents/scripts/lib/cli-usage.js +5 -27
- package/.agents/scripts/lib/cli-utils.js +2 -12
- package/.agents/scripts/lib/close-validation/commands.js +13 -76
- package/.agents/scripts/lib/close-validation/gates.js +92 -331
- package/.agents/scripts/lib/close-validation/process.js +121 -151
- package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
- package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
- package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
- package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
- package/.agents/scripts/lib/close-validation/runner.js +53 -110
- package/.agents/scripts/lib/command-header.js +6 -28
- package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
- package/.agents/scripts/lib/config/baselines.js +3 -14
- package/.agents/scripts/lib/config/ci.js +8 -38
- package/.agents/scripts/lib/config/commands.js +1 -15
- package/.agents/scripts/lib/config/defaults.js +4 -33
- package/.agents/scripts/lib/config/delivery-routing.js +6 -35
- package/.agents/scripts/lib/config/explain.js +9 -80
- package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +2 -30
- package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
- package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
- package/.agents/scripts/lib/config/gates/index.js +2 -17
- package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
- package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
- package/.agents/scripts/lib/config/gates/shared.js +4 -64
- package/.agents/scripts/lib/config/github.js +4 -22
- package/.agents/scripts/lib/config/limits.js +4 -57
- package/.agents/scripts/lib/config/paths.js +2 -21
- package/.agents/scripts/lib/config/qa.js +4 -38
- package/.agents/scripts/lib/config/quality.js +76 -432
- package/.agents/scripts/lib/config/runners.js +12 -56
- package/.agents/scripts/lib/config/runtime.js +13 -57
- package/.agents/scripts/lib/config/shared.js +2 -16
- package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
- package/.agents/scripts/lib/config/temp-paths.js +40 -280
- package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
- package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
- package/.agents/scripts/lib/config-resolver.js +10 -52
- package/.agents/scripts/lib/config-schema-shared.js +1 -4
- package/.agents/scripts/lib/config-settings-schema-delivery.js +12 -294
- package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
- package/.agents/scripts/lib/config-settings-schema.js +37 -274
- package/.agents/scripts/lib/coverage-baseline.js +20 -110
- package/.agents/scripts/lib/coverage-capture-fullscope.js +12 -37
- package/.agents/scripts/lib/coverage-capture-incremental.js +12 -43
- package/.agents/scripts/lib/coverage-capture-usage.js +4 -24
- package/.agents/scripts/lib/coverage-capture.js +99 -224
- package/.agents/scripts/lib/coverage-utils.js +14 -79
- package/.agents/scripts/lib/cpu-pool.js +17 -123
- package/.agents/scripts/lib/crap-baseline-join.js +16 -88
- package/.agents/scripts/lib/crap-coordinates.js +6 -25
- package/.agents/scripts/lib/crap-engine.js +40 -153
- package/.agents/scripts/lib/crap-method-identity.js +16 -78
- package/.agents/scripts/lib/crap-utils.js +31 -155
- package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
- package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
- package/.agents/scripts/lib/dead-exports-knip.js +18 -56
- package/.agents/scripts/lib/dead-exports-mode.js +5 -24
- package/.agents/scripts/lib/degraded-mode.js +3 -26
- package/.agents/scripts/lib/dependency-parser.js +8 -40
- package/.agents/scripts/lib/dependency-version.js +13 -35
- package/.agents/scripts/lib/detect-package-manager.js +6 -36
- package/.agents/scripts/lib/doc-tiers.js +22 -126
- package/.agents/scripts/lib/duplicate-search.js +8 -72
- package/.agents/scripts/lib/env-loader.js +5 -27
- package/.agents/scripts/lib/error-redactor.js +6 -31
- package/.agents/scripts/lib/errors/index.js +2 -22
- package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
- package/.agents/scripts/lib/escomplex-kernel.js +21 -123
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +93 -419
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -151
- package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
- package/.agents/scripts/lib/findings/classify-finding.js +14 -69
- package/.agents/scripts/lib/findings/promote-finding.js +14 -112
- package/.agents/scripts/lib/findings/provenance-field.js +11 -52
- package/.agents/scripts/lib/findings/route-finding.js +37 -255
- package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
- package/.agents/scripts/lib/findings/severity.js +18 -104
- package/.agents/scripts/lib/format-generated-json.js +12 -44
- package/.agents/scripts/lib/full-suite-lock.js +160 -429
- package/.agents/scripts/lib/full-suite-queue.js +213 -0
- package/.agents/scripts/lib/gates/baseline-store.js +5 -9
- package/.agents/scripts/lib/gates/friction.js +1 -3
- package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
- package/.agents/scripts/lib/gh-exec.js +31 -259
- package/.agents/scripts/lib/git/cached-fetch.js +9 -52
- package/.agents/scripts/lib/git/sync-from-base.js +15 -107
- package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
- package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
- package/.agents/scripts/lib/git-utils.js +37 -161
- package/.agents/scripts/lib/github/framework-repo.js +8 -71
- package/.agents/scripts/lib/github-url.js +2 -17
- package/.agents/scripts/lib/import-graph.js +11 -38
- package/.agents/scripts/lib/install-cmd-parser.js +4 -13
- package/.agents/scripts/lib/json-utils.js +3 -18
- package/.agents/scripts/lib/label-constants.js +16 -111
- package/.agents/scripts/lib/label-taxonomy.js +4 -30
- package/.agents/scripts/lib/maintainability-engine.js +12 -80
- package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
- package/.agents/scripts/lib/maintainability-utils.js +16 -92
- package/.agents/scripts/lib/mandrel-catalog.js +12 -70
- package/.agents/scripts/lib/notifications/notifier.js +13 -38
- package/.agents/scripts/lib/npm-scripts.js +4 -23
- package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
- package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
- package/.agents/scripts/lib/observability/signal-validator.js +5 -37
- package/.agents/scripts/lib/observability/signals-writer.js +11 -121
- package/.agents/scripts/lib/observability/source-classifier.js +21 -203
- package/.agents/scripts/lib/observability/terse-result.js +14 -47
- package/.agents/scripts/lib/onboard/init-tail.js +13 -74
- package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
- package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
- package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +5 -75
- package/.agents/scripts/lib/orchestration/change-set.js +7 -36
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
- package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
- package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
- package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
- package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
- package/.agents/scripts/lib/orchestration/check-state.js +92 -0
- package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +42 -189
- package/.agents/scripts/lib/orchestration/code-review.js +24 -128
- package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
- package/.agents/scripts/lib/orchestration/complexity-gate.js +42 -214
- package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
- package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
- package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
- package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
- package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
- package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
- package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
- package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
- package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
- package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
- package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
- package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
- package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
- package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
- package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
- package/.agents/scripts/lib/orchestration/light-suitability.js +26 -231
- package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
- package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
- package/.agents/scripts/lib/orchestration/plan-context.js +52 -303
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
- package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
- package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
- package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
- package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
- package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +14 -78
- package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
- package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
- package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
- package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +49 -248
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
- package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
- package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
- package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
- package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
- package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
- package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
- package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
- package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
- package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
- package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
- package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
- package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
- package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
- package/.agents/scripts/lib/orchestration/review-depth.js +12 -94
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
- package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
- package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
- package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
- package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
- package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
- package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
- package/.agents/scripts/lib/orchestration/run-epilogue.js +40 -199
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
- package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
- package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
- package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +18 -80
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +136 -486
- package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
- package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +9 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +110 -290
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
- package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
- package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
- package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
- package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -201
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
- package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
- package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
- package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
- package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -126
- package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
- package/.agents/scripts/lib/orchestration/ticket-validator.js +39 -181
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
- package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
- package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
- package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
- package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
- package/.agents/scripts/lib/path-security.js +3 -6
- package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
- package/.agents/scripts/lib/preflight-runner.js +13 -69
- package/.agents/scripts/lib/process-group.js +143 -0
- package/.agents/scripts/lib/project-root.js +2 -8
- package/.agents/scripts/lib/provider-factory.js +2 -25
- package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
- package/.agents/scripts/lib/qa/qa-session.js +15 -69
- package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
- package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
- package/.agents/scripts/lib/reserved-test-ids.js +9 -47
- package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
- package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
- package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
- package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
- package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
- package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
- package/.agents/scripts/lib/signals/detectors/common.js +12 -38
- package/.agents/scripts/lib/signals/index.js +2 -19
- package/.agents/scripts/lib/signals/schema.js +14 -109
- package/.agents/scripts/lib/signals/write.js +2 -11
- package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
- package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
- package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
- package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
- package/.agents/scripts/lib/single-story-sweep.js +14 -97
- package/.agents/scripts/lib/skills/parse-skill.js +13 -59
- package/.agents/scripts/lib/skills/skills-index.js +8 -29
- package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
- package/.agents/scripts/lib/source-extensions.js +11 -42
- package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
- package/.agents/scripts/lib/stdio-flush.js +9 -36
- package/.agents/scripts/lib/story-adjacency.js +8 -40
- package/.agents/scripts/lib/story-body/body-format-lints.js +22 -83
- package/.agents/scripts/lib/story-body/footer-block.js +11 -44
- package/.agents/scripts/lib/story-body/story-body.js +83 -358
- package/.agents/scripts/lib/temp-retention.js +42 -143
- package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
- package/.agents/scripts/lib/test-env.js +12 -65
- package/.agents/scripts/lib/test-run-credit.js +10 -65
- package/.agents/scripts/lib/test-runner-contract.js +19 -74
- package/.agents/scripts/lib/test-temp.js +38 -184
- package/.agents/scripts/lib/test-tiers.js +12 -96
- package/.agents/scripts/lib/ticket-body-sections.js +21 -96
- package/.agents/scripts/lib/transpile.js +15 -74
- package/.agents/scripts/lib/util/concurrent-map.js +6 -25
- package/.agents/scripts/lib/util/parse-id-list.js +8 -34
- package/.agents/scripts/lib/util/poll-loop.js +8 -28
- package/.agents/scripts/lib/util/with-timeout.js +2 -11
- package/.agents/scripts/lib/validation-evidence.js +21 -96
- package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
- package/.agents/scripts/lib/wave-runner/live-probe.js +53 -221
- package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
- package/.agents/scripts/lib/workers/crap-worker.js +11 -64
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
- package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
- package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
- package/.agents/scripts/lib/workflow-closure.js +22 -105
- package/.agents/scripts/lib/workspace-provisioner.js +16 -54
- package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
- package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
- package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
- package/.agents/scripts/lib/worktree-manager.js +15 -40
- package/.agents/scripts/lint-issue-body.js +12 -68
- package/.agents/scripts/mandrel-update-preflight.js +10 -70
- package/.agents/scripts/merge-baseline.js +30 -104
- package/.agents/scripts/nav-registry-diff.js +22 -108
- package/.agents/scripts/notify.js +12 -69
- package/.agents/scripts/plan-context.js +27 -111
- package/.agents/scripts/plan-critics.js +12 -66
- package/.agents/scripts/plan-persist.js +31 -148
- package/.agents/scripts/plan-run-epilogue.js +11 -37
- package/.agents/scripts/pr-watch-with-update.js +76 -267
- package/.agents/scripts/providers/github/auth.js +3 -8
- package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
- package/.agents/scripts/providers/github/board-add.js +5 -21
- package/.agents/scripts/providers/github/branch-protection.js +11 -43
- package/.agents/scripts/providers/github/cache.js +2 -14
- package/.agents/scripts/providers/github/comments.js +7 -40
- package/.agents/scripts/providers/github/compose.js +3 -19
- package/.agents/scripts/providers/github/errors.js +22 -125
- package/.agents/scripts/providers/github/issues.js +31 -123
- package/.agents/scripts/providers/github/labels.js +24 -124
- package/.agents/scripts/providers/github/mappers.js +5 -27
- package/.agents/scripts/providers/github/merge-methods.js +3 -22
- package/.agents/scripts/providers/github/project-board.js +2 -17
- package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
- package/.agents/scripts/providers/github/request-helpers.js +5 -32
- package/.agents/scripts/providers/github/search-budget.js +9 -39
- package/.agents/scripts/providers/github/search-query.js +5 -26
- package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
- package/.agents/scripts/providers/github/sub-issues.js +7 -36
- package/.agents/scripts/providers/github/tickets.js +32 -134
- package/.agents/scripts/providers/github.js +18 -59
- package/.agents/scripts/prune-plan-run-labels.js +12 -46
- package/.agents/scripts/quality-preview.js +35 -220
- package/.agents/scripts/resolve-doc-tiers.js +3 -26
- package/.agents/scripts/resolve-stories.js +16 -67
- package/.agents/scripts/resync-status-column.js +6 -25
- package/.agents/scripts/run-tests.js +29 -104
- package/.agents/scripts/single-story-close.js +23 -135
- package/.agents/scripts/single-story-confirm-merge.js +32 -139
- package/.agents/scripts/single-story-init.js +47 -209
- package/.agents/scripts/stories-wave-tick.js +102 -472
- package/.agents/scripts/sync-agentrc.js +3 -21
- package/.agents/scripts/sync-claude-agents.js +9 -55
- package/.agents/scripts/sync-claude-commands.js +20 -110
- package/.agents/scripts/test-wrapper.js +6 -43
- package/.agents/scripts/update-coverage-baseline.js +5 -22
- package/.agents/scripts/update-crap-baseline.js +7 -30
- package/.agents/scripts/update-duplication-baseline.js +16 -92
- package/.agents/scripts/update-maintainability-baseline.js +8 -62
- package/.agents/scripts/update-ticket-state.js +1 -7
- package/.agents/scripts/validate-skills.js +6 -26
- package/.agents/templates/agent-protocol.md +2 -2
- package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
- package/.agents/workflows/audit-accessibility.md +4 -7
- package/.agents/workflows/audit-adrs.md +3 -6
- package/.agents/workflows/audit-architecture.md +3 -11
- package/.agents/workflows/audit-baselines.md +6 -9
- package/.agents/workflows/audit-clean-code.md +8 -12
- package/.agents/workflows/audit-data-model.md +3 -7
- package/.agents/workflows/audit-dependencies.md +4 -7
- package/.agents/workflows/audit-devops.md +4 -8
- package/.agents/workflows/audit-documentation.md +1 -4
- package/.agents/workflows/audit-mobile.md +4 -7
- package/.agents/workflows/audit-navigability.md +3 -6
- package/.agents/workflows/audit-performance.md +2 -4
- package/.agents/workflows/audit-privacy.md +4 -7
- package/.agents/workflows/audit-quality.md +4 -7
- package/.agents/workflows/audit-security.md +4 -7
- package/.agents/workflows/audit-seo.md +4 -7
- package/.agents/workflows/audit-sre.md +4 -7
- package/.agents/workflows/audit-to-stories.md +17 -30
- package/.agents/workflows/audit-ux-ui.md +4 -7
- package/.agents/workflows/helpers/audit-lens-core.md +1 -1
- package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
- package/.agents/workflows/helpers/deliver-digest.md +6 -4
- package/.agents/workflows/helpers/deliver-reference.md +114 -188
- package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
- package/.agents/workflows/helpers/plan-reference.md +86 -139
- package/.agents/workflows/helpers/qa-core.md +12 -0
- package/.agents/workflows/memory-consolidate.md +1 -1
- package/.agents/workflows/qa-assist.md +27 -71
- package/.agents/workflows/qa-explore.md +19 -59
- package/.agents/workflows/qa-run.md +11 -33
- package/README.md +1 -1
- package/bin/mandrel.js +5 -46
- package/bin/postinstall.js +18 -107
- package/docs/CHANGELOG.md +25 -0
- package/lib/cli/doctor.js +11 -71
- package/lib/cli/init.js +26 -165
- package/lib/cli/migrate.js +5 -64
- package/lib/cli/registry.js +84 -467
- package/lib/cli/sync-agents.js +4 -64
- package/lib/cli/sync-commands.js +11 -64
- package/lib/cli/sync.js +34 -213
- package/lib/cli/uninstall.js +40 -219
- package/lib/cli/update.js +105 -661
- package/lib/cli/version-check.js +8 -72
- package/lib/cli/version-helpers.js +14 -87
- package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
- package/lib/migrations/index.js +15 -92
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
- package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
- package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
- package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
- package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
- package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
- package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
- package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +2 -21
- package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
- package/package.json +16 -14
- package/.agents/docs/SDLC.md +0 -590
- package/.agents/docs/quality-gates.md +0 -1183
- package/.agents/rules/known-tooling-behavior.md +0 -200
- package/.agents/rules/orchestration-error-handling.md +0 -61
- package/.agents/rules/test-seams.md +0 -59
- package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
- package/.agents/schemas/baselines/lint.schema.json +0 -47
- package/.agents/scripts/check-action-pinning.js +0 -260
- package/.agents/scripts/check-audit-attribution.js +0 -302
- package/.agents/scripts/check-baseline-drift.js +0 -211
- package/.agents/scripts/check-baseline-scope.js +0 -362
- package/.agents/scripts/check-generated-validator.js +0 -202
- package/.agents/scripts/check-knip-entries.js +0 -159
- package/.agents/scripts/check-lifecycle-lint.js +0 -294
- package/.agents/scripts/check-pinned-override-notes.js +0 -102
- package/.agents/scripts/check-schema-references.js +0 -368
- package/.agents/scripts/check-test-portability.js +0 -512
- package/.agents/scripts/check-workflow-citations.js +0 -218
- package/.agents/scripts/check-workflow-cli-lint.js +0 -299
- package/.agents/scripts/check-workflow-timeouts.js +0 -291
- package/.agents/scripts/install-matrix-assert.js +0 -326
- package/.agents/scripts/lib/audit-advisories.js +0 -195
- package/.agents/scripts/lib/audit-attribution.js +0 -134
- package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
- package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
- package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
- package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
- package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
- package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
- package/.agents/scripts/lib/c8-cli-path.js +0 -21
- package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
- package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
- package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
- package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
- package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
- package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
- package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
- package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
- package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
- package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
- package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
- package/.agents/scripts/lib/fs-walk.js +0 -52
- package/.agents/scripts/lib/knip-config-resolver.js +0 -181
- package/.agents/scripts/lib/knip-entry-sync.js +0 -452
- package/.agents/scripts/lib/pinned-override-notes.js +0 -88
- package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
- package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
- package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
- package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
- package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
- package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
- package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
- package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
- package/.agents/scripts/lib/test-isolate/runner.js +0 -483
- package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
- package/.agents/scripts/lib/test-profile/render-report.js +0 -45
- package/.agents/scripts/lint-label-vocabulary.js +0 -214
- package/.agents/scripts/post-structured-comment.js +0 -127
- package/.agents/scripts/provision-git-hooks.js +0 -85
- package/.agents/scripts/prune-baseline-orphans.js +0 -181
- package/.agents/scripts/run-coverage.js +0 -197
- package/.agents/scripts/run-lint.js +0 -133
- package/.agents/scripts/run-test-profile.js +0 -129
- package/.agents/scripts/run-verify.js +0 -125
- package/.agents/scripts/test-isolate.js +0 -55
- package/.agents/scripts/update-dead-exports-baseline.js +0 -321
|
@@ -1,85 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* phases/auto-merge.js —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* on any failure so the caller can fall back to the operator-merges-button
|
|
7
|
-
* path.
|
|
8
|
-
*
|
|
9
|
-
* Story #2990 routed the underlying `gh pr merge` call through the
|
|
10
|
-
* `lib/gh-exec.js` facade (the same shim the `providers/github/`
|
|
11
|
-
* gateways use). The `runner` seam is preserved so existing tests can
|
|
12
|
-
* inject a synchronous fake; the default runner delegates to
|
|
13
|
-
* `gh.pr.merge`, which spawns through the classified, typed-error
|
|
14
|
-
* surface instead of a raw `execFileSync('gh', …)` call.
|
|
15
|
-
*
|
|
16
|
-
* Story #4282 made arming robust when the base branch is checked out by a
|
|
17
|
-
* git worktree. The `--delete-branch` flag makes `gh` shell out to local
|
|
18
|
-
* `git` (including a `git checkout <base>`); from a per-Story worktree cwd
|
|
19
|
-
* that collides with the base branch already checked out by the primary
|
|
20
|
-
* worktree (`fatal: '<base>' is already used by worktree`). We now resolve
|
|
21
|
-
* the arm cwd to the **primary worktree root** (which holds the base
|
|
22
|
-
* branch) via `resolveAutoMergeArmCwd`, so `gh`'s local checkout is a
|
|
23
|
-
* no-op. `--delete-branch` is preserved verbatim, so the PR head branch is
|
|
24
|
-
* still deleted on merge without depending on the repo's auto-delete
|
|
25
|
-
* setting. Resolution is non-fatal — it degrades to the original cwd.
|
|
26
|
-
*
|
|
27
|
-
* Story #4681 made the arm survive a LOCAL-ONLY cleanup failure. Against an
|
|
28
|
-
* already-mergeable PR, `gh pr merge --auto --squash --delete-branch` merges
|
|
29
|
-
* immediately and then shells out to local `git` to drop the head branch.
|
|
30
|
-
* When the per-Story worktree still holds `story-<id>`, that local delete
|
|
31
|
-
* fails (`Cannot delete branch 'story-<id>' used by worktree at …`) and `gh`
|
|
32
|
-
* exits non-zero — even though the REMOTE merge already landed. Reporting
|
|
33
|
-
* that as an arm failure sent close's confirm phase straight to
|
|
34
|
-
* `blockOnUnlanded`, flipping a merged Story to a stale `agent::blocked` that
|
|
35
|
-
* only a hand-run `single-story-confirm-merge.js` could undo. The failure is
|
|
36
|
-
* now classified: a local-cleanup-only signature reports the arm as ENABLED
|
|
37
|
-
* with `localCleanupDeferred: true`, so the confirm phase polls the PR
|
|
38
|
-
* (observes MERGED) and the post-land tail reaps the local ref. Every other
|
|
39
|
-
* non-zero exit — a genuinely refused REMOTE merge — keeps the pre-existing
|
|
40
|
-
* `enabled: false` → blocked behaviour verbatim.
|
|
41
|
-
*
|
|
42
|
-
* Story #4682 restored the direct-merge fallback the v2.0.0 Story-only cutover
|
|
43
|
-
* dropped (originally PR #4480 / Story #4472, in the retired `AutomergeArmer`).
|
|
44
|
-
* GitHub native auto-merge (`gh pr merge --auto`) can only be QUEUED on a repo
|
|
45
|
-
* that has the "Allow auto-merge" setting enabled — which in practice requires
|
|
46
|
-
* branch protection. A repo with NO required checks and NO branch protection
|
|
47
|
-
* (every mandrel-bench sandbox, many real consumer repos) refuses the `--auto`
|
|
48
|
-
* arm: either "auto-merge is not allowed for this repository", or — once the
|
|
49
|
-
* PR has settled to an immediately-mergeable state, which the SECOND delivery
|
|
50
|
-
* into a warm repo reaches faster than the first into a cold one — the
|
|
51
|
-
* `enablePullRequestAutoMerge` "Pull request is in clean status" refusal. The
|
|
52
|
-
* close gates and Story-scope review have already cleared the merge by the
|
|
53
|
-
* time the arm runs, so the safe, must-land-satisfying response is a direct
|
|
54
|
-
* immediate squash-merge (no `--auto`). When the `--auto` failure matches the
|
|
55
|
-
* narrow {@link isAutoMergeUnavailable} signature, `enableAutoMergeWith`
|
|
56
|
-
* retries `gh pr merge --squash --delete-branch` and reports
|
|
57
|
-
* `{ enabled: true, directMerged: true }` on success — so the confirm phase
|
|
58
|
-
* polls the PR, observes MERGED, and lands it instead of blocking a PR that
|
|
59
|
-
* would never merge on its own. Every OTHER `--auto` failure — a genuine
|
|
60
|
-
* conflict, a red required check, an auth fault — matches neither the
|
|
61
|
-
* local-cleanup nor the unavailable signature and keeps blocking verbatim.
|
|
2
|
+
* phases/auto-merge.js — arm GitHub native auto-merge (squash, delete branch).
|
|
3
|
+
* Non-fatal: a failure returns `{ enabled: false, reason }`. The arm runs from
|
|
4
|
+
* the primary worktree so `--delete-branch`'s local `git checkout <base>`
|
|
5
|
+
* cannot collide with a worktree holding the base.
|
|
62
6
|
*/
|
|
63
7
|
|
|
64
|
-
import { gh as defaultGh } from '../../../gh-exec.js';
|
|
8
|
+
import { gh as defaultGh, describeGhFailure } from '../../../gh-exec.js';
|
|
65
9
|
import { resolveAutoMergeArmCwd } from '../../auto-merge-cwd.js';
|
|
66
10
|
import {
|
|
67
|
-
|
|
11
|
+
decideAdvisoryGateBlock,
|
|
68
12
|
deriveRedHeadRuns,
|
|
69
|
-
resolveAdvisoryGateVerdict,
|
|
70
|
-
selectBlockingRedRuns,
|
|
71
13
|
} from '../../merge-poll.js';
|
|
72
14
|
|
|
73
15
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* The distinction is load-bearing: an un-armed-by-request PR has nothing for
|
|
78
|
-
* close to land, so `resolveWaitForMerge` (`./options.js`) resolves
|
|
79
|
-
* `waitForMerge` to `false` for these reasons and the Story rests at
|
|
80
|
-
* `agent::closing` for the human. Every *other* falsy arm outcome
|
|
81
|
-
* (`pr-number-unparseable`, an `enableAutoMerge` failure) is a genuine fault
|
|
82
|
-
* and still routes through the merge-unlanded block path.
|
|
16
|
+
* The operator deliberately owns the merge, so close does not wait for it;
|
|
17
|
+
* every other falsy arm outcome is a genuine fault.
|
|
83
18
|
*/
|
|
84
19
|
const OPERATOR_MERGE_ARM_REASONS = Object.freeze([
|
|
85
20
|
'disabled-by-flag',
|
|
@@ -95,34 +30,16 @@ export function isOperatorMergeReason(reason) {
|
|
|
95
30
|
}
|
|
96
31
|
|
|
97
32
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* names branch DELETION specifically:
|
|
104
|
-
* - `Cannot delete branch '<name>' used by worktree at …` — `git branch -D`
|
|
105
|
-
* refusing a ref another worktree has checked out (the Story #4681 report).
|
|
106
|
-
* - `failed to delete local branch …` — `gh`'s own wrapper wording.
|
|
107
|
-
*
|
|
108
|
-
* Deliberately narrow on two fronts. A genuinely refused REMOTE merge ("Pull
|
|
109
|
-
* request is not mergeable", a required status check, branch protection)
|
|
110
|
-
* matches neither pattern and keeps the existing blocked path. Nor does the
|
|
111
|
-
* bare `fatal: '<base>' is already used by worktree` checkout collision Story
|
|
112
|
-
* #4282 defends against: that one aborts `gh` *before* the branch delete and
|
|
113
|
-
* carries no evidence the merge stands, so it must keep failing the arm.
|
|
33
|
+
* A `gh pr merge --delete-branch` failure whose only casualty is the LOCAL
|
|
34
|
+
* head-branch delete after the remote merge/arm already happened. Deliberately
|
|
35
|
+
* narrow: a refused remote merge, and the `'<base>' is already used by
|
|
36
|
+
* worktree` checkout collision (which aborts before the merge), must still
|
|
37
|
+
* fail the arm.
|
|
114
38
|
*/
|
|
115
39
|
const LOCAL_CLEANUP_FAILURE =
|
|
116
40
|
/cannot delete branch[^\n]*used by worktree|failed to delete (?:the )?local branch/i;
|
|
117
41
|
|
|
118
42
|
/**
|
|
119
|
-
* Whether a non-zero `gh pr merge` exit is attributable solely to local
|
|
120
|
-
* branch cleanup, leaving the remote merge/arm itself intact.
|
|
121
|
-
*
|
|
122
|
-
* Module-private on purpose: `enableAutoMergeWith` is the only caller and the
|
|
123
|
-
* only surface worth pinning, so the classification is asserted through it
|
|
124
|
-
* rather than through a test-only export.
|
|
125
|
-
*
|
|
126
43
|
* @param {string|undefined|null} stderr
|
|
127
44
|
* @returns {boolean}
|
|
128
45
|
*/
|
|
@@ -131,33 +48,10 @@ function isLocalCleanupOnlyFailure(stderr) {
|
|
|
131
48
|
}
|
|
132
49
|
|
|
133
50
|
/**
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
* Two distinct refusals both mean "there is no queued auto-merge for this repo,
|
|
139
|
-
* merge it directly instead", and both are safe to retry as an immediate
|
|
140
|
-
* squash-merge:
|
|
141
|
-
*
|
|
142
|
-
* - **"auto-merge is not allowed for this repository"** — the repo has no
|
|
143
|
-
* "Allow auto-merge" setting (no branch protection). Constant per repo.
|
|
144
|
-
* - **"Pull request is in clean status"** — the `enablePullRequestAutoMerge`
|
|
145
|
-
* GraphQL mutation refuses to queue a merge on a PR that is ALREADY
|
|
146
|
-
* immediately mergeable with nothing to wait for (no required checks
|
|
147
|
-
* pending). This is the second-delivery wedge (Story #4682): the first
|
|
148
|
-
* delivery into a cold sandbox arms while GitHub is still computing the
|
|
149
|
-
* fresh PR's mergeability (the arm queues, then merges); the second
|
|
150
|
-
* delivery into the now-warm repo hits an instantly-clean PR, so the arm
|
|
151
|
-
* is refused here.
|
|
152
|
-
*
|
|
153
|
-
* Only these classes fall through to the direct-merge fallback; everything
|
|
154
|
-
* else (an unmatched non-zero exit) keeps the `enabled: false` → blocked path.
|
|
155
|
-
* Matched case-insensitively.
|
|
156
|
-
*
|
|
157
|
-
* Module-private on purpose (mirroring {@link isLocalCleanupOnlyFailure}):
|
|
158
|
-
* `enableAutoMergeWith` is the only caller, so the marker set is asserted
|
|
159
|
-
* through it rather than through a test-only export the production dead-export
|
|
160
|
-
* ratchet would then flag.
|
|
51
|
+
* Whether `--auto` was refused because native auto-merge is unavailable —
|
|
52
|
+
* the repo disallows it, or the PR is already clean with nothing to queue
|
|
53
|
+
* behind (`enablePullRequestAutoMerge` "clean status"). Both are safe to
|
|
54
|
+
* retry as a direct squash-merge; any other failure keeps blocking.
|
|
161
55
|
*
|
|
162
56
|
* @param {string|undefined|null} stderr
|
|
163
57
|
* @returns {boolean}
|
|
@@ -174,18 +68,8 @@ function isAutoMergeUnavailable(stderr) {
|
|
|
174
68
|
}
|
|
175
69
|
|
|
176
70
|
/**
|
|
177
|
-
* Direct (non-`--auto`) squash-merge
|
|
178
|
-
*
|
|
179
|
-
* the {@link isAutoMergeUnavailable} signature — a repo with no native
|
|
180
|
-
* auto-merge, or an already-clean PR with nothing to queue behind. Omitting
|
|
181
|
-
* `--auto` makes `gh` merge synchronously; the same `--squash --delete-branch`
|
|
182
|
-
* shape and the same `armCwd` re-point are preserved so the trailing local
|
|
183
|
-
* `--delete-branch` housekeeping runs from the primary worktree (Story #4282).
|
|
184
|
-
*
|
|
185
|
-
* A local-cleanup-only grumble on the direct merge (Story #4681) still means
|
|
186
|
-
* the REMOTE merge landed, so it reports `directMerged` with
|
|
187
|
-
* `localCleanupDeferred`. Any other non-zero exit is a genuine failure the
|
|
188
|
-
* caller escalates.
|
|
71
|
+
* Direct (non-`--auto`) squash-merge, run from the same `armCwd`. A
|
|
72
|
+
* local-cleanup-only failure still means the remote merge landed.
|
|
189
73
|
*
|
|
190
74
|
* @returns {Promise<{ enabled: boolean, directMerged?: boolean, localCleanupDeferred?: boolean, reason?: string }>}
|
|
191
75
|
*/
|
|
@@ -231,9 +115,6 @@ export async function enableAutoMergeWith({
|
|
|
231
115
|
resolveArmCwd = resolveAutoMergeArmCwd,
|
|
232
116
|
}) {
|
|
233
117
|
const exec = runner ?? makeDefaultGhAutoMergeRunner(gh ?? defaultGh);
|
|
234
|
-
// Re-point the arm at the base-branch (primary) worktree so gh's
|
|
235
|
-
// `--delete-branch` local `git checkout <base>` cannot collide with the
|
|
236
|
-
// base branch already checked out by the primary worktree (Story #4282).
|
|
237
118
|
const armCwd = resolveArmCwd(cwd);
|
|
238
119
|
try {
|
|
239
120
|
const result = await exec(
|
|
@@ -250,15 +131,10 @@ export async function enableAutoMergeWith({
|
|
|
250
131
|
if (result.status === 0) return { enabled: true };
|
|
251
132
|
const detail = `gh-exit-${result.status}: ${(result.stderr ?? '').trim().slice(0, 200)}`;
|
|
252
133
|
if (isLocalCleanupOnlyFailure(result.stderr)) {
|
|
253
|
-
// The remote side stands;
|
|
254
|
-
// Report ENABLED so the confirm phase polls the real PR state instead
|
|
255
|
-
// of blocking a merge that already landed, and flag the deferred
|
|
256
|
-
// cleanup for the land tail's `git branch -D` to finish.
|
|
134
|
+
// The remote side stands; the land tail finishes the local ref reap.
|
|
257
135
|
return { enabled: true, localCleanupDeferred: true, reason: detail };
|
|
258
136
|
}
|
|
259
137
|
if (isAutoMergeUnavailable(result.stderr)) {
|
|
260
|
-
// No native auto-merge on this repo (or nothing to queue behind an
|
|
261
|
-
// already-clean PR): merge directly so the PR still lands (Story #4682).
|
|
262
138
|
return directMergeFallback({
|
|
263
139
|
exec,
|
|
264
140
|
prNumber,
|
|
@@ -273,20 +149,11 @@ export async function enableAutoMergeWith({
|
|
|
273
149
|
}
|
|
274
150
|
|
|
275
151
|
/**
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
* `{ status, stdout, stderr }` envelope `enableAutoMergeWith` consumes.
|
|
279
|
-
*
|
|
280
|
-
* The adapter swallows non-zero exits (mapping the typed `GhExecError`
|
|
281
|
-
* carrier back to its `code` + `stderr`) because auto-merge enablement
|
|
282
|
-
* is intentionally non-fatal — the caller treats failures as "operator
|
|
283
|
-
* merges manually".
|
|
152
|
+
* Adapt `gh.pr.merge` into the `{ status, stdout, stderr }` envelope,
|
|
153
|
+
* mapping non-zero exits back to that envelope rather than throwing.
|
|
284
154
|
*/
|
|
285
155
|
function makeDefaultGhAutoMergeRunner(gh) {
|
|
286
156
|
return async function defaultGhAutoMergeRunner(args, _opts) {
|
|
287
|
-
// `args` always starts with `pr merge <prNumber>` — pass everything
|
|
288
|
-
// after the third element to `gh.pr.merge` as flags so the facade
|
|
289
|
-
// owns the `gh pr merge <id> …` argv assembly.
|
|
290
157
|
const [, , prIdStr, ...flags] = args;
|
|
291
158
|
try {
|
|
292
159
|
const result = await gh.pr.merge(prIdStr, flags);
|
|
@@ -296,13 +163,8 @@ function makeDefaultGhAutoMergeRunner(gh) {
|
|
|
296
163
|
stderr: result?.stderr ?? '',
|
|
297
164
|
};
|
|
298
165
|
} catch (err) {
|
|
299
|
-
//
|
|
300
|
-
//
|
|
301
|
-
// `.stderr` is mapped back to the `{ status, stdout, stderr }`
|
|
302
|
-
// envelope `enableAutoMergeWith` consumes. The typed
|
|
303
|
-
// `GhExecError` carriers from `lib/gh-exec.js` already fit this
|
|
304
|
-
// shape; bare `Error`s without a code fall through to the spawn-
|
|
305
|
-
// error reason in the parent catch.
|
|
166
|
+
// Any error with a numeric `.code`/`.status` maps to the envelope;
|
|
167
|
+
// a codeless Error falls through to the caller's spawn-error reason.
|
|
306
168
|
const numericCode =
|
|
307
169
|
typeof err?.code === 'number'
|
|
308
170
|
? err.code
|
|
@@ -328,24 +190,8 @@ function makeDefaultGhAutoMergeRunner(gh) {
|
|
|
328
190
|
}
|
|
329
191
|
|
|
330
192
|
/**
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
* GitHub native auto-merge is defined to wait on REQUIRED contexts only, so a
|
|
334
|
-
* red ADVISORY quality gate — a coverage, mutation, duplication, a11y or
|
|
335
|
-
* bundle-size ratchet a consumer deliberately left non-required — is merged
|
|
336
|
-
* straight past once the required contexts go green. The arming decision is
|
|
337
|
-
* mandrel's, not GitHub's, so this is where it has to be made.
|
|
338
|
-
*
|
|
339
|
-
* Reads the SAME head-anchored derivation the merge wait uses
|
|
340
|
-
* (`readPrWaitProbe` → `deriveRedHeadRuns`), so a `CANCELLED` superseded-push
|
|
341
|
-
* run or a sibling-invalidated run is never mistaken for a red gate (the
|
|
342
|
-
* #4695 / #4710 trap), and `mergeStateStatus: UNSTABLE` supplies the
|
|
343
|
-
* required-vs-advisory discrimination the rollup itself lacks.
|
|
344
|
-
*
|
|
345
|
-
* **Non-fatal and fail-open in every degraded case.** A probe error, an absent
|
|
346
|
-
* or `UNKNOWN` merge state, or a disabled knob all return "do not block" — the
|
|
347
|
-
* arm proceeds exactly as it did before this Story. Only a positive verdict
|
|
348
|
-
* refuses.
|
|
193
|
+
* Native auto-merge waits on REQUIRED contexts only, so mandrel must refuse
|
|
194
|
+
* to arm over a red advisory gate itself.
|
|
349
195
|
*
|
|
350
196
|
* @param {object} args
|
|
351
197
|
* @returns {Promise<{ blocked: boolean, blockingRuns?: Array<object>, reason?: string }>}
|
|
@@ -365,38 +211,61 @@ async function readAdvisoryProbe({ prNumber, gh }) {
|
|
|
365
211
|
}
|
|
366
212
|
|
|
367
213
|
/**
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
* Best-effort by contract: the caller blocks the Story either way, and a
|
|
377
|
-
* failed disarm is reported rather than thrown, because the one thing it
|
|
378
|
-
* cannot do is stop GitHub from landing the PR.
|
|
214
|
+
* A `gh` refusal meaning auto-merge was never armed — the PR is already in the
|
|
215
|
+
* desired un-armed posture, unlike a genuine disarm failure.
|
|
216
|
+
*/
|
|
217
|
+
const NOT_ARMED = /not enabled|isn't enabled|is not set|no auto-?merge/i;
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Lives here because `lifecycle-lint` confines `gh pr merge` to this module.
|
|
221
|
+
* Never throws.
|
|
379
222
|
*
|
|
380
|
-
* @
|
|
223
|
+
* @param {{ prNumber?: number|string, prRef?: string, gh?: object,
|
|
224
|
+
* progress?: (tag: string, msg: string) => void }} args `prRef` wins over
|
|
225
|
+
* `prNumber` when both are given.
|
|
226
|
+
* @returns {Promise<{ disarmed: boolean, alreadyUnarmed: boolean, detail: string }>}
|
|
381
227
|
*/
|
|
382
|
-
export async function disarmAutoMerge({ prNumber, gh, progress }) {
|
|
228
|
+
export async function disarmAutoMerge({ prNumber, prRef, gh, progress }) {
|
|
229
|
+
const ref = String(prRef ?? prNumber);
|
|
383
230
|
try {
|
|
384
|
-
await (gh ?? defaultGh).pr.merge(
|
|
231
|
+
await (gh ?? defaultGh).pr.merge(ref, ['--disable-auto']);
|
|
385
232
|
progress?.(
|
|
386
233
|
'CONFIRM',
|
|
387
|
-
`🔓 Auto-merge DISARMED on PR #${
|
|
234
|
+
`🔓 Auto-merge DISARMED on PR #${ref} — the PR stays open and hand-mergeable.`,
|
|
388
235
|
);
|
|
389
|
-
return true;
|
|
236
|
+
return { disarmed: true, alreadyUnarmed: false, detail: 'disarmed' };
|
|
390
237
|
} catch (err) {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
'GitHub may still land it when the required checks pass. Disarm by hand.',
|
|
395
|
-
);
|
|
396
|
-
return false;
|
|
238
|
+
const outcome = classifyDisarmFailure(describeGhFailure(err));
|
|
239
|
+
warnIfStillArmed({ outcome, ref, progress });
|
|
240
|
+
return outcome;
|
|
397
241
|
}
|
|
398
242
|
}
|
|
399
243
|
|
|
244
|
+
/**
|
|
245
|
+
* @param {string} detail The operator-legible `gh` failure line.
|
|
246
|
+
* @returns {{ disarmed: boolean, alreadyUnarmed: boolean, detail: string }}
|
|
247
|
+
*/
|
|
248
|
+
function classifyDisarmFailure(detail) {
|
|
249
|
+
const alreadyUnarmed = NOT_ARMED.test(detail);
|
|
250
|
+
return {
|
|
251
|
+
disarmed: alreadyUnarmed,
|
|
252
|
+
alreadyUnarmed,
|
|
253
|
+
detail: alreadyUnarmed
|
|
254
|
+
? `auto-merge was not armed: ${detail.slice(0, 160)}`
|
|
255
|
+
: detail.slice(0, 200),
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function warnIfStillArmed({ outcome, ref, progress }) {
|
|
260
|
+
if (outcome.disarmed) return;
|
|
261
|
+
progress?.(
|
|
262
|
+
'CONFIRM',
|
|
263
|
+
`⚠️ Could not disarm auto-merge on PR #${ref} (${outcome.detail}) — ` +
|
|
264
|
+
'GitHub may still land it when the required checks pass. Disarm by hand.',
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/** Fail-open: a probe error or disabled knob never blocks the arm. */
|
|
400
269
|
async function evaluateAdvisoryGate({
|
|
401
270
|
prNumber,
|
|
402
271
|
gh,
|
|
@@ -423,31 +292,23 @@ async function evaluateAdvisoryGate({
|
|
|
423
292
|
);
|
|
424
293
|
return { blocked: false };
|
|
425
294
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
probe.redHeadRuns,
|
|
295
|
+
// Same evaluator as the merge wait's mid-wait gate, so the verdicts cannot drift.
|
|
296
|
+
const verdict = decideAdvisoryGateBlock({
|
|
297
|
+
probe,
|
|
298
|
+
blockOnAdvisoryFailure,
|
|
431
299
|
advisoryAllowlist,
|
|
432
|
-
);
|
|
433
|
-
|
|
434
|
-
// classifies on the text the ROLLUP carried (a legacy StatusContext's
|
|
435
|
-
// `description`); the merge wait, which owns the common case, additionally
|
|
436
|
-
// reads the check-run output. Either way a run whose failure cannot be read
|
|
437
|
-
// as "never finished" keeps the `advisory-gate-red` verdict.
|
|
438
|
-
const verdict = resolveAdvisoryGateVerdict({ blockingRuns });
|
|
300
|
+
});
|
|
301
|
+
if (!verdict) return { blocked: false };
|
|
439
302
|
return {
|
|
440
303
|
blocked: true,
|
|
441
|
-
blockingRuns,
|
|
304
|
+
blockingRuns: verdict.blockingRuns,
|
|
442
305
|
blockClass: verdict.blockClass,
|
|
443
306
|
reason: verdict.reason,
|
|
444
307
|
};
|
|
445
308
|
}
|
|
446
309
|
|
|
447
310
|
/**
|
|
448
|
-
* Dispatch auto-merge enablement
|
|
449
|
-
* unparseable PR number, or a `gh` failure. Returns the structured
|
|
450
|
-
* `{ autoMergeEnabled, autoMergeReason }` pair the result envelope needs.
|
|
311
|
+
* Dispatch auto-merge enablement.
|
|
451
312
|
*
|
|
452
313
|
* @param {{
|
|
453
314
|
* cwd: string,
|
|
@@ -459,10 +320,8 @@ async function evaluateAdvisoryGate({
|
|
|
459
320
|
* progress: (tag: string, msg: string) => void,
|
|
460
321
|
* }} args
|
|
461
322
|
* @returns {Promise<{ autoMergeEnabled: boolean, autoMergeReason: string|null, localCleanupDeferred?: boolean, directMerged?: boolean }>}
|
|
462
|
-
* `localCleanupDeferred
|
|
463
|
-
*
|
|
464
|
-
* `directMerged` is true when native auto-merge was unavailable and the PR
|
|
465
|
-
* was landed by a direct squash-merge instead (Story #4682).
|
|
323
|
+
* `localCleanupDeferred`: the arm stands but the land tail owns the local
|
|
324
|
+
* ref reap. `directMerged`: landed by direct squash-merge instead.
|
|
466
325
|
*/
|
|
467
326
|
export async function runAutoMergePhase({
|
|
468
327
|
cwd,
|
|
@@ -480,13 +339,6 @@ export async function runAutoMergePhase({
|
|
|
480
339
|
progress('PR', '⏭ Auto-merge disabled (--no-auto-merge).');
|
|
481
340
|
return { autoMergeEnabled: false, autoMergeReason: 'disabled-by-flag' };
|
|
482
341
|
}
|
|
483
|
-
// `delivery.ci.autoMerge: "strict"` opts standalone Stories out of
|
|
484
|
-
// auto-merge (parallel to the Epic path's strict predicate): the PR opens
|
|
485
|
-
// and waits for an operator merge instead of arming native auto-merge.
|
|
486
|
-
// The default `"trust-ci"` keeps arming on green required CI — GitHub's
|
|
487
|
-
// native `--auto` is the required-check gate, so no client-side predicate
|
|
488
|
-
// is needed here (unlike the Epic path, which gates on local
|
|
489
|
-
// audit/review/retro signals a standalone Story does not produce).
|
|
490
342
|
if (autoMergePolicy === 'strict') {
|
|
491
343
|
progress(
|
|
492
344
|
'PR',
|
|
@@ -507,10 +359,8 @@ export async function runAutoMergePhase({
|
|
|
507
359
|
autoMergeReason: 'pr-number-unparseable',
|
|
508
360
|
};
|
|
509
361
|
}
|
|
510
|
-
//
|
|
511
|
-
//
|
|
512
|
-
// (a re-close, or a gate carried over from an earlier push); the merge
|
|
513
|
-
// wait owns the common case, where the gate reddens after arming.
|
|
362
|
+
// Covers a gate ALREADY red at close time; the merge wait owns one that
|
|
363
|
+
// reddens after arming.
|
|
514
364
|
const advisory = await evaluateAdvisoryGate({
|
|
515
365
|
prNumber,
|
|
516
366
|
gh,
|
|
@@ -537,10 +387,6 @@ export async function runAutoMergePhase({
|
|
|
537
387
|
const result = await enableAutoMergeWith({ cwd, prNumber, gh });
|
|
538
388
|
if (result.enabled) {
|
|
539
389
|
if (result.directMerged) {
|
|
540
|
-
// No native auto-merge on this repo — the PR was merged directly
|
|
541
|
-
// instead of queued (Story #4682). The confirm phase polls the PR,
|
|
542
|
-
// observes MERGED, and runs the land tail; `localCleanupDeferred`
|
|
543
|
-
// still defers a local-ref reap when gh's `--delete-branch` grumbled.
|
|
544
390
|
progress(
|
|
545
391
|
'PR',
|
|
546
392
|
`✅ Native auto-merge unavailable on PR #${prNumber} — direct squash-merge landed it` +
|
|
@@ -556,8 +402,6 @@ export async function runAutoMergePhase({
|
|
|
556
402
|
};
|
|
557
403
|
}
|
|
558
404
|
if (result.localCleanupDeferred) {
|
|
559
|
-
// Warning, never a block (Story #4681): the merge/arm stands and the
|
|
560
|
-
// land tail reaps the local ref once the worktree releases it.
|
|
561
405
|
progress(
|
|
562
406
|
'PR',
|
|
563
407
|
`⚠️ Auto-merge armed on PR #${prNumber}, but gh's LOCAL branch cleanup failed ` +
|
|
@@ -1,25 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* phases/base-sync.js —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* Defends against the parallel-`/single-story-deliver` race where one
|
|
7
|
-
* Story's auto-merge bumps `main` while sibling Stories are mid-flight —
|
|
8
|
-
* without the sync, the lagging PRs open "behind base" and stall against
|
|
9
|
-
* the `up-to-date branch` protection rule.
|
|
10
|
-
*
|
|
11
|
-
* The sync runs INSIDE the worktree (where the Story branch is checked
|
|
12
|
-
* out); falls back to the main checkout when the worktree is absent.
|
|
13
|
-
* On a merge conflict the Story is transitioned to `agent::blocked` via
|
|
14
|
-
* `handleSyncFailure` and the caller throws — the operator resolves in
|
|
15
|
-
* the worktree and re-runs.
|
|
16
|
-
*
|
|
17
|
-
* Story #5267: a sync that lands tracked content also spends the worker's
|
|
18
|
-
* pre-push credit, because that credit is keyed on the tree. The phase says
|
|
19
|
-
* so out loud — see `buildStampInvalidatedWarning` — instead of leaving
|
|
20
|
-
* close's second full suite looking like a bug. Story #5278 splits the claim
|
|
21
|
-
* in two: gate evidence is spent by any tracked path, the capture stamp only
|
|
22
|
-
* by one under `crap.targetDirs`.
|
|
2
|
+
* phases/base-sync.js — sync the Story branch from `origin/<baseBranch>`
|
|
3
|
+
* before push, so a PR does not open behind a base a sibling's merge just
|
|
4
|
+
* moved. Runs in the worktree (else the main checkout); a failure blocks the
|
|
5
|
+
* Story and throws.
|
|
23
6
|
*/
|
|
24
7
|
|
|
25
8
|
import { getQuality } from '../../../config/quality.js';
|
|
@@ -35,11 +18,7 @@ import {
|
|
|
35
18
|
} from '../../ticketing.js';
|
|
36
19
|
|
|
37
20
|
/**
|
|
38
|
-
*
|
|
39
|
-
* inside the worktree (or main checkout when no worktree exists). On
|
|
40
|
-
* failure, post a friction comment, flip the Story to `agent::blocked`,
|
|
41
|
-
* and throw so the caller fails non-zero. The `--skip-sync` flag is
|
|
42
|
-
* handled by the caller; this function assumes the sync is desired.
|
|
21
|
+
* `--skip-sync` is the caller's concern.
|
|
43
22
|
*
|
|
44
23
|
* @param {{
|
|
45
24
|
* cwd: string,
|
|
@@ -109,10 +88,7 @@ export async function runBaseSyncPhase({
|
|
|
109
88
|
}
|
|
110
89
|
|
|
111
90
|
/**
|
|
112
|
-
* The CRAP scoring scope, or `[]` when
|
|
113
|
-
* the warning below fall back to naming the capture stamp unconditionally —
|
|
114
|
-
* the pre-#5278 wording — because an unresolvable scope is no evidence that
|
|
115
|
-
* the stamp survived.
|
|
91
|
+
* The CRAP scoring scope, or `[]` when unresolvable.
|
|
116
92
|
*
|
|
117
93
|
* @param {typeof resolveConfig} resolveConfigImpl
|
|
118
94
|
* @param {string} cwd
|
|
@@ -126,37 +102,13 @@ function resolveCrapTargetDirs(resolveConfigImpl, cwd) {
|
|
|
126
102
|
}
|
|
127
103
|
}
|
|
128
104
|
|
|
129
|
-
/**
|
|
130
|
-
* How many changed paths the warning names before it stops listing.
|
|
131
|
-
* Enough to recognise the change set; short enough that the warning still
|
|
132
|
-
* reads as a warning rather than as a diff.
|
|
133
|
-
*/
|
|
134
105
|
const WARNED_PATH_LIMIT = 12;
|
|
135
106
|
|
|
136
107
|
/**
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* on the tree (lint, typecheck) and one full-suite capture stamp keyed on the
|
|
142
|
-
* content of `crap.targetDirs`. This sync runs after that, and the two are
|
|
143
|
-
* spent on different conditions — which is why #5267's single blanket
|
|
144
|
-
* sentence was wrong half the time:
|
|
145
|
-
*
|
|
146
|
-
* - **Gate evidence** is spent by any tracked path at all, because the tree
|
|
147
|
-
* hash it is keyed on moves with the first byte.
|
|
148
|
-
* - **The capture stamp** is spent only when a merged path lands under
|
|
149
|
-
* `crap.targetDirs`. A sync that brings in docs, workflows or CI config
|
|
150
|
-
* leaves it perfectly valid, and announcing it as spent taught operators
|
|
151
|
-
* to expect a second full suite that close was never going to run.
|
|
152
|
-
*
|
|
153
|
-
* Quiet by construction on the outcome that cannot spend either: a
|
|
154
|
-
* `noop-already-current` sync never touched the tree. A content-changing
|
|
155
|
-
* fast-forward DOES warn — it moves the tree exactly as a merge commit does,
|
|
156
|
-
* and staying quiet there would be a lie of omission.
|
|
157
|
-
*
|
|
158
|
-
* Pure. Module-private: the phase is the seam tests drive it through
|
|
159
|
-
* (`injectedSync` + a `progress` spy), so it needs no export of its own.
|
|
108
|
+
* Warn that the sync spent pre-push credit, or `[]` when it changed nothing.
|
|
109
|
+
* Gate evidence is keyed on the tree, so any tracked path spends it; the
|
|
110
|
+
* full-suite capture stamp is spent only by a path under `crap.targetDirs`.
|
|
111
|
+
* A content-changing fast-forward warns just as a merge does.
|
|
160
112
|
*
|
|
161
113
|
* @param {{ baseBranch: string, result: { kind?: string, changedPaths?: string[] }, targetDirs?: string[] }} args
|
|
162
114
|
* @returns {string[]} Progress lines, in order. Empty when nothing changed.
|
|
@@ -167,8 +119,7 @@ function buildStampInvalidatedWarning({ baseBranch, result, targetDirs }) {
|
|
|
167
119
|
: [];
|
|
168
120
|
if (changed.length === 0) return [];
|
|
169
121
|
const dirs = Array.isArray(targetDirs) ? targetDirs : [];
|
|
170
|
-
// An unresolvable scope
|
|
171
|
-
// closed to the unconditional wording.
|
|
122
|
+
// An unresolvable scope cannot prove the stamp survived: fail closed.
|
|
172
123
|
const scored =
|
|
173
124
|
dirs.length === 0 ? changed : filterFilesUnderTargets(changed, dirs);
|
|
174
125
|
const shown = changed.slice(0, WARNED_PATH_LIMIT);
|
|
@@ -191,8 +142,7 @@ function buildStampInvalidatedWarning({ baseBranch, result, targetDirs }) {
|
|
|
191
142
|
}
|
|
192
143
|
|
|
193
144
|
/**
|
|
194
|
-
* Post a `friction`
|
|
195
|
-
* and transition the Story to `agent::blocked`. Exported for testing.
|
|
145
|
+
* Post a `friction` comment and block the Story; both best-effort.
|
|
196
146
|
*
|
|
197
147
|
* @param {{
|
|
198
148
|
* provider: object,
|
|
@@ -224,10 +174,8 @@ export async function handleSyncFailure({
|
|
|
224
174
|
result,
|
|
225
175
|
});
|
|
226
176
|
|
|
227
|
-
//
|
|
228
|
-
//
|
|
229
|
-
// we never want a notification-side failure to mask the real reason
|
|
230
|
-
// close threw.
|
|
177
|
+
// Comment first so the recovery surface lands even if the flip fails; a
|
|
178
|
+
// notification failure must never mask why close threw.
|
|
231
179
|
try {
|
|
232
180
|
await upsertStructuredComment(provider, storyId, 'friction', body);
|
|
233
181
|
progress('SYNC', `📝 Posted friction comment on #${storyId}.`);
|
|
@@ -237,9 +185,7 @@ export async function handleSyncFailure({
|
|
|
237
185
|
);
|
|
238
186
|
}
|
|
239
187
|
|
|
240
|
-
//
|
|
241
|
-
// `provider.updateTicket` skips the Projects v2 column sync (Story
|
|
242
|
-
// #2548) and strands the board on the Story's prior status.
|
|
188
|
+
// The canonical mutator: a bare label write skips the Projects v2 sync.
|
|
243
189
|
try {
|
|
244
190
|
await transitionTicketState(provider, storyId, STATE_LABELS.BLOCKED, {});
|
|
245
191
|
progress('SYNC', `🚧 Flipped Story #${storyId} → ${AGENT_LABELS.BLOCKED}.`);
|
|
@@ -251,17 +197,9 @@ export async function handleSyncFailure({
|
|
|
251
197
|
}
|
|
252
198
|
|
|
253
199
|
/**
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
*
|
|
257
|
-
* Story #4891 — `baseConfirmed` gates the merge-the-base recovery block, and
|
|
258
|
-
* defaults to `false` so it fails closed. Telling the operator to run
|
|
259
|
-
* `git merge origin/<baseBranch>` is actively harmful when `<baseBranch>` is
|
|
260
|
-
* not the base the Story was seeded from: it permanently contaminates the
|
|
261
|
-
* branch and its PR diff with an unrelated base. Close confirms the base
|
|
262
|
-
* against the run's init receipt before that advice is emitted; when
|
|
263
|
-
* it could not (receipt absent, unreadable, or unpinned), the operator is
|
|
264
|
-
* told to establish the real base first instead.
|
|
200
|
+
* `baseConfirmed` (default false, fail-closed) gates the merge-the-base
|
|
201
|
+
* advice: merging a base the Story was not seeded from contaminates the
|
|
202
|
+
* branch and PR diff, so an unconfirmed base gets "establish it first".
|
|
265
203
|
*
|
|
266
204
|
* @param {{ storyId: number, storyBranch: string, baseBranch: string, baseConfirmed?: boolean, syncCwd: string, result: { kind: string, conflictFiles?: string[], stderr?: string } }} args
|
|
267
205
|
* @returns {string}
|