mandrel 2.24.0 → 2.26.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/agents/acceptance-critic.md +19 -21
- package/.agents/agents/auditor.md +16 -19
- package/.agents/agents/story-worker.md +41 -54
- package/.agents/audit-checklists/architecture.md +5 -1
- package/.agents/audit-checklists/baselines.md +21 -0
- package/.agents/audit-checklists/quality.md +3 -0
- package/.agents/docs/agentrc-reference.json +2 -1
- package/.agents/docs/configuration.md +2 -1
- package/.agents/docs/quality-gates.md +80 -18
- package/.agents/docs/workflows.md +4 -2
- package/.agents/instructions.md +1 -1
- package/.agents/rules/ci-remediation.md +68 -3
- package/.agents/schemas/agentrc.schema.json +6 -1
- package/.agents/schemas/audit-rules.json +15 -0
- package/.agents/schemas/baselines/audit-baselines-envelope.schema.json +242 -0
- package/.agents/schemas/baselines/baseline-envelope.schema.json +8 -0
- package/.agents/schemas/baselines/crap.schema.json +13 -1
- package/.agents/schemas/crap-report.schema.json +37 -0
- package/.agents/schemas/model-attribution.schema.json +4 -0
- package/.agents/scripts/acceptance-eval.js +124 -15
- package/.agents/scripts/audit-baselines.js +136 -0
- package/.agents/scripts/audit-labels-bootstrap.js +16 -95
- package/.agents/scripts/audit-to-stories.js +33 -3
- package/.agents/scripts/check-arch-cycles.js +12 -93
- package/.agents/scripts/check-baseline-drift.js +16 -3
- package/.agents/scripts/check-baselines.js +19 -3
- package/.agents/scripts/check-context-budget.js +95 -14
- package/.agents/scripts/check-cyclomatic.js +214 -0
- package/.agents/scripts/check-schema-references.js +392 -0
- package/.agents/scripts/check-test-temp-hygiene.js +121 -1
- package/.agents/scripts/check-workflow-timeouts.js +291 -0
- package/.agents/scripts/cleanup-repo-test-temp.js +7 -5
- package/.agents/scripts/deliver-light.js +3 -4
- package/.agents/scripts/deliver-recover.js +13 -0
- package/.agents/scripts/diagnose-friction.js +85 -19
- package/.agents/scripts/lib/audit-baselines/engine.js +177 -0
- package/.agents/scripts/lib/audit-baselines/gate-surface.js +63 -0
- package/.agents/scripts/lib/audit-baselines/headroom.js +72 -0
- package/.agents/scripts/lib/audit-baselines/hotspots.js +69 -0
- package/.agents/scripts/lib/audit-baselines/kinds.js +313 -0
- package/.agents/scripts/lib/audit-baselines/outliers.js +100 -0
- package/.agents/scripts/lib/audit-baselines/read.js +87 -0
- package/.agents/scripts/lib/audit-baselines/staleness.js +123 -0
- package/.agents/scripts/lib/audit-baselines/surface-entry.js +106 -0
- package/.agents/scripts/lib/audit-baselines/trend.js +125 -0
- package/.agents/scripts/lib/audit-baselines/weights.js +193 -0
- package/.agents/scripts/lib/audit-suite/index.js +0 -5
- package/.agents/scripts/lib/audit-suite/selector.js +9 -62
- package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +177 -0
- package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +1 -0
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +35 -3
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +20 -11
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +23 -9
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +9 -2
- package/.agents/scripts/lib/baseline-loader.js +0 -0
- package/.agents/scripts/lib/baseline-schema-registry.js +13 -1
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +22 -160
- package/.agents/scripts/lib/baselines/duplication-scanner.js +27 -0
- package/.agents/scripts/lib/baselines/git-base.js +0 -0
- package/.agents/scripts/lib/baselines/kinds/crap.js +499 -57
- package/.agents/scripts/lib/baselines/preview-gates.js +58 -15
- package/.agents/scripts/lib/baselines/reader.js +10 -0
- package/.agents/scripts/lib/baselines/refresh-service.js +69 -11
- package/.agents/scripts/lib/baselines/scope.js +39 -90
- package/.agents/scripts/lib/baselines/writer.js +16 -7
- package/.agents/scripts/lib/changed-files.js +8 -1
- package/.agents/scripts/lib/cli-args.js +115 -1
- package/.agents/scripts/lib/close-validation/runner.js +70 -25
- package/.agents/scripts/lib/config-settings-schema-delivery.js +5 -0
- package/.agents/scripts/lib/crap-engine.js +124 -27
- package/.agents/scripts/lib/crap-method-identity.js +153 -0
- package/.agents/scripts/lib/crap-utils.js +86 -13
- package/.agents/scripts/lib/cyclomatic-ceiling.js +265 -0
- package/.agents/scripts/lib/env-loader.js +46 -16
- package/.agents/scripts/lib/feedback-loop/audit-results-graduator.js +0 -2
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +0 -2
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +0 -2
- package/.agents/scripts/lib/findings/route-finding.js +123 -17
- package/.agents/scripts/lib/findings/severity.js +80 -2
- package/.agents/scripts/lib/git/cached-fetch.js +0 -0
- package/.agents/scripts/lib/git-utils.js +136 -80
- package/.agents/scripts/lib/import-graph.js +156 -0
- package/.agents/scripts/lib/label-constants.js +17 -0
- package/.agents/scripts/lib/observability/runtime-friction.js +17 -2
- package/.agents/scripts/lib/observability/source-classifier.js +175 -2
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +110 -17
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +17 -12
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +36 -6
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +5 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +12 -1
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +8 -1
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +548 -0
- package/.agents/scripts/lib/orchestration/deliver-recover.js +2 -2
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +10 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +39 -3
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +71 -20
- package/.agents/scripts/lib/orchestration/light-backstop.js +20 -3
- package/.agents/scripts/lib/orchestration/light-escalation.js +82 -3
- package/.agents/scripts/lib/orchestration/light-suitability.js +103 -5
- package/.agents/scripts/lib/orchestration/plan-context.js +119 -66
- package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +31 -5
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +216 -109
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +61 -13
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +79 -22
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +51 -20
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +70 -74
- package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +231 -0
- package/.agents/scripts/lib/orchestration/resolve-stories.js +18 -17
- package/.agents/scripts/lib/orchestration/retro-proposals.js +0 -0
- package/.agents/scripts/lib/orchestration/run-epilogue.js +12 -0
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +276 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +41 -10
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +125 -37
- package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +6 -6
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +42 -38
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +129 -21
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -1
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +267 -125
- package/.agents/scripts/lib/orchestration/spec-budget.js +16 -5
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +182 -95
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +22 -0
- package/.agents/scripts/lib/orchestration/ticket-validator.js +5 -11
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +4 -4
- package/.agents/scripts/lib/reserved-test-ids.js +77 -0
- package/.agents/scripts/lib/story-adjacency.js +3 -3
- package/.agents/scripts/lib/story-plan.js +137 -42
- package/.agents/scripts/lib/templates/decomposer-prompts.js +4 -4
- package/.agents/scripts/lib/test-runner-contract.js +134 -0
- package/.agents/scripts/lib/test-tiers.js +11 -2
- package/.agents/scripts/lib/ticket-body-sections.js +1 -1
- package/.agents/scripts/lib/util/concurrent-map.js +17 -0
- package/.agents/scripts/lib/util/parse-id-list.js +103 -0
- package/.agents/scripts/lib/util/poll-loop.js +18 -2
- package/.agents/scripts/lib/wave-runner/live-probe.js +29 -13
- package/.agents/scripts/lib/wave-runner/ready-set.js +254 -43
- package/.agents/scripts/lib/workers/combined-mi-crap-worker.js +10 -13
- package/.agents/scripts/lib/workers/crap-worker.js +8 -13
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +4 -10
- package/.agents/scripts/lib/workers/maintainability-worker.js +4 -10
- package/.agents/scripts/lib/workers/serve-worker-messages.js +35 -0
- package/.agents/scripts/lib/worktree/git-hooks.js +206 -0
- package/.agents/scripts/lib/worktree/lifecycle/creation.js +6 -0
- package/.agents/scripts/lib/worktree-manager.js +14 -0
- package/.agents/scripts/plan-run-epilogue.js +17 -5
- package/.agents/scripts/pr-watch-with-update.js +568 -213
- package/.agents/scripts/providers/github/tickets.js +33 -10
- package/.agents/scripts/provision-git-hooks.js +85 -0
- package/.agents/scripts/quality-preview.js +137 -28
- package/.agents/scripts/resolve-stories.js +4 -1
- package/.agents/scripts/run-coverage.js +86 -35
- package/.agents/scripts/run-lint.js +20 -0
- package/.agents/scripts/run-tests.js +36 -36
- package/.agents/scripts/single-story-close.js +34 -2
- package/.agents/scripts/single-story-confirm-merge.js +22 -6
- package/.agents/scripts/single-story-init.js +7 -0
- package/.agents/scripts/stories-wave-tick.js +308 -47
- package/.agents/scripts/story-plan.js +65 -9
- package/.agents/scripts/update-coverage-baseline.js +34 -4
- package/.agents/scripts/update-crap-baseline.js +42 -4
- package/.agents/scripts/update-duplication-baseline.js +209 -83
- package/.agents/scripts/update-maintainability-baseline.js +31 -4
- package/.agents/scripts/validate-docs-freshness.js +1 -0
- package/.agents/skills/core/diagnose-friction/SKILL.md +4 -1
- package/.agents/skills/core/gates-and-baselines/SKILL.md +17 -11
- package/.agents/skills/skills.index.json +2 -2
- package/.agents/templates/single-story-body.md +16 -8
- package/.agents/workflows/audit-architecture.md +69 -13
- package/.agents/workflows/audit-baselines.md +289 -0
- package/.agents/workflows/audit-navigability.md +5 -4
- package/.agents/workflows/audit-quality.md +26 -0
- package/.agents/workflows/audit-to-stories.md +30 -4
- package/.agents/workflows/deliver.md +92 -97
- package/.agents/workflows/helpers/acceptance-self-eval.md +47 -10
- package/.agents/workflows/helpers/audit-lens-core.md +25 -4
- package/.agents/workflows/helpers/code-quality-guardrails.md +9 -2
- package/.agents/workflows/helpers/deliver-digest.md +41 -21
- package/.agents/workflows/helpers/deliver-reference.md +95 -4
- package/.agents/workflows/helpers/deliver-story-reference.md +174 -52
- package/.agents/workflows/helpers/deliver-story.md +104 -119
- package/.agents/workflows/helpers/plan-reference.md +49 -5
- package/.agents/workflows/memory-consolidate.md +116 -0
- package/.agents/workflows/plan.md +62 -75
- package/README.md +13 -6
- package/docs/CHANGELOG.md +93 -0
- package/lib/cli/update.js +14 -11
- package/lib/cli/version-check.js +9 -1
- package/package.json +9 -4
- package/.agents/schemas/friction-event.schema.json +0 -56
- package/.agents/scripts/lib/feedback-loop/memory-freshness.js +0 -707
|
@@ -1,179 +1,164 @@
|
|
|
1
1
|
---
|
|
2
2
|
description:
|
|
3
|
-
Execute one Story end-to-end
|
|
4
|
-
|
|
5
|
-
opens a PR against main, and lands.
|
|
3
|
+
Execute one Story end-to-end: story-<id> from main, implemented in a worktree
|
|
4
|
+
(optional ## Slicing checkpoints), derived-level ceremony, PR against main.
|
|
6
5
|
mandatoryReads: [deliver-digest.md]
|
|
7
6
|
---
|
|
8
7
|
|
|
9
8
|
# /deliver-story #[Story ID]
|
|
10
9
|
|
|
11
|
-
> **Lean spine.** Happy path + gate list; edge-case, recovery
|
|
12
|
-
>
|
|
13
|
-
> [
|
|
14
|
-
>
|
|
15
|
-
>
|
|
16
|
-
> **Read [`deliver-digest.md`](deliver-digest.md) once, first.** It is the
|
|
17
|
-
> one bundled read of what every delivery needs — dispatch decision, engine
|
|
18
|
-
> invariants, the change-set/ceremony incantation, the acceptance-eval gate,
|
|
19
|
-
> and the terminal-envelope contract — replacing the per-session re-reads of
|
|
20
|
-
> the helper set and `story-deliver-terminal.schema.json`. The steps below
|
|
21
|
-
> cite it as "digest § N" rather than restating it.
|
|
10
|
+
> **Lean spine.** Happy path + gate list; edge-case, recovery and reference
|
|
11
|
+
> detail lives in [`deliver-story-reference.md`](deliver-story-reference.md)
|
|
12
|
+
> ("reference" below). Invoked by [`/deliver`](../deliver.md).
|
|
13
|
+
> **Read [`deliver-digest.md`](deliver-digest.md) once, first** — the one
|
|
14
|
+
> bundled read every delivery needs. Steps cite it as "digest § N".
|
|
22
15
|
|
|
23
16
|
## Overview
|
|
24
17
|
|
|
25
|
-
The **one** delivery engine in v2
|
|
26
|
-
goes inline with inline critics; engine, gates, envelope byte-identical):
|
|
18
|
+
The **one** delivery engine in v2:
|
|
27
19
|
|
|
28
20
|
```text
|
|
29
|
-
single-story-init.js → implement + commits → derived-level ceremony
|
|
30
|
-
|
|
21
|
+
single-story-init.js → implement + commits → derived-level ceremony → push
|
|
22
|
+
──hand-off──▶ single-story-close.js (gates, PR → main, agent::closing)
|
|
31
23
|
→ CI watch + merge → single-story-confirm-merge.js (agent::done)
|
|
32
24
|
```
|
|
33
25
|
|
|
34
|
-
An `Epic: #N` reference marks a v1 ticket — **stop** and re-plan.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
26
|
+
An `Epic: #N` reference marks a v1 ticket — **stop** and re-plan. Engine
|
|
27
|
+
traits and prerequisites: reference § Engine invariants.
|
|
28
|
+
|
|
29
|
+
## Who owns which step
|
|
30
|
+
|
|
31
|
+
Steps 0–2 belong to whoever implements. **Step 3 belongs to the orchestrator
|
|
32
|
+
that dispatched the work**, never to a spawned worker.
|
|
33
|
+
|
|
34
|
+
- **Inline dispatch** (a one-Story run — digest § 1): one session is both
|
|
35
|
+
roles and walks Steps 0→7, no hand-off.
|
|
36
|
+
- **Sub-agent dispatch**: the `story-worker` stops at Step 2.5 with the branch
|
|
37
|
+
pushed and returns a hand-off; the dispatching `/deliver` session runs Step 3
|
|
38
|
+
**in its own turn** and **serializes the tail — one close at a time across
|
|
39
|
+
the run**, even though implementation ran in parallel (reference § Step 3).
|
|
40
|
+
|
|
41
|
+
**A worker returning no terminal envelope is expected, not a failure.** Only
|
|
42
|
+
Step 3 mints one, so a hand-off is the normal sub-agent return. Never
|
|
43
|
+
re-dispatch the Story on it — the branch exists, and re-running Step 0 under
|
|
44
|
+
live work is how one Story gets two closes. Resume per § Recovery instead.
|
|
38
45
|
|
|
39
46
|
## Step 0 — Initialize (`single-story-init.js`)
|
|
40
47
|
|
|
41
|
-
From the **main checkout**, **synchronously** with the maximum Bash
|
|
42
|
-
|
|
48
|
+
From the **main checkout**, **synchronously** with the maximum Bash timeout —
|
|
49
|
+
the per-tree install can take minutes; never `run_in_background`:
|
|
43
50
|
|
|
44
51
|
```bash
|
|
45
52
|
node .agents/scripts/single-story-init.js --story <storyId>
|
|
46
53
|
```
|
|
47
54
|
|
|
48
55
|
Every script below documents its own flags — run it with `--help`.
|
|
49
|
-
It validates `type::story`,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
guarded merged-`story-*` sweep, and flips `agent::executing` (reference
|
|
53
|
-
§ Step 0). Capture `workCwd` from the result envelope.
|
|
56
|
+
It validates `type::story`, takes the Story lease, seeds `story-<id>` from
|
|
57
|
+
`baseBranch`, materializes a worktree and flips `agent::executing` (reference
|
|
58
|
+
§ Step 0). Capture `workCwd` from the envelope.
|
|
54
59
|
|
|
55
|
-
**Land or block.** `remoteVerified: false` → flip
|
|
56
|
-
`
|
|
57
|
-
|
|
58
|
-
close's push is the only sanctioned landing.
|
|
60
|
+
**Land or block.** `remoteVerified: false` → flip `agent::blocked` quoting
|
|
61
|
+
`remoteProbe.detail` and stop. Implementing outside the worktree/branch/PR path,
|
|
62
|
+
or committing to local `main`, is forbidden.
|
|
59
63
|
|
|
60
64
|
**Step 0.5 — `cd "<workCwd>"`**, and prefix every path-based
|
|
61
|
-
Edit/Write/Read with that absolute root — the `cd` alone does not
|
|
62
|
-
those tools (reference § Worktree scope
|
|
65
|
+
Edit/Write/Read with that absolute worktree root — the `cd` alone does not
|
|
66
|
+
scope those tools (reference § Worktree scope).
|
|
63
67
|
|
|
64
68
|
## Step 1 — Implementation
|
|
65
69
|
|
|
66
70
|
One branch, one PR to `main`, commits against the inline `acceptance[]` /
|
|
67
|
-
`verify[]`
|
|
68
|
-
|
|
69
|
-
1. Read the Story body;
|
|
70
|
-
digest-first; read a caller-provided `checklistPath`
|
|
71
|
-
(reference § Step 1).
|
|
72
|
-
2. Implement
|
|
73
|
-
(
|
|
74
|
-
3.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
4. Run the **full test command** once in the worktree (`npm test`) **before
|
|
78
|
-
Step 1a** — repo-invariant guards outside the Story's scoped greps are
|
|
79
|
-
the failure class that bounces deliveries. Fix and commit first.
|
|
80
|
-
5. Run the self-eval loop (Step 1a).
|
|
71
|
+
`verify[]` and `## Spec`:
|
|
72
|
+
|
|
73
|
+
1. Read the Story body; its acceptance criteria are the contract. Docs are
|
|
74
|
+
digest-first; read a caller-provided `checklistPath` first, and walk any
|
|
75
|
+
`## Slicing` rows as **intra-session checkpoints** (reference § Step 1).
|
|
76
|
+
2. Implement and commit on the Story branch, iterating with quick advisory
|
|
77
|
+
gates (`typecheck`, `lint`, scoped tests) — the full chain runs in Step 3.
|
|
78
|
+
3. Run `npm test` once in the worktree **before Step 1a**: repo-invariant
|
|
79
|
+
guards outside the Story's scoped greps are the failure class that bounces
|
|
80
|
+
deliveries. Fix and commit first, then run the self-eval loop.
|
|
81
81
|
|
|
82
82
|
### Step 1a — Bounded acceptance self-eval loop (**required**)
|
|
83
83
|
|
|
84
84
|
Run the loop and score it with `acceptance-eval.js` — **digest § 4** carries
|
|
85
|
-
the invocation and the proceed / redraft / block contract; per-round
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
**`proceed`** → Step 2 then Step 3. **`block`** → **do not close**: post a
|
|
90
|
-
`friction` comment and flip `agent::blocked` — commands and the
|
|
91
|
-
`evidence-gate.js --standalone` evidence-share mechanic: reference
|
|
92
|
-
§ Step 1a.
|
|
85
|
+
the invocation and the proceed / redraft / block contract; per-round mechanics
|
|
86
|
+
live in [`acceptance-self-eval.md`](acceptance-self-eval.md). **`proceed`** →
|
|
87
|
+
Step 2. **`block`** → **do not close**: post a `friction` comment and flip
|
|
88
|
+
`agent::blocked` (reference § Step 1a).
|
|
93
89
|
|
|
94
90
|
## Step 2 — Ceremony (profile + derived level)
|
|
95
91
|
|
|
96
|
-
Ceremony is `delivery.routing.ceremonyProfile` × the **derived change
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
92
|
+
Ceremony is `delivery.routing.ceremonyProfile` × the **derived change level**,
|
|
93
|
+
never a planner-authored verdict. **Digest § 3** is the incantation (change set
|
|
94
|
+
once, derive the level, resolve critics with `ceremony-routing.js`); edge cases
|
|
95
|
+
are reference § Step 2. Hard gates always run in Step 3 — the derived level
|
|
96
|
+
never disables them; do **not** pre-run the chain here.
|
|
97
|
+
|
|
98
|
+
### Step 2.5 — Push and hand off (sub-agent dispatch only)
|
|
99
|
+
|
|
100
|
+
Push `story-<storyId>` to `origin` and confirm the remote ref moved. Return the
|
|
101
|
+
hand-off — Story id, `workCwd`, branch, pushed head SHA, self-eval verdict,
|
|
102
|
+
`verify[]` evidence — then stop. Do not open the PR; do not compose a terminal
|
|
103
|
+
envelope. An inline run skips this.
|
|
103
104
|
|
|
104
105
|
## Step 3 — Close and land (`single-story-close.js`)
|
|
105
106
|
|
|
107
|
+
**The orchestrator's step** (§ Who owns which step), run in the **foreground**,
|
|
108
|
+
serialized against sibling Stories:
|
|
109
|
+
|
|
106
110
|
```bash
|
|
107
111
|
node <main-repo>/.agents/scripts/single-story-close.js --story <storyId> --cwd <main-repo>
|
|
108
112
|
```
|
|
109
113
|
|
|
110
114
|
**The whole delivery tail** — gates, PR, merge wait, `agent::done` flip,
|
|
111
|
-
post-land tail in one process.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
`
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
## Steps 4–6 — Recovery router (**recovery-only**)
|
|
125
|
-
|
|
126
|
-
A `landed` envelope means everything ran — go straight to Step 7. Enter a
|
|
127
|
-
recovery path **only** when the envelope routes you there:
|
|
128
|
-
|
|
129
|
-
- **`blocked` / `checks-failed`** → fix, push a new commit (auto-merge stays
|
|
130
|
-
armed), resume via `nextCommand`; triage per
|
|
131
|
-
[`rules/ci-remediation.md`](../../rules/ci-remediation.md). The watch is
|
|
132
|
-
internally blocking — never end a turn with prose and an unconfirmed
|
|
133
|
-
merge. Reference § Step 4.
|
|
134
|
-
- **`pending`** → run `nextCommand` (`single-story-confirm-merge.js`) until
|
|
135
|
-
resolved. Reference § Step 5.
|
|
136
|
-
- **`tail.statusResync: false`** → reference § Step 5.5;
|
|
137
|
-
**`tail.refCleanup` / `tail.baseFastForward: false`** → reference § Step 6.
|
|
138
|
-
|
|
139
|
-
## Step 7 — Return contract (**required as a sub-agent**) {#return-contract}
|
|
140
|
-
|
|
141
|
-
End your turn by relaying the validated envelope close emits between its
|
|
115
|
+
post-land tail in one process. Never background it, never delegate it to a
|
|
116
|
+
child, and never end your turn while it is still running: "close is running"
|
|
117
|
+
is not a return value. Branch on the envelope's `status` per **digest § 5**
|
|
118
|
+
(`landed` → Step 7; `pending` → run `nextCommand`; `blocked`/`checks-failed`
|
|
119
|
+
→ Step 4; `failed` → diagnose, re-run). Gate output is captured.
|
|
120
|
+
|
|
121
|
+
Internals, merge-wait budgets, the slow-CI **async** confirm mode, the
|
|
122
|
+
`autoMerge` policy and every close flag: reference § Step 3.
|
|
123
|
+
|
|
124
|
+
## Step 7 — Return contract {#return-contract}
|
|
125
|
+
|
|
126
|
+
Relay the validated envelope close emits between its
|
|
142
127
|
`--- STORY DELIVER TERMINAL ---` markers — never free-form prose, never a
|
|
143
|
-
hand-composed object. Statuses, exits
|
|
144
|
-
(
|
|
145
|
-
|
|
146
|
-
`pending` is the only sanctioned no-merge ending, returned only when your own
|
|
147
|
-
budget is exhausted. Reference § Step 7.
|
|
128
|
+
hand-composed object. Statuses, exits and fields: **digest § 5** (SSOT: the
|
|
129
|
+
shipped [schema](../../schemas/story-deliver-terminal.schema.json)).
|
|
130
|
+
`pending` is the only sanctioned no-merge ending.
|
|
148
131
|
|
|
149
|
-
##
|
|
132
|
+
## Steps 4–6 — Recovery (**recovery-only**) {#recover}
|
|
133
|
+
|
|
134
|
+
A `landed` envelope means everything ran — go to Step 7. Enter recovery **only**
|
|
135
|
+
when the envelope routes you there; procedures are reference §§ Step 4–6.
|
|
136
|
+
Two rules the spine keeps: a red **disarms auto-merge**,
|
|
137
|
+
so only a green on a NEW head SHA re-arms it — a re-run is refused; fix at source
|
|
138
|
+
and push ([`rules/ci-remediation.md`](../../rules/ci-remediation.md)). And a
|
|
139
|
+
`tail.*: false` degrades the report, never the land.
|
|
140
|
+
|
|
141
|
+
**Watch exit codes** — `pr-watch-with-update.js` exits 0 green, 1 only when a
|
|
142
|
+
required check genuinely failed (or the PR is unreadable), 2 slow-but-not-red:
|
|
143
|
+
still-running, unresolved, **or** `notYetStarted` — no required context attached
|
|
144
|
+
inside `attachWindowMs`. Never route a 2 onto the red path; nothing is broken
|
|
145
|
+
and no digest exists to read.
|
|
150
146
|
|
|
151
147
|
**Lost envelope first: read it off disk.** Close persists each to
|
|
152
148
|
`temp/orchestration/story-deliver-terminal-<storyId>.json`; branch on it per
|
|
153
|
-
digest § 5. Otherwise
|
|
154
|
-
do not guess — probe **read-only** with
|
|
149
|
+
digest § 5. Otherwise do not guess — probe **read-only** with
|
|
155
150
|
`node .agents/scripts/deliver-recover.js --story <storyId>`; it prints the
|
|
156
151
|
**one** next command with its evidence, never a menu. A live close answers
|
|
157
152
|
`close-in-flight`: wait, never re-init underneath it.
|
|
158
153
|
|
|
159
154
|
## Idempotence & constraints
|
|
160
155
|
|
|
161
|
-
Every script no-ops safely on re-run (
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
- **Never** push the Story branch directly to `main` — the PR is the only
|
|
166
|
-
merge surface.
|
|
167
|
-
- **Always** prefix path-based tools with the absolute `workCwd` root
|
|
168
|
-
(Step 0.5); close's wrong-tree guard is a backstop.
|
|
169
|
-
- **Report state, not process** — mirror the close envelope's fields; no
|
|
170
|
-
step narration.
|
|
171
|
-
- Drive every `agent::*` transition through
|
|
172
|
-
`update-ticket-state.js --ticket <id> --state <state>`.
|
|
156
|
+
Every script no-ops safely on re-run (reference § Idempotence). **Never** push
|
|
157
|
+
the Story branch to `main` — the PR is the only merge surface. Report state,
|
|
158
|
+
not process. Drive `agent::*` through
|
|
159
|
+
`update-ticket-state.js --ticket <id> --state <state>`.
|
|
173
160
|
|
|
174
161
|
## See also
|
|
175
162
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
- [`deliver-story-reference.md`](deliver-story-reference.md) — all on-demand
|
|
179
|
-
detail.
|
|
163
|
+
[`deliver-digest.md`](deliver-digest.md), [`/deliver`](../deliver.md),
|
|
164
|
+
[`deliver-story-reference.md`](deliver-story-reference.md).
|
|
@@ -36,6 +36,22 @@ whole surface exists to remove.
|
|
|
36
36
|
Mixed ids and prose in one invocation is a **hard error**: refuse and ask which
|
|
37
37
|
was meant, rather than guessing a mode and doing the wrong work.
|
|
38
38
|
|
|
39
|
+
## Default-single split policy — what the seam means
|
|
40
|
+
|
|
41
|
+
The spine's two escape hatches from N=1 are narrow on purpose:
|
|
42
|
+
|
|
43
|
+
- **Near-zero overlap** — the pieces touch disjoint files and neither's
|
|
44
|
+
acceptance criteria can be scored without the other having landed.
|
|
45
|
+
- **Architectural seam** — different deployables, or a migration and its
|
|
46
|
+
consumer: work that cannot share one branch and one PR without one half
|
|
47
|
+
sitting unverifiable behind the other.
|
|
48
|
+
|
|
49
|
+
Everything else is one Story with `## Slicing` checkpoints. When N>1 does
|
|
50
|
+
apply, **every acceptance criterion belongs to exactly one Story** —
|
|
51
|
+
`assertAcceptancePartition` refuses a split whose criteria repeat across
|
|
52
|
+
siblings, because a verbatim-shared criterion is the signature of coupled work
|
|
53
|
+
cut in half rather than genuinely separable work.
|
|
54
|
+
|
|
39
55
|
## Unknown triage — AFK vs HITL
|
|
40
56
|
|
|
41
57
|
Every open question interrogation surfaces is triaged by **who can resolve
|
|
@@ -98,6 +114,14 @@ Resume `/plan` at step 2 (Author) **in this same session** — the interrogation
|
|
|
98
114
|
is still valid and re-paying for it buys nothing. This bounce-back is not an
|
|
99
115
|
escalation.
|
|
100
116
|
|
|
117
|
+
**Under `--yes` the offer is recorded and planning proceeds** — it is *never*
|
|
118
|
+
auto-downgraded to light. An unattended run has nobody to confirm the reroute,
|
|
119
|
+
and a suggestion is not a confirmation. The same rule governs unknown triage
|
|
120
|
+
unattended: AFK unknowns are still researched, but no free-form operator
|
|
121
|
+
question is asked — each HITL unknown lands in Key Assumptions marked a
|
|
122
|
+
decision-made-by-default, so the record shows what was decided for the operator
|
|
123
|
+
rather than pretending it was decided with them.
|
|
124
|
+
|
|
101
125
|
Escalation in the *other* direction — an over-scope prompt on the light path —
|
|
102
126
|
is terminal and requires a fresh session. The rule that separates the two, and
|
|
103
127
|
why it must not be flattened into symmetry:
|
|
@@ -191,12 +215,14 @@ ceilings on `STORY_SHAPE_CEILINGS` in
|
|
|
191
215
|
against the repo before overriding one (authoring `creates` for a file
|
|
192
216
|
that exists at base is a validator rejection). The persist gates stay
|
|
193
217
|
authoritative: they probe the base branch ref, not the working tree.
|
|
194
|
-
- **Keep `## Spec` near contract-level prose.**
|
|
195
|
-
|
|
196
|
-
|
|
218
|
+
- **Keep `## Spec` near contract-level prose.** **Aim for ~250 words; an
|
|
219
|
+
advisory warning fires past 350** (`SPEC_SOFT_WORD_BUDGET`). Two numbers,
|
|
220
|
+
two jobs: ~250 is the authoring target — the nudge toward a contract-level
|
|
197
221
|
Spec (interfaces, invariants, load-bearing constraints; no per-file
|
|
198
|
-
behavior narration)
|
|
199
|
-
|
|
222
|
+
behavior narration) — while 350 is the slacker threshold at which persist
|
|
223
|
+
actually warns, so the warning marks a real outlier instead of ordinary
|
|
224
|
+
variance. Neither fails the persist. The hard fail-closed ceiling
|
|
225
|
+
(~1500 tokens, `spec-spill.js`) is unchanged.
|
|
200
226
|
|
|
201
227
|
A faithfully-filled skeleton — placeholders replaced, pre-resolved entries
|
|
202
228
|
kept, tags valid — passes the persist ticket validators with no
|
|
@@ -289,11 +315,29 @@ output shape standalone. When the kill-switch is off
|
|
|
289
315
|
(`roleScopedAgents: false`) or the host cannot spawn at this depth, fall back
|
|
290
316
|
to a generic sub-agent and hand it the same charter (the `consolidation` /
|
|
291
317
|
`pre-mortem` definitions in [`plan-critic.md`](../../agents/plan-critic.md)).
|
|
318
|
+
**When both critics fire, dispatch them in a single turn.** Consolidation and
|
|
319
|
+
pre-mortem read the same immutable draft, share no write path, and neither
|
|
320
|
+
consumes the other's verdict — the textbook independent fan-out of
|
|
321
|
+
[`parallel-tooling.md`](parallel-tooling.md) Rule 3. Issue both `Agent` calls
|
|
322
|
+
together in one assistant turn rather than awaiting the first verdict before
|
|
323
|
+
spawning the second; serialized critics double the round's wall clock and buy
|
|
324
|
+
nothing, because you fold both verdicts into the same re-author round anyway.
|
|
325
|
+
|
|
292
326
|
Either way the critic is **maker-blind**: hand it the draft artifacts
|
|
293
327
|
(`stories.json`, and `techspec.md` when present) — never the authoring
|
|
294
328
|
transcript or the reasons the planner believed its own draft is sound. A
|
|
295
329
|
critic that reads the maker's case grades the case, not the draft.
|
|
296
330
|
|
|
331
|
+
## What `--dry-run` actually gates
|
|
332
|
+
|
|
333
|
+
`plan-persist.js --dry-run` is the same command with GitHub writes suppressed,
|
|
334
|
+
and every gate runs before the first `createIssue` would fire — the validator,
|
|
335
|
+
the body parse, the DAG, the capacity and Spec-budget ceilings, the
|
|
336
|
+
reachability check, the split and supersede partitions, and the Tech Spec fold.
|
|
337
|
+
That is the whole point of running it first: a dry run that comes back clean
|
|
338
|
+
has already paid for every deterministic refusal, so the real persist has
|
|
339
|
+
nothing left to discover except network failure.
|
|
340
|
+
|
|
297
341
|
## Ready means fully persisted
|
|
298
342
|
|
|
299
343
|
`agent::ready` is the **terminal** step, not part of the creating POST.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: >-
|
|
3
|
+
Attended consolidation pass over this project's agent memory pool — merge
|
|
4
|
+
duplicates, verify claims against the current tree, prune with operator
|
|
5
|
+
confirmation, rewrite the index, and stamp the pool so the /plan advisory
|
|
6
|
+
goes quiet.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# /memory-consolidate [--dry-run]
|
|
10
|
+
|
|
11
|
+
Agent memory drifts as the codebase moves: a workaround gets fixed, a budget
|
|
12
|
+
changes, two sessions save the same lesson twice. This is the sweep that
|
|
13
|
+
corrects it — and the **only** sanctioned writer of the memory pool outside a
|
|
14
|
+
session's own point-of-write corrections.
|
|
15
|
+
|
|
16
|
+
**Attended by contract.** Mandrel ships the trigger, the grounding and the
|
|
17
|
+
receipt; it never mutates the operator's personal memory store unsupervised.
|
|
18
|
+
Nothing here runs on a schedule, and no step deletes a file before Gate #2.
|
|
19
|
+
|
|
20
|
+
## Step 0 — Resolve the pool
|
|
21
|
+
|
|
22
|
+
`MANDREL_MEMORY_DIR` wins outright; otherwise the pool is
|
|
23
|
+
`~/.claude/projects/<cwd-slug>/memory/`, where `<cwd-slug>` is the absolute
|
|
24
|
+
working directory with every `/` and `.` replaced by `-`.
|
|
25
|
+
|
|
26
|
+
Report the resolved path and the entry count. **No pool → say so in one line
|
|
27
|
+
and stop** — an absent substrate is a clean no-op, never an error, and never a
|
|
28
|
+
reason to create one.
|
|
29
|
+
|
|
30
|
+
Each project (and each worktree) has its own pool: consolidate the pool of the
|
|
31
|
+
checkout you are in, and never reach across into another.
|
|
32
|
+
|
|
33
|
+
## Step 1 — Read the pool
|
|
34
|
+
|
|
35
|
+
Read `MEMORY.md` and every `*.md` entry. Group them by subject so duplicates
|
|
36
|
+
and supersessions surface together. Do not judge an entry from its index line —
|
|
37
|
+
the index is a pointer, the file is the claim.
|
|
38
|
+
|
|
39
|
+
## Step 2 — Classify each entry
|
|
40
|
+
|
|
41
|
+
Verify before you keep. Run `ls` / `grep` against the **current tree** for the
|
|
42
|
+
paths, flags, budgets and gate names an entry cites; re-measure a number rather
|
|
43
|
+
than trusting it (`wc -c` a file whose byte budget is quoted).
|
|
44
|
+
|
|
45
|
+
| Verdict | Means | Action |
|
|
46
|
+
| --- | --- | --- |
|
|
47
|
+
| `fresh` | Claims re-confirmed against the tree | Leave byte-identical |
|
|
48
|
+
| `correct` | Core lesson holds, a detail has moved | Rewrite the detail in place, keep the entry |
|
|
49
|
+
| `duplicate` | Same lesson as another entry | Merge into the richer one, propose the thinner for pruning |
|
|
50
|
+
| `superseded` | The thing it warns about is fixed or retired | Strike the claim, keep the correction visible |
|
|
51
|
+
| `dead` | Subject no longer exists at all | Propose for pruning |
|
|
52
|
+
|
|
53
|
+
**A closed issue is the subject of a retrospective, never evidence of
|
|
54
|
+
staleness.** These pools are largely delivery write-ups — "delivered this
|
|
55
|
+
Story", "fixed by that PR". The referenced issue being closed is what the
|
|
56
|
+
memory is *about*: the normal, healthy shape. A retired predecessor of this
|
|
57
|
+
workflow marked exactly that pattern stale, which is why it no longer exists.
|
|
58
|
+
Use `github.owner` / `github.repo` from `.agentrc.json` when an issue
|
|
59
|
+
genuinely needs probing, and treat an unreachable probe as unknown — never
|
|
60
|
+
as dead.
|
|
61
|
+
|
|
62
|
+
Prefer `correct` over `dead`. A rewritten entry keeps hard-won context; a
|
|
63
|
+
deleted one costs a future session the same mistake.
|
|
64
|
+
|
|
65
|
+
## Step 3 — Gate #1: present the plan
|
|
66
|
+
|
|
67
|
+
Write the full proposal to `temp/memory/consolidation-<date>.md` — per entry:
|
|
68
|
+
verdict, evidence, and the exact edit or merge proposed. Summarize inline:
|
|
69
|
+
counts per verdict and the specific prune candidates by name.
|
|
70
|
+
|
|
71
|
+
**STOP.** Do not edit until the operator responds.
|
|
72
|
+
|
|
73
|
+
## Step 4 — Apply the edits
|
|
74
|
+
|
|
75
|
+
On confirmation, apply the `correct`, `duplicate` and `superseded` rewrites.
|
|
76
|
+
Preserve each entry's frontmatter contract (`name`, `description`, `metadata`)
|
|
77
|
+
and keep `[[wiki-link]]` references resolvable — a merge that orphans a link
|
|
78
|
+
has moved the problem, not fixed it.
|
|
79
|
+
|
|
80
|
+
## Step 5 — Gate #2: confirm every deletion
|
|
81
|
+
|
|
82
|
+
**Deletion is never implied by Gate #1.** Name each file proposed for pruning
|
|
83
|
+
with its one-line reason, and offer **mark-vs-delete**: marking the claim
|
|
84
|
+
superseded in place is the default and always available. Wait for an explicit
|
|
85
|
+
yes; delete only what the operator names. Silence is not consent.
|
|
86
|
+
|
|
87
|
+
## Step 6 — Rewrite the index and stamp
|
|
88
|
+
|
|
89
|
+
Rewrite `MEMORY.md` so it holds exactly one pointer line per surviving entry —
|
|
90
|
+
title, link, hook. It is loaded into context every session, so it carries
|
|
91
|
+
pointers only, never memory content.
|
|
92
|
+
|
|
93
|
+
Then write the receipt to `.consolidation-stamp.json` in the pool root:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{ "lastConsolidatedAt": "<ISO-8601 timestamp>" }
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The `/plan` Phase 0 advisory reads this file; until it is written, the nudge
|
|
100
|
+
keeps firing. Write it **only** after Gate #2 — the stamp asserts an operator
|
|
101
|
+
reviewed the pass, so writing it early makes it a lie.
|
|
102
|
+
|
|
103
|
+
Close with counts: entries read, corrected, merged, pruned, and the new total.
|
|
104
|
+
|
|
105
|
+
## Constraints
|
|
106
|
+
|
|
107
|
+
- `--dry-run` runs Steps 0–3 and stops: the report is written, nothing mutates.
|
|
108
|
+
- Never delete an entry the operator did not name. Never write the stamp on a
|
|
109
|
+
dry run or a declined gate.
|
|
110
|
+
- Never invent memories here — this pass corrects and prunes what sessions
|
|
111
|
+
wrote; new memories come from the sessions that learned them.
|
|
112
|
+
|
|
113
|
+
## See also
|
|
114
|
+
|
|
115
|
+
[`/plan`](plan.md) (surfaces the advisory at its Gate #1),
|
|
116
|
+
[`/deliver`](deliver.md) (point-of-write corrections as work lands).
|