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
|
@@ -10,14 +10,9 @@ caller: helpers/deliver-story.md
|
|
|
10
10
|
|
|
11
11
|
# helpers/deliver-story — reference (lease, recovery, troubleshooting)
|
|
12
12
|
|
|
13
|
-
> **Not a slash command, not the runtime path.**
|
|
14
|
-
>
|
|
15
|
-
>
|
|
16
|
-
> carries the step flow, commands, gate contracts, and the return contract a
|
|
17
|
-
> standalone-Story run needs; this file holds the lease/sweep mechanics, the
|
|
18
|
-
> worktree-scope safety warning, the CI-recovery procedures, and the
|
|
19
|
-
> Status-column reconciliation the core points at with one-line pointers.
|
|
20
|
-
> Read a section here only when the matching pointer in the core sends you.
|
|
13
|
+
> **Not a slash command, not the runtime path.** The reference companion to
|
|
14
|
+
> [`deliver-story.md`](deliver-story.md): read a section here only when the
|
|
15
|
+
> matching pointer in the core sends you.
|
|
21
16
|
|
|
22
17
|
---
|
|
23
18
|
|
|
@@ -28,17 +23,12 @@ caller: helpers/deliver-story.md
|
|
|
28
23
|
Before any git mutation, init takes an exclusive, time-bounded **lease** on
|
|
29
24
|
the Story ticket via the assignee-as-lease primitive
|
|
30
25
|
(`lib/orchestration/ticket-lease.js`). The single assignee _is_ the lease
|
|
31
|
-
owner (resolved from `github.operatorHandle`)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
has **no Epic-scoped lifecycle ledger** to read a per-owner
|
|
38
|
-
`story.heartbeat` from, so there is no live-heartbeat source to decide
|
|
39
|
-
whether a foreign claim is stale. Rather than silently reclaim every
|
|
40
|
-
foreign assignee (which would leave the guard inert), the standalone lease
|
|
41
|
-
**fails closed**: a foreign assignee is treated as a _live_ claim. Outcomes:
|
|
26
|
+
owner (resolved from `github.operatorHandle`), and it is the only guard
|
|
27
|
+
against a concurrent `single-story-init` clobbering an in-flight run.
|
|
28
|
+
|
|
29
|
+
**Fail-closed.** The standalone path has **no Epic-scoped lifecycle ledger**
|
|
30
|
+
to read a per-owner `story.heartbeat` from, so it cannot tell whether a
|
|
31
|
+
foreign claim is stale — a foreign assignee is treated as a _live_ claim:
|
|
42
32
|
|
|
43
33
|
- **Unclaimed / self-held** → init proceeds (a self-held claim is
|
|
44
34
|
re-affirmed without re-writing assignees).
|
|
@@ -51,64 +41,39 @@ runs in `single-story-close.js` (Step 3).
|
|
|
51
41
|
|
|
52
42
|
### Branch reuse
|
|
53
43
|
|
|
54
|
-
When a `story-<id>` branch already exists locally, init **reuses** it
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
keys off local + remote ref presence, so re-running init on a
|
|
58
|
-
partially-initialized Story is idempotent.
|
|
44
|
+
When a `story-<id>` branch already exists locally, init **reuses** it. The
|
|
45
|
+
seed decision (`reuse` / `fetch` / `create`) keys off local + remote ref
|
|
46
|
+
presence, so re-running init on a partially-initialized Story is idempotent.
|
|
59
47
|
|
|
60
48
|
### Merged-`story-*` sweep
|
|
61
49
|
|
|
62
|
-
Between the fetch and the branch
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
The sweep
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
`headRefOid`, meaning the operator has commits the merge didn't
|
|
78
|
-
capture.
|
|
79
|
-
- `dirty-tree` — the attached worktree (if any) has uncommitted
|
|
80
|
-
changes.
|
|
81
|
-
- `ticket-not-done` — the parent Story ticket isn't closed and
|
|
82
|
-
doesn't carry `agent::done`.
|
|
83
|
-
Protected candidates are skipped, listed in the sweep result envelope
|
|
84
|
-
under `protected[]`, and named in the `CLEANUP` log line so the
|
|
85
|
-
operator can see what was preserved.
|
|
86
|
-
- **Cross-session lock.** The sweep acquires a process-scoped lockfile
|
|
87
|
-
at `<tempRoot>/single-story-sweep.lock` before planning. On
|
|
88
|
-
contention (another `/deliver-story` already in the sweep
|
|
89
|
-
step), this run's sweep is **skipped** with a warn log; init
|
|
90
|
-
continues normally. Stale lockfiles (mtime older than the timeout)
|
|
91
|
-
are treated as expired. The timeout defaults to 60 seconds and is
|
|
92
|
-
overridable via `delivery.worktreeIsolation.sweepLockMs` in
|
|
93
|
-
`.agentrc.json`.
|
|
94
|
-
|
|
95
|
-
Both layers are non-fatal — sweep failure / skip never blocks init, and
|
|
96
|
-
the new story is always created. `--dry-run` also skips the sweep.
|
|
50
|
+
Between the fetch and the branch seed, init runs the same primitive as
|
|
51
|
+
`<agentRoot>/scripts/git-cleanup.js` scoped to `story-*` in
|
|
52
|
+
`--execute --remote` mode, excluding this run's `story-<id>`, reaping merged
|
|
53
|
+
siblings' local refs, `origin/` refs and stale tracking refs in one pass.
|
|
54
|
+
|
|
55
|
+
- **Per-candidate protection.** A candidate is skipped — listed under
|
|
56
|
+
`protected[]` and named in the `CLEANUP` log line — on `unpushed-work`
|
|
57
|
+
(branch HEAD differs from the PR's `headRefOid`), `dirty-tree` (its
|
|
58
|
+
worktree has uncommitted changes) or `ticket-not-done` (the Story is
|
|
59
|
+
neither closed nor `agent::done`).
|
|
60
|
+
- **Cross-session lock.** The sweep takes `<tempRoot>/single-story-sweep.lock`
|
|
61
|
+
before planning. On contention this run's sweep is **skipped** with a warn
|
|
62
|
+
log; a lockfile older than the fixed 60-second timeout is treated as expired.
|
|
63
|
+
|
|
64
|
+
Sweep failure or skip never blocks init. `--dry-run` also skips the sweep.
|
|
97
65
|
|
|
98
66
|
### Worktree scope is not just the Bash cwd
|
|
99
67
|
|
|
100
68
|
`cd <workCwd>` steers the **Bash** tool's working directory, but it does
|
|
101
69
|
**not** scope the path-based **Edit/Write/Read** tools — those resolve
|
|
102
|
-
**absolute paths** and ignore the shell cwd
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
`friction` comment if it finds uncommitted tracked-path edits in the main
|
|
110
|
-
checkout while the worktree is the active work tree — but that is a backstop,
|
|
111
|
-
not a substitute for prefixing paths correctly.
|
|
70
|
+
**absolute paths** and ignore the shell cwd, so an agent whose shell sits in
|
|
71
|
+
the worktree can still silently edit the **main checkout**. You MUST prefix
|
|
72
|
+
**every Edit/Write/Read path with the absolute worktree root** (the `workCwd`
|
|
73
|
+
value from Step 0). Never edit files under the bare main-checkout root.
|
|
74
|
+
`single-story-close.js` runs a **wrong-tree guard** that aborts close and posts
|
|
75
|
+
a `friction` comment on uncommitted tracked-path edits in the main checkout —
|
|
76
|
+
a backstop, not a substitute for prefixing paths correctly.
|
|
112
77
|
|
|
113
78
|
---
|
|
114
79
|
|
|
@@ -116,45 +81,20 @@ not a substitute for prefixing paths correctly.
|
|
|
116
81
|
|
|
117
82
|
**Prerequisites before Step 0.** A `type::story` issue, a clean
|
|
118
83
|
`gh auth status`, and `project.baseBranch` present both locally and on
|
|
119
|
-
`origin` —
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
The v2 engine's trait table:
|
|
124
|
-
|
|
125
|
-
| Trait | v2 `/deliver-story` |
|
|
126
|
-
| ------------- | ------------------------------------------------------------------------ |
|
|
127
|
-
| Ticket type | `type::story` only |
|
|
128
|
-
| Branch | `story-<id>` seeded from `project.baseBranch` (`main`) |
|
|
129
|
-
| Merge target | `main` via PR (squash + required checks) |
|
|
130
|
-
| Spec / slices | Folded `## Spec` + optional `## Slicing` checkpoints in-session |
|
|
131
|
-
| Ceremony | Per-Story, resolved from the ceremony profile alone via `ceremony-routing.js` (digest § 3) |
|
|
84
|
+
`origin` — a missing or unauthenticated remote surfaces as a
|
|
85
|
+
`remoteVerified: false` block rather than a useful error. The engine's trait
|
|
86
|
+
table is digest § 2.
|
|
132
87
|
|
|
133
88
|
**A cheap shape never buys a cheaper landing.** A small Story collapses only
|
|
134
89
|
the _advisory_ ceremony — the fresh-critic / Tech-Spec authoring a
|
|
135
90
|
one-artifact scope does not earn. The close-validation gates (lint / test /
|
|
136
91
|
format / coverage / CRAP / maintainability), the PR to `main`, and the
|
|
137
92
|
`rules/security-baseline.md` MUSTs run exactly as for any other Story. There
|
|
138
|
-
is no gate bypass to opt into, and nothing in the ticket can declare one
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
verdict owner; the derived change level (`deriveChangeLevel` over the computed
|
|
144
|
-
change set) sets **review depth**, so a footprint intersecting a sensitive-path
|
|
145
|
-
class buys a deep review rather than a fresh acceptance critic. Persist stamps
|
|
146
|
-
no route label. The light path is the one caller that reads the authored body's
|
|
147
|
-
shape, through `deriveStoryShape`
|
|
148
|
-
(`lib/orchestration/complexity-gate.js`).
|
|
149
|
-
|
|
150
|
-
The derived level does **not** set the dispatch mode either,
|
|
151
|
-
because `inline` names one indivisible resource — the router's own session —
|
|
152
|
-
and only run topology can say whether it is free: a **single-Story run**
|
|
153
|
-
executes inline, and every Story of a multi-Story run dispatches as a
|
|
154
|
-
`story-worker` sub-agent whatever its shape — a lite shape makes the work
|
|
155
|
-
cheap, it does not conjure a second session for a sibling. Inline
|
|
156
|
-
execution changes the isolation only: the engine, every script gate, and the
|
|
157
|
-
terminal envelope are byte-identical either way.
|
|
93
|
+
is no gate bypass to opt into, and nothing in the ticket can declare one.
|
|
94
|
+
|
|
95
|
+
**The ceremony rule has one home: digest § 3**, and the dispatch rule is
|
|
96
|
+
digest § 1. The light path is the one caller that reads the authored body's
|
|
97
|
+
shape, through `deriveStoryShape` (`lib/orchestration/complexity-gate.js`).
|
|
158
98
|
|
|
159
99
|
---
|
|
160
100
|
|
|
@@ -179,49 +119,30 @@ alone inside the `---` footer block declares an edge:
|
|
|
179
119
|
blocked by #42
|
|
180
120
|
```
|
|
181
121
|
|
|
182
|
-
Prose elsewhere in the body declares **nothing
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
dispatch-edge parser share it — so what a Story body round-trips and what gates
|
|
193
|
-
dispatch cannot drift apart.
|
|
194
|
-
|
|
195
|
-
**The native channel fails loud.** The read paginates to exhaustion (a
|
|
196
|
-
first-page read silently truncated a Story's gates at GitHub's 30-item
|
|
197
|
-
default), and **a 404 is not an empty result**. An issue with no dependencies
|
|
198
|
-
answers `200 []`; a 404 is how GitHub also answers a token that cannot see the
|
|
199
|
-
dependencies API, so treating it as "no edges" erased every native edge in the
|
|
200
|
-
run under a mis-scoped token, silently, with a clean exit code. Any non-OK
|
|
201
|
-
read now fails the resolution naming the Story — check the token's scopes
|
|
202
|
-
first. The one degrade that is scoped rather than fatal is a **cross-repo
|
|
203
|
-
edge**: another repository's issue number cannot be matched against this
|
|
204
|
-
repo's same-numbered issue without risking a false match, so that edge is
|
|
122
|
+
Prose elsewhere in the body declares **nothing** — move a hand-written prose
|
|
123
|
+
edge into the footer block. The loose spellings `depends on #N`,
|
|
124
|
+
`Blocked by: #N`, and `blocked by #N once X lands` declare nothing either.
|
|
125
|
+
|
|
126
|
+
**The native channel fails loud.** The read paginates to exhaustion, and
|
|
127
|
+
**a 404 is not an empty result**: an issue with no dependencies answers
|
|
128
|
+
`200 []`, while a 404 is also how GitHub answers a token that cannot see the
|
|
129
|
+
dependencies API. Any non-OK read fails the resolution naming the Story —
|
|
130
|
+
check the token's scopes first. The one scoped degrade is a **cross-repo
|
|
131
|
+
edge**: it cannot be matched against this repo's same-numbered issue, so it is
|
|
205
132
|
dropped with a warning naming the Story, and its siblings resolve normally.
|
|
206
133
|
|
|
207
|
-
**Edges are monotone — retraction is not built.**
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
write path never deletes a native relation it did not need. In practice that
|
|
212
|
-
means: re-resolve after editing edges, and treat a stale gate as a body/issue
|
|
213
|
-
edit plus a fresh `resolve-stories.js` run, never as something delivery
|
|
214
|
-
un-declares on your behalf. This is a known limitation, not an oversight.
|
|
134
|
+
**Edges are monotone — retraction is not built.** Removing a footer line or a
|
|
135
|
+
native relation makes the edge absent from the **next** resolve, but nothing
|
|
136
|
+
reconciles an edge a previous run already acted on: treat a stale gate as a
|
|
137
|
+
body/issue edit plus a fresh `resolve-stories.js` run.
|
|
215
138
|
|
|
216
139
|
---
|
|
217
140
|
|
|
218
141
|
## Step 1 — Implementation detail
|
|
219
142
|
|
|
220
143
|
**Docs context — digest-first.** Read a full doc only when the Story's own
|
|
221
|
-
context points you at one
|
|
222
|
-
|
|
223
|
-
`docsDigestPath`, prefer that compact outline and pull individual files on
|
|
224
|
-
demand. See [`.agents/instructions.md` § 3](../../instructions.md).
|
|
144
|
+
context points you at one; prefer a caller-provided `docsDigestPath` and pull
|
|
145
|
+
individual files on demand. See [`.agents/instructions.md` § 3](../../instructions.md).
|
|
225
146
|
|
|
226
147
|
**Write-time audit checklists.** When the caller provides a `checklistPath`
|
|
227
148
|
(footprint-matched **local**-lens authoring checklists), read it before you
|
|
@@ -231,45 +152,24 @@ dispatch step produces `checklistPath` from the Story's predicted footprint
|
|
|
231
152
|
before it spawns the worker — see [`/mandrel-deliver`](../mandrel-deliver.md).
|
|
232
153
|
|
|
233
154
|
**Full-suite discipline (spine Step 2.5).** Repo-invariant guards —
|
|
234
|
-
drift-guard and schema tests
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
and what it credits — is stated once, in
|
|
239
|
-
[`deliver-digest.md`](deliver-digest.md) § 5.
|
|
155
|
+
drift-guard and schema tests outside the Story's scoped greps — are the
|
|
156
|
+
failure class that bounces deliveries, and close-validation discovers them
|
|
157
|
+
only after the whole close pipeline has run. The run itself is stated once,
|
|
158
|
+
in [`deliver-digest.md`](deliver-digest.md) § 5.
|
|
240
159
|
|
|
241
160
|
**Conflict with `main` mid-implementation** → resolve as you would any branch
|
|
242
|
-
rebase
|
|
243
|
-
directly.
|
|
161
|
+
rebase; the rebase base is `main` directly.
|
|
244
162
|
|
|
245
163
|
### Step 1a — self-eval mechanics
|
|
246
164
|
|
|
247
|
-
**One verdict owner per Story
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
`
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
`acceptance-eval.js` is the deterministic **scorer** of that one authored
|
|
256
|
-
verdict — schema validation, round cap, proceed / redraft / block — not an
|
|
257
|
-
independent additional pass over the criteria.
|
|
258
|
-
|
|
259
|
-
**One round = ONE verdict file → ONE gate call.** The verdict covers every
|
|
260
|
-
`acceptance[]` item exactly once, ordered by `index`, under one `storyId`,
|
|
261
|
-
`schemaVersion`, `round` and `commitSha`:
|
|
262
|
-
|
|
263
|
-
```bash
|
|
264
|
-
node <main-repo>/.agents/scripts/acceptance-eval.js \
|
|
265
|
-
--story <storyId> --verdict <verdict-path>
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
The gate reads the Story's `acceptance[]` count itself (Story #5313), so a
|
|
269
|
-
partial verdict is rejected before scoring and consumes no round;
|
|
270
|
-
`--expected-criteria` is accepted but redundant. A second gate call inside one
|
|
271
|
-
round spends a round for nothing, and concurrent calls race the Story-scoped
|
|
272
|
-
round ledger. Full per-round mechanics:
|
|
165
|
+
**One verdict owner per Story** — `verdictOwner: 'fresh-critic' |
|
|
166
|
+
'inline-self-eval'` from `resolveCeremonyForRisk`, following the ceremony
|
|
167
|
+
profile alone (digest § 3). Exactly one pass authors the verdict — never both,
|
|
168
|
+
and never a preliminary self-assessment before dispatching a fresh critic.
|
|
169
|
+
`acceptance-eval.js` is the deterministic **scorer** of that one verdict —
|
|
170
|
+
schema validation, round cap, proceed / redraft / block — not an additional
|
|
171
|
+
pass over the criteria. The invocation and the one-verdict-one-call rule are
|
|
172
|
+
digest § 4; per-round mechanics are
|
|
273
173
|
[`acceptance-self-eval.md`](acceptance-self-eval.md).
|
|
274
174
|
|
|
275
175
|
**On `decision: "block"`** — post a `friction` comment naming the unmet
|
|
@@ -285,31 +185,13 @@ node .agents/scripts/update-ticket-state.js --ticket <storyId> --state agent::bl
|
|
|
285
185
|
|
|
286
186
|
## Step 2 — Ceremony detail
|
|
287
187
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
Its `level` comes from
|
|
298
|
-
[`deriveChangeLevel`](../../scripts/lib/orchestration/review-depth.js) over
|
|
299
|
-
the one computed change-set list: a diff touching a sensitive path registered
|
|
300
|
-
in `.agents/schemas/audit-rules.json` derives `high`, one touching none
|
|
301
|
-
derives `low`, and an unenumerable diff (`files: null`) derives `null`.
|
|
302
|
-
Hand the **same** `files` list to the verdict owner (Step 1a) — an evaluator
|
|
303
|
-
that re-ran its own `git diff` could score against a different set than the
|
|
304
|
-
one that routed it.
|
|
305
|
-
|
|
306
|
-
The derived level drives **review depth** and nothing else: `review-depth.js`
|
|
307
|
-
reads it inside close and still resolves `deep` for any sensitive class.
|
|
308
|
-
`mode` / `verdictOwner` come from
|
|
309
|
-
[`resolveCeremonyForRisk`](../../scripts/lib/orchestration/ceremony-routing.js),
|
|
310
|
-
which since Story #5366 accepts the profile and nothing else. The rule — and
|
|
311
|
-
what an `inline` dispatch does and does not change about it — is stated once
|
|
312
|
-
in **digest § 3**; do not restate it here.
|
|
188
|
+
`ceremony-derive.js` (digest § 3) is the change-set enumeration, the level
|
|
189
|
+
derivation ([`deriveChangeLevel`](../../scripts/lib/orchestration/review-depth.js))
|
|
190
|
+
and the ceremony resolution
|
|
191
|
+
([`resolveCeremonyForRisk`](../../scripts/lib/orchestration/ceremony-routing.js))
|
|
192
|
+
in one call. Hand the **same** `files` list to the verdict owner (Step 1a) —
|
|
193
|
+
an evaluator that re-ran its own `git diff` could score a different set than
|
|
194
|
+
the one that routed it.
|
|
313
195
|
|
|
314
196
|
---
|
|
315
197
|
|
|
@@ -317,16 +199,12 @@ in **digest § 3**; do not restate it here.
|
|
|
317
199
|
|
|
318
200
|
**Step 3 is the orchestrator's, and it is serialized.** A dispatched
|
|
319
201
|
`story-worker` ends its turn at a pushed branch (spine § Step 2.5); the session
|
|
320
|
-
that dispatched it runs close. Two reasons
|
|
321
|
-
theoretical:
|
|
202
|
+
that dispatched it runs close. Two reasons:
|
|
322
203
|
|
|
323
204
|
1. **A sub-agent cannot resume itself.** It gets no notification when a
|
|
324
205
|
backgrounded close finishes, so a worker that backgrounds close and ends its
|
|
325
|
-
turn strands the envelope in a turn nobody reads
|
|
326
|
-
|
|
327
|
-
instruction. Moving the seam removes the failure instead of re-wording the
|
|
328
|
-
prohibition. The parent, by contrast, is still live and _does_ observe and
|
|
329
|
-
retry its own close.
|
|
206
|
+
turn strands the envelope in a turn nobody reads. The parent, by contrast,
|
|
207
|
+
is still live and _does_ observe and retry its own close.
|
|
330
208
|
2. **Closes contend; implementation does not.** Close syncs from
|
|
331
209
|
`origin/<baseBranch>`, pushes, opens a PR and arms auto-merge — two of those
|
|
332
210
|
in flight race on the base branch, the merge queue and the shared checkout.
|
|
@@ -340,16 +218,6 @@ envelope with a re-dispatch: `single-story-init.js` re-run under a live branch
|
|
|
340
218
|
is how one Story ends up with two closes. Close the pushed branch, or probe with
|
|
341
219
|
`deliver-recover.js` and run the one command it prints.
|
|
342
220
|
|
|
343
|
-
**What close does internally.** The script runs the close-validation gates
|
|
344
|
-
against `baseBranch`, syncs the Story branch from `origin/<baseBranch>`
|
|
345
|
-
(the parallel-race defence), pushes `story-<id>`, opens (or
|
|
346
|
-
reuses) a PR against `baseBranch` with a `Closes #<storyId>` footer, enables
|
|
347
|
-
GitHub native auto-merge (`--auto --squash --delete-branch`) **when
|
|
348
|
-
`delivery.ci.autoMerge` is `"trust-ci"` (the default)**, flips the Story to
|
|
349
|
-
`agent::closing`, reaps the worktree, releases the lease, then **waits for
|
|
350
|
-
the merge** and — on a confirmed merge — flips `agent::done` and runs the
|
|
351
|
-
post-land tail.
|
|
352
|
-
|
|
353
221
|
**The merge wait is bounded and resumable.** Two budgets, deliberately
|
|
354
222
|
separate (`delivery.mergeWatch.*`):
|
|
355
223
|
|
|
@@ -363,38 +231,16 @@ separate (`delivery.mergeWatch.*`):
|
|
|
363
231
|
|
|
364
232
|
The wait probes the checks every poll: a red required check fails fast as
|
|
365
233
|
`checks-failed` instead of burning the budget, and a PR that falls behind its
|
|
366
|
-
base is brought up to date within
|
|
367
|
-
|
|
368
|
-
**Async merge-confirm mode (`delivery.mergeWatch.mode: "async"`).** Under
|
|
369
|
-
the default `"sync"` the merge wait runs in the foreground as described above.
|
|
234
|
+
base is brought up to date within 3 tries.
|
|
370
235
|
|
|
371
236
|
**On a multi-Story run, async is the posture — pass `--merge-watch-mode async`
|
|
372
|
-
on every close.**
|
|
373
|
-
the
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
([`deliver-reference.md`](deliver-reference.md) § Async merge-confirm mode).
|
|
380
|
-
A slow-CI consumer reaches for the same mode for the separate reason that a
|
|
381
|
-
foreground wait longer than the host tool ceiling (~10 min) almost always
|
|
382
|
-
expires `pending` after burning ~5 minutes of the slot — `"async"` makes that
|
|
383
|
-
confirm a designed ending instead of an expiry accident.
|
|
384
|
-
|
|
385
|
-
In async mode the close arms auto-merge, runs one short **~60s
|
|
386
|
-
probe window** (long enough to catch an instant merge and, via the
|
|
387
|
-
head-anchored required-check predicate, an instantly-red required check),
|
|
388
|
-
then returns the standard `pending` terminal with a `nextCommand`. When you
|
|
389
|
-
receive that `pending` envelope, launch its `nextCommand`
|
|
390
|
-
(`single-story-confirm-merge.js … --wait`) as a **background** invocation —
|
|
391
|
-
host **background Bash** (`run_in_background`), whose completion re-invokes
|
|
392
|
-
the agent — and continue; do **not** sit in a foreground poll the tool
|
|
393
|
-
ceiling will kill. `single-story-confirm-merge.js` is already idempotent and
|
|
394
|
-
owns the whole tail, so no new state holder is needed, and
|
|
395
|
-
`deliver-recover.js` remains the recovery path for an orphaned confirm. The
|
|
396
|
-
cumulative `maxBudgetSeconds` give-up is unchanged; `"sync"` behaviour is
|
|
397
|
-
byte-compatible.
|
|
237
|
+
on every close.** The close tail is serialized, and under `sync` each close
|
|
238
|
+
holds the foreground for its full merge wait before the next may start. Close
|
|
239
|
+
cannot see run topology, so the orchestrator makes the call per invocation
|
|
240
|
+
(`deliver-run.js` renders it into every multi-Story `close[]` command) while
|
|
241
|
+
the config default stays `"sync"` — right for a solo delivery. What async does
|
|
242
|
+
and how to resume its `pending` is
|
|
243
|
+
[`deliver-reference.md`](deliver-reference.md) § Async merge-confirm mode.
|
|
398
244
|
|
|
399
245
|
**`delivery.ci.autoMerge` policy.** Under the default `"trust-ci"`, GitHub
|
|
400
246
|
native auto-merge is armed and the PR squash-merges once its **required**
|
|
@@ -434,10 +280,9 @@ judgment that help text cannot carry.
|
|
|
434
280
|
- `--merge-watch-mode <sync|async>` — the per-invocation override of
|
|
435
281
|
`delivery.mergeWatch.mode`. **Pass `async` on every close of a multi-Story
|
|
436
282
|
run** (above); leave it off for a solo delivery. It composes with
|
|
437
|
-
`--max-wait-seconds` —
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
reports a `failed` terminal envelope at `phase: init`, mutating nothing.
|
|
283
|
+
`--max-wait-seconds` — the explicit bound still wins over the async probe
|
|
284
|
+
cap. An unrecognized value is refused before any phase runs, reporting a
|
|
285
|
+
`failed` terminal envelope at `phase: init` and mutating nothing.
|
|
441
286
|
|
|
442
287
|
---
|
|
443
288
|
|
|
@@ -446,15 +291,10 @@ judgment that help text cannot carry.
|
|
|
446
291
|
The `single-story-close.js` script, in order:
|
|
447
292
|
|
|
448
293
|
1. **Syncs the Story branch from `origin/<baseBranch>`** — before the gates,
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
bumps `baseBranch`, and without this sync the lagging Stories open
|
|
454
|
-
PRs that are "behind base" and stall against branch-protection's
|
|
455
|
-
`up-to-date branch` rule. Running it first also means a conflict costs
|
|
456
|
-
no gate run at all, and — the load-bearing half — the tree the gates
|
|
457
|
-
validate is the tree the push sends. Outcomes:
|
|
294
|
+
so the tree the gates validate is the tree the push sends, and a conflict
|
|
295
|
+
costs no gate run. It runs `git fetch origin <baseBranch>` then
|
|
296
|
+
`git merge --no-edit origin/<baseBranch>` in the worktree, defending against
|
|
297
|
+
parallel Stories leaving a lagging PR "behind base". Outcomes:
|
|
458
298
|
- **No-op / fast-forward / clean merge-commit** → close proceeds to
|
|
459
299
|
push.
|
|
460
300
|
- **Merge conflict** → the merge is aborted, a `friction` structured
|
|
@@ -466,75 +306,32 @@ The `single-story-close.js` script, in order:
|
|
|
466
306
|
- **Fetch failed** → close throws with the git stderr; no label
|
|
467
307
|
transition.
|
|
468
308
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
defence against the parallel race. Without merge queue, the sync
|
|
472
|
-
closes the PR-open-time race but a residual race remains between PR
|
|
473
|
-
open and auto-merge fire.
|
|
474
|
-
|
|
475
|
-
2. Runs the close-validation gates against `baseBranch` as the baseline.
|
|
476
|
-
On any gate failure it throws — the operator fixes and re-runs close.
|
|
477
|
-
The chain fails cheapest-first: `typecheck`, `lint`, `format` and the
|
|
478
|
-
coverage-independent half of the baselines gate
|
|
479
|
-
(`check-baselines-independent`) run in parallel, and only once they are
|
|
480
|
-
green does the serial walk pay for `coverage-capture` and the
|
|
481
|
-
coverage-consuming half (`check-baselines-coverage`).
|
|
482
|
-
**Gate output is captured, not streamed.** Every gate line
|
|
483
|
-
goes to `temp/orchestration/close-gates-<storyId>.log`; a clean run reports
|
|
484
|
-
one digest line naming that artifact, and a **failed** gate replays its
|
|
485
|
-
captured tail inline so the evidence is in front of you without opening a
|
|
486
|
-
file. Read the artifact when you need the full text — or re-run under
|
|
487
|
-
`AGENT_LOG_LEVEL=verbose` for live streaming.
|
|
309
|
+
Without a merge queue a residual race remains between PR open and
|
|
310
|
+
auto-merge fire; the merge queue re-tests against the queue tip.
|
|
488
311
|
|
|
312
|
+
2. Runs the close-validation gates against `baseBranch`; any failure throws —
|
|
313
|
+
fix and re-run close. The chain fails cheapest-first: `typecheck`, `lint`,
|
|
314
|
+
`format` and `check-baselines-independent` run in parallel, and only once
|
|
315
|
+
they are green does the serial walk pay for `coverage-capture` and
|
|
316
|
+
`check-baselines-coverage`. Gate output is captured (digest § 6).
|
|
489
317
|
3. Pushes `story-<id>` to `origin`.
|
|
490
|
-
4.
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
4a. **Enables GitHub native auto-merge by default** via
|
|
495
|
-
`gh pr merge <prNumber> --auto --squash --delete-branch`. Once CI's
|
|
496
|
-
required checks turn green, GitHub squash-merges the PR and deletes
|
|
497
|
-
the source branch — the operator does not need to babysit the merge
|
|
498
|
-
button. Mirrors the `/mandrel-deliver` finalize path. Failure is
|
|
499
|
-
non-fatal: the operator retains the manual merge surface in the
|
|
500
|
-
GitHub UI. Pass `--no-auto-merge` to opt out when the PR needs a
|
|
501
|
-
pre-merge eyeball.
|
|
318
|
+
4. Opens (or reuses) a PR with `head = story-<id>` against `<baseBranch>`,
|
|
319
|
+
carrying `Closes #<storyId>`, and arms native auto-merge
|
|
320
|
+
(`gh pr merge <prNumber> --auto --squash --delete-branch`) unless
|
|
321
|
+
`--no-auto-merge` or `autoMerge: "strict"`. An arm failure is non-fatal.
|
|
502
322
|
5. Flips the Story to **`agent::closing`** (NOT `agent::done`) and leaves
|
|
503
|
-
the
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
at `agent::closing` while the PR is open with auto-merge armed; the
|
|
508
|
-
`agent::done` flip (which closes the issue) is deferred to Step 5's
|
|
509
|
-
merge confirmation — `single-story-confirm-merge.js` on a
|
|
510
|
-
`--no-wait-merge` run, or the in-close confirm phase on the
|
|
511
|
-
close-and-land default. (Step 5.5 is the Status-column resync.) A Story
|
|
512
|
-
only reaches `agent::done` once its PR to `main` is confirmed merged.
|
|
323
|
+
the issue **OPEN**: auto-merge completes after the arm, so closing here
|
|
324
|
+
would strand a CLOSED issue with no merged work if the PR failed CI, went
|
|
325
|
+
`BEHIND` base, or closed unmerged. A Story only reaches `agent::done` once
|
|
326
|
+
its PR to `main` is confirmed merged (Step 5).
|
|
513
327
|
6. Reaps the worktree when `delivery.worktreeIsolation.reapOnSuccess`
|
|
514
328
|
is enabled.
|
|
515
|
-
7. **Releases the Story lease
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
Note the lease does **not** expire on its own: the standalone lease is
|
|
522
|
-
fail-closed by design (it anchors its heartbeat to now, so a foreign
|
|
523
|
-
claim always reads as live regardless of the configured TTL), so a
|
|
524
|
-
claim stranded by a failed release is cleared only by `--steal` or by
|
|
525
|
-
de-assigning the ticket. The close result carries
|
|
526
|
-
`leaseReleased: <boolean>`.
|
|
527
|
-
|
|
528
|
-
`--skip-validation` bypasses the gate step. Use only when re-running
|
|
529
|
-
close after a fixed gate failure that's already known to pass.
|
|
530
|
-
|
|
531
|
-
`--skip-sync` bypasses the base-sync step. Use only when re-running
|
|
532
|
-
close after a hand-resolved sync, or in tests. The two flags are
|
|
533
|
-
independent: either, both or neither may be set, and each elides exactly
|
|
534
|
-
its own phase.
|
|
535
|
-
|
|
536
|
-
`--no-auto-merge` disables the auto-merge arm (step 4a). Use when the PR materially changes
|
|
537
|
-
behaviour and warrants pre-merge review.
|
|
329
|
+
7. **Releases the Story lease** — a no-op when the operator no longer holds
|
|
330
|
+
the claim, so a late close never yanks a live claim. Best-effort: a
|
|
331
|
+
release failure is logged, not fatal, and reported as
|
|
332
|
+
`leaseReleased: <boolean>`. The fail-closed lease never expires on its
|
|
333
|
+
own, so a claim stranded by a failed release is cleared only by `--steal`
|
|
334
|
+
or by de-assigning the ticket.
|
|
538
335
|
|
|
539
336
|
---
|
|
540
337
|
|
|
@@ -543,10 +340,9 @@ behaviour and warrants pre-merge review.
|
|
|
543
340
|
Enter this step **only** when Step 3 returned `blocked` with
|
|
544
341
|
`blockClass: "checks-failed"` (a required check went red), or when a
|
|
545
342
|
`--no-wait-merge` run left the PR for you to shepherd. When a required check is
|
|
546
|
-
red, the agent owns the green-CI outcome, not just the push:
|
|
547
|
-
close-validation gates pass on the dev host's environment; CI runs on a
|
|
343
|
+
red, the agent owns the green-CI outcome, not just the push: CI runs on a
|
|
548
344
|
different OS and concurrency, and coverage rounding, platform-conditional
|
|
549
|
-
branches, and timing-sensitive tests routinely drift
|
|
345
|
+
branches, and timing-sensitive tests routinely drift from the dev host.
|
|
550
346
|
|
|
551
347
|
Fix the failure and push a new commit on `story-<storyId>` — the watcher
|
|
552
348
|
**disarmed native auto-merge on the first red** and re-arms it
|
|
@@ -566,18 +362,11 @@ node <agentRoot>/scripts/pr-watch-with-update.js --pr <prNumber> --story <storyI
|
|
|
566
362
|
(`temp/story-<id>-ci-digest.{json,md}` — failing check name, the PR head SHA,
|
|
567
363
|
run id + run link, and a `gh run view --log-failed` tail). Omit it and a red
|
|
568
364
|
check writes no digest — and with no digest the no-rerun guard has nothing to
|
|
569
|
-
adjudicate the next green against, so always pass it.
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
`--
|
|
573
|
-
|
|
574
|
-
**empty** required-check set before it stops waiting for a context to attach —
|
|
575
|
-
a required context that is an aggregator job gated on every other tier is the
|
|
576
|
-
last check to appear, measured at 16m52s on this repository.
|
|
577
|
-
|
|
578
|
-
Add `--repo owner/repo` only when the cwd is not the target repository; it
|
|
579
|
-
reaches `gh` as a real flag. There is no `<owner/repo>#<number>` ref form —
|
|
580
|
-
`gh` parses that as a branch name.
|
|
365
|
+
adjudicate the next green against, so always pass it. Cadence, caps and the
|
|
366
|
+
attach window (how long an **empty** required-check set is re-resolved before
|
|
367
|
+
the watch stops waiting, default 20 min) are in `--help`. Add
|
|
368
|
+
`--repo owner/repo` only when the cwd is not the target repository; there is no
|
|
369
|
+
`<owner/repo>#<number>` ref form — `gh` parses that as a branch name.
|
|
581
370
|
|
|
582
371
|
When the watch exits, branch on the exit code:
|
|
583
372
|
|
|
@@ -607,17 +396,14 @@ When the watch exits, branch on the exit code:
|
|
|
607
396
|
and **no** required context ever attached, while the PR kept reading back
|
|
608
397
|
fine. CI has not started; there is no failing check and no CI digest to
|
|
609
398
|
read. Do **not** treat it as red — nothing needs fixing, and re-watching
|
|
610
|
-
(or raising `
|
|
399
|
+
(or raising `--attach-window-ms`) is the whole remediation.
|
|
611
400
|
- **unresolved** (`reconciliation.reconciled: false`) — every observed
|
|
612
401
|
required check is green but the repository still refuses the merge, so the
|
|
613
402
|
green verdict is withheld.
|
|
614
403
|
|
|
615
404
|
**Triage authority.** How to classify and remediate a red (or repeatedly slow)
|
|
616
|
-
check — the root-cause-only decision tree
|
|
617
|
-
|
|
618
|
-
Option-2 verdict and file the intake issue), the never-rerun / never-quarantine
|
|
619
|
-
prohibitions, and the escalation criteria (three-strikes, the 30-minute
|
|
620
|
-
wall-clock timebox, and the clearly-environmental fast path) — is defined once in
|
|
405
|
+
check — the root-cause-only decision tree, the never-rerun / never-quarantine
|
|
406
|
+
prohibitions, and the escalation criteria — is defined once in
|
|
621
407
|
[`.agents/rules/ci-remediation.md`](../../rules/ci-remediation.md). Read it
|
|
622
408
|
before remediating a red check.
|
|
623
409
|
|
|
@@ -638,23 +424,17 @@ planning pass, so the delivery never waits on planning.
|
|
|
638
424
|
|
|
639
425
|
### The auto-merge wait is an internally-blocking step
|
|
640
426
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
background watch task to complete" or "the next event will be its completion
|
|
645
|
-
notification" — leaving the merge unconfirmed and the Story stranded at
|
|
646
|
-
`agent::closing`. **Do not do this.**
|
|
427
|
+
A session that owns close must not arm auto-merge and then end its turn with
|
|
428
|
+
**free-form prose** ("I'll wait for the background watch task…"), leaving the
|
|
429
|
+
merge unconfirmed and the Story stranded at `agent::closing`.
|
|
647
430
|
`pr-watch-with-update.js --pr <prNumber>` _blocks the current turn_ until CI
|
|
648
|
-
resolves — that is the mechanism by which you wait.
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
`
|
|
654
|
-
|
|
655
|
-
[terminal schema](../../schemas/story-deliver-terminal.schema.json) accepts. Ending your turn with prose and an
|
|
656
|
-
unconfirmed merge is a contract violation — it is the very bug this workflow
|
|
657
|
-
exists to prevent.
|
|
431
|
+
resolves — that is the mechanism by which you wait. Keep your turn alive:
|
|
432
|
+
watch → (fix + push + re-watch on red) → confirm the merge (Step 5) → and only
|
|
433
|
+
then return the terminal status. **Only** a confirmed-`MERGED` PR
|
|
434
|
+
(→ `status: "landed"`), an `agent::blocked` transition (→ `status: "blocked"`),
|
|
435
|
+
or an unrecoverable failure (→ `status: "failed"`) ends the turn — or a
|
|
436
|
+
genuine `pending` (§ Step 7). The statuses are the shipped
|
|
437
|
+
[terminal schema](../../schemas/story-deliver-terminal.schema.json)'s.
|
|
658
438
|
|
|
659
439
|
### Resurrecting the worktree after `reapOnSuccess`
|
|
660
440
|
|
|
@@ -674,33 +454,22 @@ state and lose the close commit's structured comment.
|
|
|
674
454
|
|
|
675
455
|
### Diagnosing the failure
|
|
676
456
|
|
|
677
|
-
Pull the failing job log via:
|
|
678
|
-
|
|
679
457
|
```bash
|
|
680
458
|
gh run view <runId> --repo <owner>/<repo> --log-failed
|
|
681
459
|
```
|
|
682
460
|
|
|
683
|
-
The `<runId>` is the
|
|
684
|
-
|
|
685
|
-
|
|
461
|
+
The `<runId>` is in the failing row's URL from `gh pr checks`. The gate that
|
|
462
|
+
exited non-zero is named at the bottom of the log (e.g.
|
|
463
|
+
`[Coverage] ❌ REGRESSION in …`).
|
|
686
464
|
|
|
687
465
|
### Fixing without re-running close-validation
|
|
688
466
|
|
|
689
|
-
For coverage / maintainability / CRAP regressions detected only on CI
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
locally, because Windows numbers will overwrite CI's Linux numbers
|
|
696
|
-
and the cycle repeats.
|
|
697
|
-
2. Commit the baseline delta with a `chore(baselines):` message that
|
|
698
|
-
names the CI run that produced the values.
|
|
699
|
-
3. `git push` to `origin/story-<storyId>` and re-watch.
|
|
700
|
-
|
|
701
|
-
For genuine test failures (a flaky test, a platform-conditional bug):
|
|
702
|
-
fix the code or test, commit, push, re-watch. Keep iterating until
|
|
703
|
-
the watch exits clean.
|
|
467
|
+
For coverage / maintainability / CRAP regressions detected only on CI, update
|
|
468
|
+
the relevant `baselines/*.json` to CI's actual numbers by hand when they are
|
|
469
|
+
within the tolerance you would otherwise accept — a local `npm run … :update`
|
|
470
|
+
on another OS overwrites CI's numbers and the cycle repeats. Commit it as
|
|
471
|
+
`chore(baselines):` naming the CI run, push, and re-watch. For genuine test
|
|
472
|
+
failures: fix the code or test, commit, push, re-watch.
|
|
704
473
|
|
|
705
474
|
### When to stop iterating
|
|
706
475
|
|
|
@@ -733,27 +502,12 @@ the watch exits clean.
|
|
|
733
502
|
node .agents/scripts/single-story-confirm-merge.js --story <storyId> --cwd <main-repo>
|
|
734
503
|
```
|
|
735
504
|
|
|
736
|
-
This is the **same** shared land path Step 3 reaches: it
|
|
737
|
-
`agent::closing → agent::done` on a confirmed merge (closing the
|
|
738
|
-
the **same** post-land tail — so the two surfaces cannot
|
|
739
|
-
idempotent, emits the same terminal envelope, and is safe to
|
|
740
|
-
is still open (returns `pending`).
|
|
741
|
-
|
|
742
|
-
`single-story-confirm-merge.js` re-reads the live PR state (`gh pr view
|
|
743
|
-
--json state,mergedAt`, probing `gh pr list --head story-<id> --state all`
|
|
744
|
-
when `--pr` is omitted) and:
|
|
745
|
-
|
|
746
|
-
- **PR `MERGED`** → flips `agent::closing → agent::done`, closing the
|
|
747
|
-
issue, and fires the `story-merged` notify. Prints
|
|
748
|
-
`{ action: 'done', merged: true, ... }`.
|
|
749
|
-
- **PR still open / closed-without-merge** → leaves the Story at
|
|
750
|
-
`agent::closing` (issue stays OPEN) and prints
|
|
751
|
-
`{ action: 'pending', reason: 'pr-open' | 'pr-not-merged' | 'no-pr' }`.
|
|
752
|
-
Re-run after the merge lands.
|
|
753
|
-
- **Story already `agent::done` / issue already closed** → idempotent
|
|
754
|
-
`{ action: 'noop', reason: 'already-done' }`.
|
|
755
|
-
|
|
756
|
-
The issue closes exactly when the work has merged, never at PR-open.
|
|
505
|
+
This is the **same** shared land path Step 3 reaches: it re-reads the live PR
|
|
506
|
+
state, flips `agent::closing → agent::done` on a confirmed merge (closing the
|
|
507
|
+
issue) and runs the **same** post-land tail — so the two surfaces cannot
|
|
508
|
+
diverge. It is idempotent, emits the same terminal envelope, and is safe to
|
|
509
|
+
re-run while the PR is still open (returns `pending`). The issue closes exactly
|
|
510
|
+
when the work has merged, never at PR-open.
|
|
757
511
|
|
|
758
512
|
---
|
|
759
513
|
|
|
@@ -767,58 +521,22 @@ The issue closes exactly when the work has merged, never at PR-open.
|
|
|
767
521
|
node .agents/scripts/resync-status-column.js --story <storyId>
|
|
768
522
|
```
|
|
769
523
|
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
`Pull request linked to issue` are enabled by default on most boards
|
|
776
|
-
and fire ~minutes _after_ auto-merge lands. They overwrite the Status
|
|
777
|
-
field as a side-effect, clobbering the `Done` value
|
|
778
|
-
`single-story-confirm-merge.js` set at the `agent::done` flip in Step 5
|
|
779
|
-
and leaving closed Stories stuck at `In Progress` on the board. The
|
|
780
|
-
confirmation step has already exited by then, so the bot gets the last
|
|
781
|
-
write.
|
|
782
|
-
|
|
783
|
-
`resync-status-column.js`:
|
|
784
|
-
|
|
785
|
-
- Reads the ticket's current `agent::*` label set (now `agent::done`).
|
|
786
|
-
- Re-fires the same `ColumnSync` mutation `transitionTicketState` used
|
|
787
|
-
at close, overwriting the bot's late write.
|
|
788
|
-
- **Polls the live Status for ~15 s after the initial write** and
|
|
789
|
-
re-fires on drift. Without this loop, a one-shot
|
|
790
|
-
mutation routinely lost the race against the bot's asynchronous
|
|
791
|
-
fire.
|
|
792
|
-
- Prints a single-line JSON envelope:
|
|
793
|
-
`{ ticketId, status, column?, reason?, attempts? }`. `attempts > 1`
|
|
794
|
-
means the helper had to fight a bot overwrite; `status: 'drifted'`
|
|
795
|
-
means the bot won every attempt in the poll budget (rare; usually
|
|
796
|
-
signals operator should reap the conflicting workflows).
|
|
797
|
-
|
|
798
|
-
Tuning flags are rarely needed; the script enumerates them itself
|
|
799
|
-
(`node .agents/scripts/resync-status-column.js --help`).
|
|
800
|
-
|
|
801
|
-
Idempotent: re-running on a ticket whose Status already matches the
|
|
802
|
-
target returns the same envelope. No-op skips (`no-project`,
|
|
803
|
-
`no-meta`, `not-on-project`) exit 0 with the reason in the envelope
|
|
804
|
-
so the workflow can continue.
|
|
805
|
-
|
|
806
|
-
**Canonical operator fix:** run
|
|
524
|
+
It re-fires the `ColumnSync` mutation and polls to win the race against the
|
|
525
|
+
Projects v2 built-in `Pull request merged` / `Pull request linked to issue`
|
|
526
|
+
workflows, which overwrite Status minutes after the merge. Idempotent and
|
|
527
|
+
no-op-safe; its envelope and flags are in `--help`. `status: 'drifted'` means
|
|
528
|
+
the bot won every attempt. **Canonical operator fix:** run
|
|
807
529
|
`node .agents/scripts/agents-bootstrap-github.js --reap-conflicting-workflows`
|
|
808
530
|
once per project to delete the conflicting bot workflows entirely.
|
|
809
|
-
This eliminates the race source; the poll loop becomes pure
|
|
810
|
-
defense-in-depth against re-enabled or future workflows.
|
|
811
531
|
|
|
812
532
|
---
|
|
813
533
|
|
|
814
534
|
## Step 6 — Local branch cleanup detail
|
|
815
535
|
|
|
816
536
|
> **The land tail already ran this** — it is `tail.refCleanup` and
|
|
817
|
-
> `tail.baseFastForward` in the terminal envelope
|
|
818
|
-
>
|
|
819
|
-
>
|
|
820
|
-
> after a manual merge on a `--no-wait-merge` run. To prune the story ref **and**
|
|
821
|
-
> fast-forward local `main` (or `project.baseBranch`):
|
|
537
|
+
> `tail.baseFastForward` in the terminal envelope. Run it by hand only when
|
|
538
|
+
> either step reported `false` (a dirty shared checkout is the common, benign
|
|
539
|
+
> cause), or after a manual merge on a `--no-wait-merge` run:
|
|
822
540
|
|
|
823
541
|
```bash
|
|
824
542
|
node .agents/scripts/git-cleanup.js \
|
|
@@ -830,51 +548,10 @@ node .agents/scripts/git-cleanup.js \
|
|
|
830
548
|
--include "story-<storyId>"
|
|
831
549
|
```
|
|
832
550
|
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
operator opted out via `--no-auto-merge` AND has not yet merged the PR — run the
|
|
838
|
-
cleanup after the manual merge lands.
|
|
839
|
-
|
|
840
|
-
GitHub deletes the **remote** branch on auto-merge (via the
|
|
841
|
-
`--delete-branch` flag `single-story-close.js` passes to `gh pr merge`).
|
|
842
|
-
The **local** `story-<storyId>` ref, however, lingers in the main
|
|
843
|
-
checkout until something prunes it — `single-story-init.js` runs a
|
|
844
|
-
merged-sweep at the start of every _subsequent_ `/deliver-story`
|
|
845
|
-
invocation, but that's next-run cleanup, not end-of-run cleanup. Stale
|
|
846
|
-
local refs accumulate between sessions, clutter `git branch`, and shadow
|
|
847
|
-
the lessons the sweep is meant to surface.
|
|
848
|
-
|
|
849
|
-
**Why local `main` goes stale:** `single-story-init.js` seeds new
|
|
850
|
-
`story-<id>` branches from the **local** `baseBranch` ref (default
|
|
851
|
-
`main`). Auto-merge updates **`origin/main`** on GitHub; nothing in
|
|
852
|
-
close or the old Step 6 command updated **local `main`**. The next init
|
|
853
|
-
then forked from a tip six merges behind until you manually pulled.
|
|
854
|
-
`single-story-init` also attempts the same fast-forward after `git fetch`
|
|
855
|
-
when the main checkout is clean (defense in depth if Step 6 was skipped).
|
|
856
|
-
Step 6 must still run `--fast-forward-main` so local `main` is current
|
|
857
|
-
before the next session — init may skip when the tree is dirty or the
|
|
858
|
-
operator is mid-checkout on another branch.
|
|
859
|
-
|
|
860
|
-
What the Step 6 cleanup command does:
|
|
861
|
-
|
|
862
|
-
- **`--fast-forward-main`** fetches `origin/<baseBranch>` and
|
|
863
|
-
`git merge --ff-only` on the main checkout when the tree is clean and
|
|
864
|
-
the local base is strictly behind remote. Skipped when already current,
|
|
865
|
-
dirty, or diverged (see `/git-cleanup`).
|
|
866
|
-
- **`--branches`** reaps the merged `story-<storyId>` ref (worktree,
|
|
867
|
-
local branch, stale `origin/` tracking ref). Does not run
|
|
868
|
-
`--prune-remotes` or `--stashes` unless you add those flags.
|
|
869
|
-
- **`--include "story-<storyId>"`** scopes the branch reap to this
|
|
870
|
-
Story's ref only — sibling stories in flight are untouched.
|
|
871
|
-
- **`--execute --remote --yes`** actually deletes the local ref, prunes
|
|
872
|
-
the matching `origin/` tracking ref, and runs non-interactively.
|
|
873
|
-
|
|
874
|
-
The sweep is idempotent. It is safe to run before `state: "MERGED"`
|
|
875
|
-
confirms (it will skip a not-yet-merged branch), and safe to re-run
|
|
876
|
-
after a successful cleanup (it reports "no merged branches to clean
|
|
877
|
-
up").
|
|
551
|
+
It fast-forwards local `main` (the next init seeds from it) and reaps only
|
|
552
|
+
this Story's ref. Idempotent and safe before `MERGED` confirms (a
|
|
553
|
+
not-yet-merged branch is skipped); after an `--no-auto-merge` opt-out, run it
|
|
554
|
+
once the manual merge lands.
|
|
878
555
|
|
|
879
556
|
---
|
|
880
557
|
|
|
@@ -896,9 +573,8 @@ The four constraints the spine states without arguing for them:
|
|
|
896
573
|
- **Never push the Story branch directly to `main`.** The PR is the only merge
|
|
897
574
|
surface — a direct push bypasses required checks and the squash title
|
|
898
575
|
release-please parses.
|
|
899
|
-
- **Always prefix path-based tools with the absolute `workCwd` root
|
|
900
|
-
|
|
901
|
-
the mistake, not a licence to make it.
|
|
576
|
+
- **Always prefix path-based tools with the absolute `workCwd` root** —
|
|
577
|
+
§ Worktree scope.
|
|
902
578
|
- **Report state, not process.** Mirror the close envelope's fields; step
|
|
903
579
|
narration reads as progress while telling the caller nothing it can branch on.
|
|
904
580
|
- **Drive every `agent::*` transition through `update-ticket-state.js`** so the
|
|
@@ -909,74 +585,57 @@ The four constraints the spine states without arguing for them:
|
|
|
909
585
|
The field-level contract is the shipped schema
|
|
910
586
|
[`story-deliver-terminal.schema.json`](../../schemas/story-deliver-terminal.schema.json)
|
|
911
587
|
— not this file, and not
|
|
912
|
-
[`agents/story-worker.md`](../../agents/story-worker.md).
|
|
913
|
-
|
|
914
|
-
follows is the _judgement_ around it, which a schema cannot express.
|
|
588
|
+
[`agents/story-worker.md`](../../agents/story-worker.md). What follows is the
|
|
589
|
+
_judgement_ around it, which a schema cannot express.
|
|
915
590
|
|
|
916
591
|
### `pending` is a real status — and it is not a park
|
|
917
592
|
|
|
918
593
|
`pending` is a real terminal status with its own exit code (3) — the honest
|
|
919
594
|
name for a close-and-land whose CI outlived the host's ~10-minute
|
|
920
|
-
tool-invocation ceiling
|
|
921
|
-
`agent::closing` with no event and no label:
|
|
595
|
+
tool-invocation ceiling:
|
|
922
596
|
|
|
923
597
|
- It is **resumable**: no label was mutated, no `merge.unlanded` was emitted,
|
|
924
598
|
and `nextCommand` names the one command that continues it. The cumulative
|
|
925
599
|
budget is anchored at the PR's `createdAt`, so resuming does not restart the
|
|
926
|
-
clock
|
|
600
|
+
clock.
|
|
927
601
|
- It is **not** a park. Returning `pending` because you would rather not wait
|
|
928
602
|
is the no-park failure mode wearing a schema. Return it only
|
|
929
603
|
when the bound genuinely expired, or a human owns the merge.
|
|
930
604
|
|
|
931
|
-
The no-park rule holds: a turn that ends with prose
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
"still working" from "done but silent". `pending` is the honest,
|
|
935
|
-
machine-readable alternative: "not finished, here is exactly how to continue."
|
|
605
|
+
The no-park rule holds: a turn that ends with prose and an unconfirmed merge
|
|
606
|
+
is a **contract violation** — the parent cannot distinguish "still working"
|
|
607
|
+
from "done but silent". `pending` is the honest, machine-readable alternative.
|
|
936
608
|
|
|
937
609
|
### The envelope also lands on disk
|
|
938
610
|
|
|
939
|
-
|
|
940
|
-
reader is not always still listening. A child that reports progress and ends
|
|
941
|
-
its turn while its close is mid-gate-chain is behaving reasonably, but the
|
|
942
|
-
envelope it never relayed is gone, and reconstructing the Story's state from
|
|
943
|
-
labels costs a recovery round trip plus a full resume of the child. Observed
|
|
944
|
-
four times across three workers in a single consumer run, on unrelated
|
|
945
|
-
footprints, and not new to that run.
|
|
946
|
-
|
|
947
|
-
So `emitTerminalEnvelope` — the one writer behind every emit site — also
|
|
611
|
+
`emitTerminalEnvelope` — the one writer behind every emit site — also
|
|
948
612
|
persists the validated envelope to
|
|
949
|
-
`<tempRoot>/orchestration/story-deliver-terminal-<storyId>.json
|
|
613
|
+
`<tempRoot>/orchestration/story-deliver-terminal-<storyId>.json`, because
|
|
614
|
+
stdout's one reader is not always still listening:
|
|
950
615
|
|
|
951
616
|
- **It is the same object**, not a summary. Read it and branch exactly as you
|
|
952
617
|
would on stdout; the copy is written before the markers are, so a caller
|
|
953
618
|
that saw them can rely on the file.
|
|
954
619
|
- **It is best-effort.** A failed write returns null and changes nothing about
|
|
955
|
-
the emitted envelope or the exit code
|
|
956
|
-
crash because a temp directory was unwritable.
|
|
620
|
+
the emitted envelope or the exit code.
|
|
957
621
|
- **It is a fallback, not a licence.** The orchestrator running close still
|
|
958
622
|
holds its turn until the envelope arrives; see § Step 3 above and
|
|
959
623
|
[`agents/story-worker.md`](../../agents/story-worker.md).
|
|
960
624
|
|
|
961
625
|
`deliver-recover.js` reads the same artifact, plus the freshness of
|
|
962
|
-
`close-gates-<storyId>.log`, to split
|
|
963
|
-
table. `agent::executing` with no PR used to answer "Implementation never
|
|
964
|
-
finished" — false for the whole duration of a close, whose gates and push
|
|
965
|
-
happen before any PR exists, and actively hazardous, because acting on its
|
|
966
|
-
re-init suggestion can put a second close on one PR. It now answers
|
|
626
|
+
`close-gates-<storyId>.log`, to split `agent::executing` with no PR: it answers
|
|
967
627
|
`close-in-flight` (a gate log touched inside the window: wait, then re-probe)
|
|
968
628
|
or `close-envelope-on-disk` (the close already reached a verdict: relay it),
|
|
969
|
-
and falls back to
|
|
629
|
+
and falls back to "Implementation never finished" only when neither artifact
|
|
630
|
+
exists — never re-init under a live close.
|
|
970
631
|
|
|
971
632
|
### Exit-code compatibility note (`--no-wait-merge`)
|
|
972
633
|
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
"close finished" must be updated to treat 3 as the operator-merge success
|
|
979
|
-
path; `!= 0` no longer implies failure.
|
|
634
|
+
A `--no-wait-merge` (or `--no-auto-merge` / `autoMerge: "strict"`) run exits
|
|
635
|
+
**3** (`pending`), not 0: the PR is open and a human still owns the merge, and
|
|
636
|
+
`landed` is what exit 0 means. A wrapper testing `exit == 0` for "close
|
|
637
|
+
finished" must treat 3 as the operator-merge success path; `!= 0` does not
|
|
638
|
+
imply failure.
|
|
980
639
|
|
|
981
640
|
### Per-status judgement
|
|
982
641
|
|
|
@@ -994,10 +653,7 @@ path; `!= 0` no longer implies failure.
|
|
|
994
653
|
|
|
995
654
|
> **Handoff discipline — report state, not process.** Populate the envelope
|
|
996
655
|
> with essential terminal state only (mirroring the fields
|
|
997
|
-
> `single-story-close.js` already emits)
|
|
998
|
-
>
|
|
999
|
-
>
|
|
1000
|
-
>
|
|
1001
|
-
> operator in prose instead — but the **no-park rule still holds**: never end
|
|
1002
|
-
> an interactive turn with an unconfirmed merge either; block on the watch,
|
|
1003
|
-
> confirm, and report the merged outcome.
|
|
656
|
+
> `single-story-close.js` already emits); do not narrate the steps you took.
|
|
657
|
+
> When run **interactively** (no parent aggregator), the JSON envelope is
|
|
658
|
+
> optional — relay terminal state in prose — but the **no-park rule still
|
|
659
|
+
> holds**: never end an interactive turn with an unconfirmed merge either.
|