mandrel 2.0.0 → 2.2.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 +59 -28
- package/.agents/agents/acceptance-critic.md +20 -9
- package/.agents/agents/story-worker.md +45 -48
- package/.agents/audit-checklists/performance.md +1 -1
- package/.agents/docs/SDLC.md +60 -46
- package/.agents/docs/agentrc-reference.json +8 -13
- package/.agents/docs/configuration.md +33 -57
- package/.agents/docs/execution-reference.md +39 -10
- package/.agents/docs/quality-gates.md +17 -19
- package/.agents/docs/workflows.md +6 -6
- package/.agents/instructions.md +64 -79
- package/.agents/rules/ci-remediation.md +3 -3
- package/.agents/rules/gherkin-standards.md +10 -0
- package/.agents/rules/git-conventions-reference.md +42 -51
- package/.agents/schemas/acceptance-eval-verdict.schema.json +2 -2
- package/.agents/schemas/agentrc.schema.json +35 -46
- package/.agents/schemas/audit-rules.json +59 -1
- package/.agents/schemas/audit-rules.schema.json +33 -1
- package/.agents/schemas/lifecycle/README.md +1 -2
- package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
- package/.agents/schemas/lifecycle/merge.flip-failed.schema.json +33 -0
- package/.agents/schemas/lifecycle/merge.unlanded.schema.json +1 -0
- package/.agents/schemas/lifecycle/story.merged.schema.json +1 -1
- package/.agents/schemas/signal-event.schema.json +3 -3
- package/.agents/schemas/story-deliver-terminal.schema.json +152 -0
- package/.agents/schemas/validation-evidence.schema.json +1 -1
- package/.agents/scripts/acceptance-eval.js +24 -68
- package/.agents/scripts/agents-bootstrap-github.js +1 -1
- package/.agents/scripts/bootstrap.js +3 -3
- package/.agents/scripts/check-dead-exports.js +43 -104
- package/.agents/scripts/check-doc-links.js +2 -2
- package/.agents/scripts/check-lifecycle-lint.js +1 -1
- package/.agents/scripts/check-workflow-cli-lint.js +91 -0
- package/.agents/scripts/deliver-recover.js +122 -0
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +20 -50
- package/.agents/scripts/generate-skills-index.js +17 -1
- package/.agents/scripts/generate-workflows-doc.js +4 -4
- package/.agents/scripts/lib/ITicketingProvider.js +1 -19
- package/.agents/scripts/lib/audit-suite/selector.js +323 -23
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -11
- package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -33
- package/.agents/scripts/lib/bootstrap/manifest.js +8 -11
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +30 -53
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -2
- package/.agents/scripts/lib/checks/core-bare-clean.js +4 -1
- package/.agents/scripts/lib/checks/index.js +1 -1
- package/.agents/scripts/lib/checks/loop-health.js +12 -11
- package/.agents/scripts/lib/checks/state.js +17 -248
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +3 -3
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +3 -4
- package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +2 -2
- package/.agents/scripts/lib/checks/worktree-residue-biome.js +3 -3
- package/.agents/scripts/lib/cli-args.js +23 -2
- package/.agents/scripts/lib/close-validation/gates.js +13 -13
- package/.agents/scripts/lib/close-validation/projections/inputs.js +7 -7
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +12 -12
- package/.agents/scripts/lib/close-validation/runner.js +13 -21
- package/.agents/scripts/lib/close-validation/telemetry.js +17 -8
- package/.agents/scripts/lib/config/acceptance-eval.js +2 -2
- package/.agents/scripts/lib/config/delivery-routing.js +7 -6
- package/.agents/scripts/lib/config/explain.js +10 -16
- package/.agents/scripts/lib/config/github.js +7 -5
- package/.agents/scripts/lib/config/limits.js +15 -25
- package/.agents/scripts/lib/config/quality.js +11 -14
- package/.agents/scripts/lib/config/runners.js +8 -21
- package/.agents/scripts/lib/config/temp-paths.js +18 -56
- package/.agents/scripts/lib/config-settings-schema-delivery.js +34 -16
- package/.agents/scripts/lib/config-settings-schema-quality.js +9 -2
- package/.agents/scripts/lib/config-settings-schema.js +48 -22
- package/.agents/scripts/lib/dead-exports-knip.js +105 -0
- package/.agents/scripts/lib/dead-exports-mode.js +51 -0
- package/.agents/scripts/lib/duplicate-search.js +38 -7
- package/.agents/scripts/lib/findings/promote-finding.js +23 -14
- package/.agents/scripts/lib/format-generated-json.js +97 -0
- package/.agents/scripts/lib/framework-version.js +19 -189
- package/.agents/scripts/lib/gh-exec.js +8 -0
- package/.agents/scripts/lib/git-branch-lifecycle.js +0 -158
- package/.agents/scripts/lib/git-utils.js +0 -14
- package/.agents/scripts/lib/json-utils.js +1 -2
- package/.agents/scripts/lib/label-constants.js +0 -15
- package/.agents/scripts/lib/label-taxonomy.js +1 -12
- package/.agents/scripts/lib/observability/active-story-env.js +42 -163
- package/.agents/scripts/lib/observability/runtime-friction.js +243 -0
- package/.agents/scripts/lib/observability/signal-validator.js +4 -4
- package/.agents/scripts/lib/observability/signals-writer.js +6 -82
- package/.agents/scripts/lib/observability/source-classifier.js +2 -2
- package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
- package/.agents/scripts/lib/orchestration/acceptance-clusters.js +1 -1
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +2 -2
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +43 -45
- package/.agents/scripts/lib/orchestration/change-set.js +103 -0
- package/.agents/scripts/lib/orchestration/code-review.js +70 -191
- package/.agents/scripts/lib/orchestration/consolidation-precondition.js +3 -3
- package/.agents/scripts/lib/orchestration/deliver-recover.js +328 -0
- package/.agents/scripts/lib/orchestration/detectors-phase.js +12 -6
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +34 -0
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -2
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +142 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +9 -11
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +86 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +37 -103
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +7 -3
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +50 -85
- package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +3 -14
- package/.agents/scripts/lib/orchestration/merge-block-class.js +76 -20
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
- package/.agents/scripts/lib/orchestration/plan-context.js +116 -33
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +26 -36
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +31 -22
- package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
- package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +16 -6
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +173 -25
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +280 -100
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +472 -55
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +21 -16
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +230 -0
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +41 -40
- package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +1 -2
- package/.agents/scripts/lib/orchestration/planning/spec-authoring-grounding.js +1 -1
- package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
- package/.agents/scripts/lib/orchestration/retro-proposals.js +7 -7
- package/.agents/scripts/lib/orchestration/review-depth.js +105 -40
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +3 -13
- package/.agents/scripts/lib/orchestration/review-providers/native.js +1 -154
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +3 -2
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +1 -1
- package/.agents/scripts/lib/orchestration/review-providers/types.js +5 -4
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +1 -1
- package/.agents/scripts/lib/orchestration/run-epilogue.js +374 -16
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +24 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +11 -9
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +4 -4
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +4 -13
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +608 -152
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +72 -30
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +305 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +1 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +12 -8
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +37 -4
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +2 -2
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +264 -43
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
- package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +104 -279
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +191 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +120 -0
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +75 -14
- package/.agents/scripts/lib/orchestration/story-init-remote.js +12 -8
- package/.agents/scripts/lib/orchestration/story-plan-state.js +14 -29
- package/.agents/scripts/lib/orchestration/task-body-validator.js +52 -7
- package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +119 -14
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +3 -4
- package/.agents/scripts/lib/orchestration/ticket-validator.js +121 -18
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -47
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +19 -32
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +61 -1
- package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
- package/.agents/scripts/lib/plan-phase-cleanup.js +12 -14
- package/.agents/scripts/lib/planning-corpus.js +12 -286
- package/.agents/scripts/lib/preflight-runner.js +2 -2
- package/.agents/scripts/lib/qa/qa-context-hydrator.js +5 -5
- package/.agents/scripts/lib/signals/index.js +4 -17
- package/.agents/scripts/lib/signals/read.js +35 -35
- package/.agents/scripts/lib/signals/schema.js +8 -11
- package/.agents/scripts/lib/signals/span-tree.js +7 -7
- package/.agents/scripts/lib/signals/write.js +0 -1
- package/.agents/scripts/lib/single-story/story-merged-notify.js +13 -2
- package/.agents/scripts/lib/skills/parse-skill.js +16 -3
- package/.agents/scripts/lib/story-adjacency.js +8 -7
- package/.agents/scripts/lib/story-body/story-body.js +81 -13
- package/.agents/scripts/lib/templates/decomposer-prompts.js +15 -16
- package/.agents/scripts/lib/test-env.js +14 -1
- package/.agents/scripts/lib/test-tiers.js +0 -3
- package/.agents/scripts/lib/ticket-body-sections.js +0 -14
- package/.agents/scripts/lib/validation-evidence.js +31 -59
- package/.agents/scripts/lib/wave-runner/live-probe.js +315 -0
- package/.agents/scripts/lib/wave-runner/ready-set.js +32 -6
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +68 -19
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
- package/.agents/scripts/plan-context.js +38 -7
- package/.agents/scripts/plan-critics.js +203 -0
- package/.agents/scripts/plan-persist.js +145 -35
- package/.agents/scripts/plan-run-epilogue.js +83 -38
- package/.agents/scripts/post-structured-comment.js +0 -38
- package/.agents/scripts/pr-watch-with-update.js +43 -22
- package/.agents/scripts/providers/github/compose.js +0 -1
- package/.agents/scripts/providers/github/errors.js +0 -19
- package/.agents/scripts/providers/github/issues.js +1 -11
- package/.agents/scripts/providers/github/mappers.js +5 -0
- package/.agents/scripts/providers/github/sub-issues.js +0 -47
- package/.agents/scripts/providers/github/tickets.js +33 -153
- package/.agents/scripts/providers/github.js +17 -6
- package/.agents/scripts/quality-preview.js +13 -6
- package/.agents/scripts/resolve-stories.js +236 -0
- package/.agents/scripts/run-coverage.js +4 -1
- package/.agents/scripts/run-lint.js +2 -2
- package/.agents/scripts/run-verify.js +31 -2
- package/.agents/scripts/signals-view.js +9 -10
- package/.agents/scripts/single-story-close.js +173 -18
- package/.agents/scripts/single-story-confirm-merge.js +288 -15
- package/.agents/scripts/single-story-init.js +6 -10
- package/.agents/scripts/stories-wave-tick.js +380 -53
- package/.agents/scripts/story-plan.js +3 -3
- package/.agents/scripts/update-ticket-state.js +8 -50
- package/.agents/skills/core/code-review-and-quality/SKILL.md +28 -450
- package/.agents/skills/core/code-review-and-quality/reference.md +458 -0
- package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +22 -315
- package/.agents/skills/core/debugging-and-error-recovery/reference.md +323 -0
- package/.agents/skills/core/diagnose-friction/SKILL.md +14 -18
- package/.agents/skills/core/documentation-and-adrs/SKILL.md +25 -397
- package/.agents/skills/core/documentation-and-adrs/reference.md +403 -0
- package/.agents/skills/core/gates-and-baselines/SKILL.md +12 -12
- package/.agents/skills/core/idea-refinement/SKILL.md +3 -3
- package/.agents/skills/core/scope-triage/SKILL.md +3 -0
- package/.agents/skills/core/security-and-hardening/SKILL.md +22 -367
- package/.agents/skills/core/security-and-hardening/reference.md +375 -0
- package/.agents/skills/skills.index.json +2 -12
- package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +2 -4
- package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +1 -1
- package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -3
- package/.agents/workflows/audit-architecture.md +3 -4
- package/.agents/workflows/audit-clean-code.md +4 -4
- package/.agents/workflows/audit-documentation.md +4 -5
- package/.agents/workflows/audit-lighthouse.md +8 -0
- package/.agents/workflows/audit-navigability.md +10 -0
- package/.agents/workflows/audit-performance.md +2 -3
- package/.agents/workflows/audit-quality.md +8 -9
- package/.agents/workflows/audit-security.md +1 -2
- package/.agents/workflows/audit-seo.md +10 -0
- package/.agents/workflows/audit-ux-ui.md +7 -0
- package/.agents/workflows/deliver.md +133 -45
- package/.agents/workflows/git-cleanup.md +2 -2
- package/.agents/workflows/git-deliver.md +1 -1
- package/.agents/workflows/helpers/acceptance-self-eval.md +34 -17
- package/.agents/workflows/helpers/code-quality-guardrails.md +15 -12
- package/.agents/workflows/helpers/code-review.md +14 -12
- package/.agents/workflows/helpers/deliver-story-reference.md +73 -32
- package/.agents/workflows/helpers/deliver-story.md +209 -118
- package/.agents/workflows/helpers/parallel-tooling.md +2 -2
- package/.agents/workflows/helpers/worktree-lifecycle.md +28 -32
- package/.agents/workflows/plan.md +239 -19
- package/.agents/workflows/qa-assist.md +6 -6
- package/.agents/workflows/qa-explore.md +3 -3
- package/.agents/workflows/qa-run.md +1 -5
- package/bin/mandrel.js +12 -1
- package/docs/CHANGELOG.md +62 -0
- package/lib/cli/registry.js +262 -19
- package/lib/cli/sync-agents.js +157 -0
- package/lib/cli/sync-commands.js +115 -6
- package/lib/cli/sync.js +168 -6
- package/lib/cli/update.js +105 -8
- package/lib/cli/version-helpers.js +131 -0
- package/lib/migrations/README.md +7 -5
- package/lib/migrations/index.js +17 -9
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +100 -0
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +101 -0
- package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +154 -0
- package/package.json +2 -2
- package/.agents/schemas/epic-perf-report.schema.json +0 -89
- package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +0 -15
- package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.blocked.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.close.end.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.complete.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +0 -14
- package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +0 -17
- package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +0 -15
- package/.agents/schemas/lifecycle/epic.plan.end.schema.json +0 -18
- package/.agents/schemas/lifecycle/epic.plan.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +0 -16
- package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.watch.end.schema.json +0 -29
- package/.agents/schemas/lifecycle/epic.watch.start.schema.json +0 -16
- package/.agents/schemas/lifecycle/story.heartbeat.schema.json +0 -20
- package/.agents/schemas/risk-verdict.schema.json +0 -53
- package/.agents/schemas/story-perf-summary.schema.json +0 -73
- package/.agents/scripts/analyze-execution.js +0 -444
- package/.agents/scripts/check-prepush-recovery.js +0 -90
- package/.agents/scripts/lib/git-merge-orchestrator.js +0 -261
- package/.agents/scripts/lib/observability/baseline-refresh-rate.js +0 -221
- package/.agents/scripts/lib/observability/hook-heartbeat.js +0 -187
- package/.agents/scripts/lib/observability/perf-aggregator.js +0 -813
- package/.agents/scripts/lib/observability/perf-report-readers.js +0 -328
- package/.agents/scripts/lib/observability/perf-report-render.js +0 -182
- package/.agents/scripts/lib/orchestration/audit-lens-routing.js +0 -128
- package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -273
- package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +0 -155
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-diff.js +0 -140
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +0 -665
- package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
- package/.agents/scripts/lib/orchestration/planning/risk-verdict.js +0 -104
- package/.agents/scripts/lib/orchestration/planning-context-budget.js +0 -213
- package/.agents/scripts/lib/orchestration/planning-risk.js +0 -194
- package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +0 -56
- package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +0 -21
- package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +0 -78
- package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +0 -68
- package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +0 -118
- package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +0 -397
- package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
- package/.agents/scripts/lib/orchestration/resolve-plan-run.js +0 -155
- package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
- package/.agents/scripts/lib/orchestration/story-progress/story-run-progress-writer.js +0 -400
- package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +0 -36
- package/.agents/scripts/resolve-plan-run.js +0 -117
- package/.agents/skills/core/analyze-execution/SKILL.md +0 -101
|
@@ -1,87 +1,153 @@
|
|
|
1
1
|
---
|
|
2
2
|
description:
|
|
3
|
-
Unified delivery entry point.
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Unified delivery entry point. Takes a list of Story ids, resolves their
|
|
4
|
+
dependency graph from live state, and delivers each via the single
|
|
5
|
+
deliver-story engine — story-<id> → PR → main.
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# /deliver <storyId...>
|
|
8
|
+
# /deliver <storyId...>
|
|
9
9
|
|
|
10
10
|
## Role
|
|
11
11
|
|
|
12
|
-
Single delivery path
|
|
13
|
-
every Story runs
|
|
14
|
-
[`helpers/deliver-story.md`](helpers/deliver-story.md)
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
Single delivery path with a single input shape: **a list of Story ids**.
|
|
13
|
+
`/deliver` owns input resolution and sequencing only — every Story runs
|
|
14
|
+
through [`helpers/deliver-story.md`](helpers/deliver-story.md). There is no
|
|
15
|
+
Epic wave loop, no `epic/<id>` integration branch, and no `--no-ff` wave
|
|
16
|
+
merges.
|
|
17
|
+
|
|
18
|
+
The dependency graph is **discovered, not declared**: `resolve-stories.js`
|
|
19
|
+
reads it from live state (body edges ∪ native GitHub `blocked_by` edges,
|
|
20
|
+
with every blocker resolved against its real issue state). You never hand it
|
|
21
|
+
a graph, and there is no batch label — which is what lets you deliver
|
|
22
|
+
Stories **across plan runs and over time**: a Story whose blocker landed
|
|
23
|
+
weeks ago in a different run is simply ready.
|
|
17
24
|
|
|
18
25
|
## Inputs
|
|
19
26
|
|
|
20
27
|
| Invocation | Behavior |
|
|
21
28
|
| --- | --- |
|
|
22
29
|
| `/deliver <storyId>` | Deliver one Story via `helpers/deliver-story.md`. |
|
|
23
|
-
| `/deliver <storyId> <storyId> ...` |
|
|
24
|
-
|
|
30
|
+
| `/deliver <storyId> <storyId> ...` | Resolve the set with `resolve-stories.js`, then sequence by the discovered graph via `stories-wave-tick.js`. Default concurrency is **3**. |
|
|
31
|
+
|
|
32
|
+
Any named ticket that is not `type::story`, or that still carries an
|
|
33
|
+
`Epic: #N` footer, is a hard error naming the id and the fix (close or
|
|
34
|
+
re-plan as a v2 Story). Resolution refuses the whole set rather than
|
|
35
|
+
silently dropping the offending id and under-delivering.
|
|
25
36
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
37
|
+
> **Retired (Story #4540).** `--run <planRunId>` and the `plan-run::<id>`
|
|
38
|
+
> label are gone, along with `--dep`. Batch identity was the wrong axis:
|
|
39
|
+
> it could not express an edge to a Story planned in another run, while
|
|
40
|
+
> ordering already lives in the dependency edges themselves. Deliver the
|
|
41
|
+
> ids; the graph resolves itself.
|
|
29
42
|
|
|
30
43
|
## Flags
|
|
31
44
|
|
|
32
45
|
| Flag | Meaning |
|
|
33
46
|
| --- | --- |
|
|
34
|
-
| `--run <planRunId>` | Deliver every Story in the plan-run (label `plan-run::<id>`). |
|
|
35
|
-
| `--dep <from>:<to>` | Extra operator dependency edge (Story id → Story id). |
|
|
36
47
|
| `--concurrency <n>` | Ready-set fan-out cap (default **3** from `delivery.deliverRunner.concurrencyCap`; set `1` for sequential). |
|
|
37
48
|
| `--yes` | Suppress the multi-Story confirmation gate. |
|
|
38
49
|
| `--steal` | Forwarded to `single-story-init.js` / lease steal. |
|
|
39
|
-
| `--wait-merge` | Force close-and-land (default
|
|
50
|
+
| `--wait-merge` | Force close-and-land (the default; `delivery.routing.closeAndLand`, default `true`). |
|
|
40
51
|
| `--no-wait-merge` | Opt out of close-and-land; stop at `agent::closing` for a human land. |
|
|
41
52
|
|
|
42
|
-
|
|
53
|
+
**Operator-merge implies no-wait.** `--no-auto-merge` and
|
|
54
|
+
`delivery.ci.autoMerge: "strict"` deliberately leave the PR un-armed, so
|
|
55
|
+
there is nothing for close to land: the Story rests at `agent::closing` for
|
|
56
|
+
the human merge, and is **not** flipped to `agent::blocked`. An explicit
|
|
57
|
+
`--wait-merge` does not override this — close cannot land a PR that was
|
|
58
|
+
never armed. A genuine *arm failure* is different: it still waits and still
|
|
59
|
+
blocks, because that is a fault to report rather than an operator decision
|
|
60
|
+
to respect.
|
|
43
61
|
|
|
44
|
-
|
|
45
|
-
- Positional IDs → use them.
|
|
46
|
-
- `--run <planRunId>` →
|
|
62
|
+
## Procedure
|
|
47
63
|
|
|
48
|
-
|
|
49
|
-
node .agents/scripts/resolve-plan-run.js --run <planRunId>
|
|
50
|
-
```
|
|
64
|
+
1. **Resolve the set.** One command, for one Story or many:
|
|
51
65
|
|
|
52
|
-
|
|
53
|
-
|
|
66
|
+
```bash
|
|
67
|
+
node .agents/scripts/resolve-stories.js --ids <id,id,...>
|
|
68
|
+
```
|
|
54
69
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
70
|
+
This validates the set and shows the operator what will run: read
|
|
71
|
+
`stories[]`, `dag[]`, and `done[]` to present the order in step 2. You do
|
|
72
|
+
**not** thread them into step 3 — the tick re-resolves the graph itself
|
|
73
|
+
from the same machinery, every beat. Do **not** rebuild the graph by hand;
|
|
74
|
+
it is discovered from live state, including edges a body does not spell
|
|
75
|
+
out and blockers outside the delivered set.
|
|
58
76
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
77
|
+
Resolution hard-errors (exit 1) on a named id that is not a Story, still
|
|
78
|
+
carries an `Epic: #N` footer, or whose native dependency edges cannot be
|
|
79
|
+
read. A failed edge read is fatal by design: a missing gate would
|
|
80
|
+
co-dispatch a Story against an unlanded blocker.
|
|
62
81
|
|
|
63
|
-
|
|
82
|
+
2. **Confirm (N>1).** Present the order and wait unless `--yes`.
|
|
64
83
|
|
|
65
|
-
|
|
84
|
+
3. **Sequence.** Loop until the tick reports `epilogueDue: true`:
|
|
66
85
|
|
|
67
86
|
```bash
|
|
68
87
|
node .agents/scripts/stories-wave-tick.js \
|
|
69
|
-
--
|
|
88
|
+
--stories <id,id,...> --probe-live --concurrency <n> \
|
|
89
|
+
--dispatched <every id you have dispatched so far>
|
|
70
90
|
```
|
|
71
91
|
|
|
92
|
+
Each beat re-probes live state: it re-resolves the graph, classifies done
|
|
93
|
+
(`agent::done` or a closed issue — including foreign blockers that landed
|
|
94
|
+
in another run), and derives in-flight from live `agent::executing` /
|
|
95
|
+
`agent::closing` labels. You never compute `done` or `in-flight` — that
|
|
96
|
+
accounting is read from reality every beat (Story #4594).
|
|
97
|
+
|
|
98
|
+
**`--dispatched` is the one thing you must tell it (Story #4601).** List
|
|
99
|
+
every Story id you have spawned this run. Live state cannot report a Story
|
|
100
|
+
you dispatched ninety seconds ago: `single-story-init.js` flips
|
|
101
|
+
`agent::executing` at step 6 of 6, *after* a 3–6 minute worktree install,
|
|
102
|
+
so until then the Story still reads `agent::ready` and the next beat hands
|
|
103
|
+
it back — a second sub-agent then joins the first on the same branch and
|
|
104
|
+
worktree, interleaving commits.
|
|
105
|
+
|
|
106
|
+
The rule is **append-only: add each id as you dispatch it and never remove
|
|
107
|
+
one.** The flag is additive, not authoritative — the probe unions it into
|
|
108
|
+
the label-derived set and then filters it against live state, so an id that
|
|
109
|
+
has since gone `agent::done` is dropped for you. Re-listing an id costs
|
|
110
|
+
nothing and cannot double-count a slot; *omitting* one is the only way to
|
|
111
|
+
get this wrong. This is why `--dispatched` is not the `--done` bookkeeping
|
|
112
|
+
#4594 retired, and why `--in-flight` remains rejected under `--probe-live`.
|
|
113
|
+
|
|
114
|
+
Branch on the exit code:
|
|
115
|
+
- **0** — dispatch each `ready` id (the set is already capped and
|
|
116
|
+
overlap-free). An empty `ready` with work in flight means "waiting";
|
|
117
|
+
keep looping. `epilogueDue: true` means every Story is done — leave the
|
|
118
|
+
loop and go to step 4.
|
|
119
|
+
- **2** — `cycleError`: the graph is self-referential. Fix the
|
|
120
|
+
`depends_on` declarations; do not retry.
|
|
121
|
+
- **3** — `wedged`: nothing is dispatchable, nothing is in flight, and
|
|
122
|
+
undone Stories are waiting on blockers that are not done. The envelope
|
|
123
|
+
names the stuck ids and their unmet blockers. Either land the blocker
|
|
124
|
+
first or include it in `--ids`. Do not retry unchanged — the state
|
|
125
|
+
cannot improve on its own.
|
|
126
|
+
- **4** — `blocked`: one or more Stories carry `agent::blocked`, named in
|
|
127
|
+
`blocked[]` with `blockedReason`. This is the protocol's HITL pause
|
|
128
|
+
([`instructions.md` § 1.J](../instructions.md)) — **stop the loop and
|
|
129
|
+
surface it to the operator; do not poll.** No beat can clear it, because
|
|
130
|
+
a human owes a decision. Read the Story's friction comment, and resume
|
|
131
|
+
only once the operator has unblocked it:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
gh issue view <id> --comments
|
|
135
|
+
node .agents/scripts/update-ticket-state.js --ticket <id> --state agent::ready
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
A blocked Story outranks a wedge (its blockers are moot while a human
|
|
139
|
+
owes a decision) but not a cycle (exit 2 — fix the graph first).
|
|
140
|
+
|
|
72
141
|
For each `ready` Story id, read
|
|
73
142
|
[`helpers/deliver-story.md`](helpers/deliver-story.md) **in full** and
|
|
74
143
|
execute it (init → implement → ceremony → close-and-land). Under
|
|
75
144
|
`--yes` / injected helper content, execute directly without a re-read
|
|
76
145
|
turn.
|
|
77
146
|
|
|
78
|
-
|
|
147
|
+
4. **Per-run epilogue (N>1).** Once step 3 reports `epilogueDue: true`
|
|
148
|
+
(every Story done), keyed on the delivered id set:
|
|
79
149
|
|
|
80
150
|
```bash
|
|
81
|
-
# Plan-run label path:
|
|
82
|
-
node .agents/scripts/plan-run-epilogue.js --run <planRunId>
|
|
83
|
-
|
|
84
|
-
# Positional multi-Story path (synthesizes an adhoc planRunId):
|
|
85
151
|
node .agents/scripts/plan-run-epilogue.js --stories 101,102
|
|
86
152
|
```
|
|
87
153
|
|
|
@@ -112,21 +178,43 @@ to `main`.
|
|
|
112
178
|
## Ceremony (profiles + two scopes)
|
|
113
179
|
|
|
114
180
|
Ceremony depth is selected by `delivery.routing.ceremonyProfile`
|
|
115
|
-
(`minimal` | `standard` | `strict`, default `standard`) and the
|
|
116
|
-
|
|
181
|
+
(`minimal` | `standard` | `strict`, default `standard`) and the **change
|
|
182
|
+
level derived from the Story's own diff** — the changed files' intersection
|
|
183
|
+
with the sensitive-path classes in `audit-rules.json`
|
|
184
|
+
(`review-depth.js#deriveChangeLevel`), not a planner-authored verdict
|
|
185
|
+
(Story #4542):
|
|
117
186
|
|
|
118
187
|
| Profile | Acceptance critic | When to use |
|
|
119
188
|
| --- | --- | --- |
|
|
120
189
|
| `minimal` | Always inline | Tiny trusted N=1 Stories |
|
|
121
|
-
| `standard` |
|
|
190
|
+
| `standard` | Derived-level routed (+ sampling floor) | Default |
|
|
122
191
|
| `strict` | Always fresh-context | High-assurance / regulated surfaces |
|
|
123
192
|
|
|
124
193
|
| Scope | What runs | Mechanism |
|
|
125
194
|
| --- | --- | --- |
|
|
126
195
|
| **Per-Story (always)** | Gates, branch discipline, close-and-land | `deliver-story` / `single-story-close` |
|
|
127
|
-
| **Per-Story (profile +
|
|
196
|
+
| **Per-Story (profile + derived level)** | Acceptance critic mode; review depth | `ceremony-routing.js` + `review-depth.js` + `code-review.js` |
|
|
128
197
|
| **Per-run (N>1)** | Audit roster · follow-up roll-up · sibling coherence | `plan-run-epilogue.js` once at run end |
|
|
129
|
-
| **Per-Story land** |
|
|
198
|
+
| **Per-Story land tail** | Follow-up capture · status resync · ref cleanup · base fast-forward | `single-story-close/phases/post-land.js` (in-process, per-step reported) |
|
|
199
|
+
|
|
200
|
+
## Reading a Story's outcome
|
|
201
|
+
|
|
202
|
+
Each Story's delivery ends in exactly one schema-validated terminal envelope
|
|
203
|
+
([`story-deliver-terminal.schema.json`](../schemas/story-deliver-terminal.schema.json),
|
|
204
|
+
Story #4543) — `landed` | `pending` | `blocked` | `failed`. That schema is the
|
|
205
|
+
SSOT for the shape; this workflow does not restate its fields.
|
|
206
|
+
|
|
207
|
+
`pending` is **not** a failure: the bounded merge wait expired with the PR
|
|
208
|
+
healthy and in flight (or a human owns the merge), nothing was mutated, and
|
|
209
|
+
the envelope's `nextCommand` names what resumes it. Run that command rather
|
|
210
|
+
than re-dispatching the Story.
|
|
211
|
+
|
|
212
|
+
For a Story in an unclear state — including the merged-but-label-stale one a
|
|
213
|
+
`/deliver` re-run refuses outright — probe it read-only:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
node .agents/scripts/deliver-recover.js --story <storyId>
|
|
217
|
+
```
|
|
130
218
|
|
|
131
219
|
## Constraints
|
|
132
220
|
|
|
@@ -24,7 +24,7 @@ confirmation:
|
|
|
24
24
|
already gone (or never existed) but whose `origin/<branch>` still
|
|
25
25
|
points at a merged PR — even without `--remote`; `--remote` is still
|
|
26
26
|
required to *delete* them. A third branch, whose content already
|
|
27
|
-
landed in `<base>` by another route (a squash-merged
|
|
27
|
+
landed in `<base>` by another route (a squash-merged PR, a
|
|
28
28
|
cherry-pick, a manual `merge --squash`), is caught by a
|
|
29
29
|
**content-equivalence probe** (`git merge-tree --write-tree`,
|
|
30
30
|
git ≥ 2.38) even when it has no merged PR of its own and is not a
|
|
@@ -40,7 +40,7 @@ passed, **all four phases run** sequentially. Pass any of
|
|
|
40
40
|
narrow the run.
|
|
41
41
|
|
|
42
42
|
> **When to run**: After a session that landed several PRs, or before
|
|
43
|
-
> starting a new
|
|
43
|
+
> starting a new Story, to put the local checkout into a known
|
|
44
44
|
> tidy state.
|
|
45
45
|
>
|
|
46
46
|
> **Persona**: `devops-engineer` · **Skills**:
|
|
@@ -10,7 +10,7 @@ description: >-
|
|
|
10
10
|
# /git-deliver [Message] [--no-push] [--pr] [--draft] [--no-auto-merge] [--branch <name>] [--base <branch>]
|
|
11
11
|
|
|
12
12
|
The **single source of truth** for getting outstanding working-tree changes
|
|
13
|
-
out the door when they do not belong to a planned
|
|
13
|
+
out the door when they do not belong to a planned Story (typo fixes, doc
|
|
14
14
|
tweaks, dependency bumps, operator housekeeping, benchmark result commits
|
|
15
15
|
from mandrel-bench's `/benchmark` Step 4). It is the ad-hoc counterpart to
|
|
16
16
|
the heavyweight `/deliver` pipeline: one command that **detects the git
|
|
@@ -13,8 +13,10 @@ description: >-
|
|
|
13
13
|
> only its wrapper (Story label transitions).
|
|
14
14
|
|
|
15
15
|
After the implementation commits land and **before** the Story proceeds to
|
|
16
|
-
close, run an explicit, **independent** eval pass that scores the
|
|
17
|
-
|
|
16
|
+
close, run an explicit, **independent** eval pass that scores the change set
|
|
17
|
+
computed once for this Story and injected into the critic — never one the
|
|
18
|
+
critic re-derives (Story #4593) — against **each** `acceptance[]` item
|
|
19
|
+
individually. This is the acceptance gate
|
|
18
20
|
the close-validation chain does not provide: that chain (lint / test / format /
|
|
19
21
|
maintainability / coverage / crap) proves the code is *healthy*, not that it
|
|
20
22
|
satisfies *this Story's* acceptance criteria.
|
|
@@ -33,7 +35,7 @@ mid-delivery, and evaluates the actual work product.
|
|
|
33
35
|
continuation of your implementing turn — so the evaluator does not grade its
|
|
34
36
|
own homework.
|
|
35
37
|
|
|
36
|
-
> **Sub-agent type +
|
|
38
|
+
> **Sub-agent type + derived-level ceremony (Epic #4478, M7-B).** When
|
|
37
39
|
> `delivery.routing.roleScopedAgents` is enabled (the **default**), dispatch
|
|
38
40
|
> the critic with `subagent_type: acceptance-critic` — it boots on the
|
|
39
41
|
> role-scoped [`acceptance-critic`](../../agents/acceptance-critic.md) context
|
|
@@ -42,20 +44,31 @@ mid-delivery, and evaluates the actual work product.
|
|
|
42
44
|
> kill-switch is **off** (`roleScopedAgents: false`), fall back to
|
|
43
45
|
> `subagent_type: general-purpose`.
|
|
44
46
|
>
|
|
45
|
-
> **Whether to spawn fresh at all is
|
|
46
|
-
>
|
|
47
|
-
> `
|
|
47
|
+
> **Whether to spawn fresh at all is routed off the derived change level**
|
|
48
|
+
> — the same signal `review-depth.js` resolves depth from, so the two
|
|
49
|
+
> decisions cannot disagree. Derive it with `deriveChangeLevel` from
|
|
50
|
+
> [`review-depth.js`](../../scripts/lib/orchestration/review-depth.js) over
|
|
51
|
+
> the **change set your caller computed once** for this Story (Story #4593 —
|
|
52
|
+
> `computeChangeSet` from
|
|
53
|
+
> [`change-set.js`](../../scripts/lib/orchestration/change-set.js); see
|
|
54
|
+
> [`deliver-story.md`](deliver-story.md) Step 2), then
|
|
55
|
+
> resolve the ceremony per cluster with `resolveCeremonyForRisk` from
|
|
48
56
|
> [`ceremony-routing.js`](../../scripts/lib/orchestration/ceremony-routing.js)
|
|
49
|
-
> using
|
|
50
|
-
> `
|
|
51
|
-
>
|
|
52
|
-
> `inline`** (the contract-identical inline fallback below),
|
|
53
|
-
> `freshCriticSampleRate` fraction of low-
|
|
54
|
-
> forces `fresh` so low
|
|
55
|
-
> / unknown
|
|
56
|
-
> fresh-vs-inline **per cluster
|
|
57
|
+
> using that `derivedLevel` and `delivery.routing.freshCriticSampleRate`:
|
|
58
|
+
> **`high` (the diff touches a sensitive path registered in
|
|
59
|
+
> `audit-rules.json`) → `fresh`** (spawn the critic); **`low` (it touches
|
|
60
|
+
> none) → `inline`** (the contract-identical inline fallback below),
|
|
61
|
+
> **except** the `freshCriticSampleRate` fraction of low-level clusters the
|
|
62
|
+
> sampling floor forces `fresh` so a low level never means zero independent
|
|
63
|
+
> checking; **`null` / unknown (the diff could not be enumerated) → `fresh` +
|
|
64
|
+
> full ceremony** (fail-safe). This chooses fresh-vs-inline **per cluster
|
|
65
|
+
> only — it never changes the cluster count**.
|
|
57
66
|
>
|
|
58
|
-
>
|
|
67
|
+
> Story #4542 re-based this off the planner-authored risk verdict: a level
|
|
68
|
+
> the plan asserted about itself was exactly the signal that could *reduce*
|
|
69
|
+
> independent checking, and nothing verified it against the diff.
|
|
70
|
+
>
|
|
71
|
+
> **Inline-critic path (low-level-routed OR nesting-absent harness).** The
|
|
59
72
|
> verdict is authored **inline** whenever the risk router above resolves to
|
|
60
73
|
> `inline` (a low-risk cluster not caught by the sampling floor), and also as
|
|
61
74
|
> a **fallback** on any harness that cannot spawn the fresh critic.
|
|
@@ -79,8 +92,12 @@ mid-delivery, and evaluates the actual work product.
|
|
|
79
92
|
> comment (if you block) that the inline fallback was used.
|
|
80
93
|
|
|
81
94
|
The critic:
|
|
82
|
-
- Inspects the
|
|
83
|
-
Story's inline `acceptance[]` / `verify[]`
|
|
95
|
+
- Inspects the **change set handed to it in its spawn context** — the one
|
|
96
|
+
list computed above — and the Story's inline `acceptance[]` / `verify[]`
|
|
97
|
+
arrays. Pass the file list explicitly when you dispatch the critic; it
|
|
98
|
+
does not re-enumerate the diff for itself (Story #4593), so a commit
|
|
99
|
+
landing mid-ceremony cannot leave the critic scoring a different change
|
|
100
|
+
than the one that routed it.
|
|
84
101
|
- **Runs the `verify[]` commands** and consumes their output as **required
|
|
85
102
|
evidence** when scoring the relevant acceptance items. `verify[]` is not
|
|
86
103
|
optional advisory pre-flight — a criterion cannot be scored `met` without
|
|
@@ -15,8 +15,10 @@ read the same numbers from here so a "high cyclomatic complexity" finding in
|
|
|
15
15
|
|
|
16
16
|
Run [`npm run quality:preview`](../../../package.json) before committing
|
|
17
17
|
on any Story that touches production source. The preview runs
|
|
18
|
-
`quality-preview.js
|
|
19
|
-
|
|
18
|
+
`quality-preview.js`, which scopes the diff to `HEAD` by default (the
|
|
19
|
+
alias passes no `--changed-since`; the script defaults to `HEAD`) and
|
|
20
|
+
exercises the same maintainability and CRAP engines (`escomplex` +
|
|
21
|
+
`c8` coverage) that
|
|
20
22
|
`check-baselines.js` enforces at merge time, then merges the results
|
|
21
23
|
into a single per-file delta table. A clean preview means the commit
|
|
22
24
|
will not bounce off the unified baselines gate. The `.husky/pre-commit`
|
|
@@ -58,16 +60,17 @@ review-time prose rule.
|
|
|
58
60
|
|
|
59
61
|
Per-file Maintainability Index (MI) is tracked in
|
|
60
62
|
[`baselines/maintainability.json`](../../../baselines/maintainability.json).
|
|
61
|
-
A commit that drops a file's MI by more than
|
|
62
|
-
`delivery.quality.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
`quality:preview
|
|
70
|
-
|
|
63
|
+
A commit that drops a file's MI by more than the configured
|
|
64
|
+
`delivery.quality.gates.maintainability.tolerance` (default `0.5` points)
|
|
65
|
+
requires a refactor in the same Story — not a baseline bump. `tolerance` is
|
|
66
|
+
the single MI-drop control: it is not a noise filter beneath a separate
|
|
67
|
+
must-refactor ceiling — any drop past it is treated as a regression that
|
|
68
|
+
must be undone or offset, not absorbed. Set `tolerance` higher only when the
|
|
69
|
+
project deliberately wants a looser MI-drop budget.
|
|
70
|
+
|
|
71
|
+
`quality:preview` shows the per-file MI delta in the working tree before
|
|
72
|
+
the commit lands (scoped to `HEAD` by default — the alias passes no
|
|
73
|
+
`--changed-since`; the script defaults to `HEAD`).
|
|
71
74
|
|
|
72
75
|
## Rename = baseline-refresh
|
|
73
76
|
|
|
@@ -30,7 +30,7 @@ the change set is reviewed by a process the maker cannot influence. The
|
|
|
30
30
|
enforcing code path is
|
|
31
31
|
[`runStoryScopeReview`](../../scripts/lib/orchestration/single-story-close/phases/code-review.js)
|
|
32
32
|
→ shared
|
|
33
|
-
[`runStoryReviewCore`](../../scripts/lib/orchestration/story-close/phases/
|
|
33
|
+
[`runStoryReviewCore`](../../scripts/lib/orchestration/story-close/phases/review-core.js).
|
|
34
34
|
A future refactor MUST preserve this isolation: do not move Story-scope
|
|
35
35
|
review into the maker's context or run it as a step of the delivering
|
|
36
36
|
child.
|
|
@@ -57,14 +57,16 @@ the argument envelope.
|
|
|
57
57
|
|
|
58
58
|
### Review depth (`depth`)
|
|
59
59
|
|
|
60
|
-
`depth` is the
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
`
|
|
66
|
-
|
|
67
|
-
|
|
60
|
+
`depth` is the thoroughness lever introduced by Story #3876, made a live
|
|
61
|
+
consumed signal end to end by Story #3937, and re-based on an observable signal
|
|
62
|
+
by Story #4542. `runCodeReview` derives it from the diff it already enumerates,
|
|
63
|
+
via [`review-depth.js`](../../scripts/lib/orchestration/review-depth.js): the
|
|
64
|
+
changed files' intersection with the `sensitivePaths` classes registered in
|
|
65
|
+
`audit-rules.json` gives the level, their count gives the width, and
|
|
66
|
+
`resolveDepth` folds the two (a sensitive path OR a wide diff → `deep`; neither,
|
|
67
|
+
on a small diff → `light`; an unenumerable diff → `standard`). It takes no
|
|
68
|
+
planner-authored input and reads no checkpoint. `runCodeReview` forwards `depth`
|
|
69
|
+
to every provider's `runReview` input.
|
|
68
70
|
|
|
69
71
|
It is an **input-only** signal: it changes *how thorough* the review is, never
|
|
70
72
|
the findings envelope (`{ status, severity, posted, report, halted,
|
|
@@ -97,7 +99,7 @@ review yourself, honor the `depth` semantics above directly.
|
|
|
97
99
|
2. Resolve `[BASE_REF]` from `baseRef` and `[HEAD_REF]` from `headRef`.
|
|
98
100
|
3. Fetch the Story ticket and resolve the planning context from its own
|
|
99
101
|
body: folded `## Spec` / `## Slicing`, acceptance criteria, and the
|
|
100
|
-
`story-plan-state`
|
|
102
|
+
`story-plan-state` structured comment when present.
|
|
101
103
|
4. Read that Spec fully to understand the intended scope, architectural
|
|
102
104
|
decisions, and acceptance criteria. Do **not** look for a parent Epic.
|
|
103
105
|
|
|
@@ -120,7 +122,7 @@ The pipeline will:
|
|
|
120
122
|
### Step 1a — Story-scope local-lens pass (`scope: story` only, Epic #4405)
|
|
121
123
|
|
|
122
124
|
When `scope === 'story'`, the shared review spine
|
|
123
|
-
[`runStoryReviewCore`](../../scripts/lib/orchestration/story-close/phases/
|
|
125
|
+
[`runStoryReviewCore`](../../scripts/lib/orchestration/story-close/phases/review-core.js)
|
|
124
126
|
runs a **shift-left local-lens pass** in the same close subprocess, *before*
|
|
125
127
|
returning the review envelope. It:
|
|
126
128
|
|
|
@@ -376,7 +378,7 @@ in-place.
|
|
|
376
378
|
structured comment for the operator to triage in Step 5.
|
|
377
379
|
2. **Leave the finding on the structured comment for Step 5.** Required
|
|
378
380
|
when the finding falls into any of the following classes:
|
|
379
|
-
- `spec-deviation` — the change diverges from the
|
|
381
|
+
- `spec-deviation` — the change diverges from the Story `## Spec`.
|
|
380
382
|
- `secrets` — credentials, tokens, or PII surfaced in the diff.
|
|
381
383
|
- `test-deletion` — coverage was removed without an explicit
|
|
382
384
|
decision in the spec.
|
|
@@ -161,9 +161,11 @@ The `single-story-close.js` script, in order:
|
|
|
161
161
|
would strand a CLOSED issue with no merged work if the PR later failed
|
|
162
162
|
CI, went `BEHIND` base, or was closed without merging. The Story rests
|
|
163
163
|
at `agent::closing` while the PR is open with auto-merge armed; the
|
|
164
|
-
`agent::done` flip (which closes the issue) is deferred to Step 5
|
|
165
|
-
`single-story-confirm-merge.js
|
|
166
|
-
|
|
164
|
+
`agent::done` flip (which closes the issue) is deferred to Step 5's
|
|
165
|
+
merge confirmation — `single-story-confirm-merge.js` on a
|
|
166
|
+
`--no-wait-merge` run, or the in-close confirm phase on the
|
|
167
|
+
close-and-land default. (Step 5.5 is the Status-column resync.) A Story
|
|
168
|
+
only reaches `agent::done` once its PR to `main` is confirmed merged.
|
|
167
169
|
5. Reaps the worktree when `delivery.worktreeIsolation.reapOnSuccess`
|
|
168
170
|
is enabled.
|
|
169
171
|
6. **Releases the Story lease** (Story #3483). Clears the Story assignment
|
|
@@ -171,8 +173,12 @@ The `single-story-close.js` script, in order:
|
|
|
171
173
|
unclaimed ticket. The release is a no-op when the operator no longer
|
|
172
174
|
holds the claim (a later run took over via reclaim/steal), so a late
|
|
173
175
|
close never yanks a live claim away from its current owner. Best-effort:
|
|
174
|
-
a release failure is logged but does not fail an otherwise-clean close
|
|
175
|
-
the lease
|
|
176
|
+
a release failure is logged but does not fail an otherwise-clean close.
|
|
177
|
+
Note the lease does **not** expire on its own: the standalone lease is
|
|
178
|
+
fail-closed by design (it anchors its heartbeat to now, so a foreign
|
|
179
|
+
claim always reads as live regardless of the configured TTL), so a
|
|
180
|
+
claim stranded by a failed release is cleared only by `--steal` or by
|
|
181
|
+
de-assigning the ticket. The close result carries
|
|
176
182
|
`leaseReleased: <boolean>`.
|
|
177
183
|
|
|
178
184
|
`--skip-validation` bypasses Step 1 (gates). Use only when re-running
|
|
@@ -289,9 +295,8 @@ when `--pr` is omitted) and:
|
|
|
289
295
|
- **Story already `agent::done` / issue already closed** → idempotent
|
|
290
296
|
`{ action: 'noop', reason: 'already-done' }`.
|
|
291
297
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
exactly when the work has merged, never at PR-open.
|
|
298
|
+
The issue closes exactly when the work has merged, never at PR-open
|
|
299
|
+
(#2155).
|
|
295
300
|
|
|
296
301
|
---
|
|
297
302
|
|
|
@@ -386,33 +391,69 @@ up").
|
|
|
386
391
|
|
|
387
392
|
## Step 7 — Return-contract detail
|
|
388
393
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
394
|
+
The field-level contract is the shipped schema
|
|
395
|
+
[`story-deliver-terminal.schema.json`](../../schemas/story-deliver-terminal.schema.json)
|
|
396
|
+
(Story #4543) — not this file, and not
|
|
397
|
+
[`agents/story-worker.md`](../../agents/story-worker.md). All three used to
|
|
398
|
+
carry their own prose version; the schema is now the only definition. What
|
|
399
|
+
follows is the *judgement* around it, which a schema cannot express.
|
|
400
|
+
|
|
401
|
+
### `pending` is a real status — and it is not a park
|
|
402
|
+
|
|
403
|
+
Earlier revisions asserted "the auto-merge wait does not produce a fourth
|
|
404
|
+
status", on the reasoning that the wait is internally blocking so a run either
|
|
405
|
+
merges or blocks. That was true only while the wait was unbounded — and it was
|
|
406
|
+
never actually unbounded, because the host kills a tool invocation at ~10
|
|
407
|
+
minutes. So a close-and-land whose CI outlived that ceiling took **no**
|
|
408
|
+
terminal path at all: no event, no label, the Story parked at
|
|
409
|
+
`agent::closing`. The status the model refused to name was the one that kept
|
|
410
|
+
happening.
|
|
411
|
+
|
|
412
|
+
`pending` names it, with its own exit code (3):
|
|
413
|
+
|
|
414
|
+
- It is **resumable**: no label was mutated, no `merge.unlanded` was emitted,
|
|
415
|
+
and `nextCommand` names the one command that continues it. The cumulative
|
|
416
|
+
budget is anchored at the PR's `createdAt`, so resuming does not restart the
|
|
417
|
+
clock and the give-up bound still means something.
|
|
418
|
+
- It is **not** a park. Returning `pending` because you would rather not wait
|
|
419
|
+
is the Story #1553 / PR #1554 failure mode wearing a schema. Return it only
|
|
420
|
+
when the bound genuinely expired, or a human owns the merge.
|
|
421
|
+
|
|
422
|
+
The no-park rule is therefore unchanged in substance: a turn that ends with
|
|
423
|
+
prose ("I'll wait for the watch task…", "the next event will be its
|
|
424
|
+
completion notification…") and an unconfirmed merge is a **contract
|
|
425
|
+
violation** — the parent cannot distinguish "still working" from "done but
|
|
426
|
+
silent". What changed is that there is now an honest, machine-readable way to
|
|
427
|
+
say "not finished, here is exactly how to continue" instead of a choice
|
|
428
|
+
between lying and blocking forever.
|
|
429
|
+
|
|
430
|
+
### Exit-code compatibility note (`--no-wait-merge`)
|
|
431
|
+
|
|
432
|
+
Every close flag keeps its meaning, but the **exit code** of a
|
|
433
|
+
`--no-wait-merge` (or `--no-auto-merge` / `autoMerge: "strict"`) run changed:
|
|
434
|
+
it now exits **3** (`pending`) rather than 0, because the PR is open and a
|
|
435
|
+
human still owns the merge. Reporting `landed` would be a lie, and `landed` is
|
|
436
|
+
what exit 0 means. A wrapper that shells out and tests `exit == 0` to mean
|
|
437
|
+
"close finished" must be updated to treat 3 as the operator-merge success
|
|
438
|
+
path; `!= 0` no longer implies failure.
|
|
439
|
+
|
|
440
|
+
### Per-status judgement
|
|
441
|
+
|
|
442
|
+
- **`landed`** — the only status that means done. A `false` in `tail.*`
|
|
443
|
+
degrades the report, never the land: the merge is on the base branch, and
|
|
444
|
+
failing it because a Projects v2 mutation flaked would report a false
|
|
445
|
+
negative about work that demonstrably shipped.
|
|
446
|
+
- **`pending`** — see above.
|
|
447
|
+
- **`blocked`** — you (or the close pipeline) transitioned the Story to
|
|
448
|
+
`agent::blocked` and posted a `friction` comment. `blocked.blockClass` comes
|
|
449
|
+
from the shared classifier, never an ad hoc string, and
|
|
450
|
+
`blocked.frictionCommentId` points at the remediation.
|
|
451
|
+
- **`failed`** — an unrecoverable failure outside the blocked protocol.
|
|
452
|
+
`phase` reflects where it died.
|
|
412
453
|
|
|
413
454
|
> **Handoff discipline — report state, not process.** Populate the envelope
|
|
414
455
|
> with essential terminal state only (mirroring the fields
|
|
415
|
-
> `single-story-close.js`
|
|
456
|
+
> `single-story-close.js` already emits). Do not narrate the
|
|
416
457
|
> steps you took, and do not prescribe how the next stage should work. Prose
|
|
417
458
|
> process commentary only bloats the hydrated prompt. When run **interactively** (no parent
|
|
418
459
|
> aggregator), this JSON envelope is optional — relay terminal state to the
|