mandrel 1.90.0 → 1.92.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.
Files changed (115) hide show
  1. package/.agents/README.md +5 -5
  2. package/.agents/docs/SDLC.md +75 -107
  3. package/.agents/docs/configuration.md +1 -1
  4. package/.agents/docs/quality-gates.md +8 -7
  5. package/.agents/docs/workflows.md +4 -10
  6. package/.agents/instructions.md +2 -2
  7. package/.agents/schemas/agentrc.schema.json +1 -1
  8. package/.agents/schemas/lifecycle/README.md +2 -1
  9. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  10. package/.agents/schemas/risk-verdict.schema.json +14 -1
  11. package/.agents/scripts/README.md +0 -46
  12. package/.agents/scripts/analyze-execution.js +76 -1
  13. package/.agents/scripts/check-doc-links.js +3 -0
  14. package/.agents/scripts/check-workflow-cli-lint.js +208 -0
  15. package/.agents/scripts/epic-audit-recheck.js +1 -1
  16. package/.agents/scripts/epic-deliver-preflight.js +37 -1
  17. package/.agents/scripts/epic-plan-clarity.js +16 -6
  18. package/.agents/scripts/epic-plan-decompose.js +37 -59
  19. package/.agents/scripts/epic-plan-healthcheck.js +39 -6
  20. package/.agents/scripts/epic-plan-spec.js +41 -168
  21. package/.agents/scripts/epic-reconcile.js +7 -1
  22. package/.agents/scripts/lib/Logger.js +4 -4
  23. package/.agents/scripts/lib/audit-suite/index.js +4 -5
  24. package/.agents/scripts/lib/audit-suite/runner.js +6 -4
  25. package/.agents/scripts/lib/audit-suite/selector.js +2 -3
  26. package/.agents/scripts/lib/bdd-runner-detect.js +1 -1
  27. package/.agents/scripts/lib/command-header.js +20 -0
  28. package/.agents/scripts/lib/config/github.js +1 -3
  29. package/.agents/scripts/lib/config-settings-schema.js +4 -3
  30. package/.agents/scripts/lib/degraded-mode.js +1 -1
  31. package/.agents/scripts/lib/label-constants.js +18 -3
  32. package/.agents/scripts/lib/label-taxonomy.js +14 -3
  33. package/.agents/scripts/lib/mutation/baseline-snapshot.js +7 -6
  34. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +18 -8
  35. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +3 -4
  36. package/.agents/scripts/lib/orchestration/docs-digest.js +2 -2
  37. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +4 -0
  38. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +22 -12
  39. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +6 -1
  40. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +18 -2
  41. package/.agents/scripts/{lifecycle-diff.js → lib/orchestration/lifecycle/ledger-diff.js} +10 -76
  42. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +1 -1
  43. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +32 -0
  44. package/.agents/scripts/lib/orchestration/plan-context.js +510 -0
  45. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +177 -0
  46. package/.agents/scripts/lib/orchestration/plan-metrics.js +445 -0
  47. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +359 -0
  48. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +127 -0
  49. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +978 -0
  50. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +191 -0
  51. package/.agents/scripts/lib/orchestration/plan-reachability.js +160 -0
  52. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +3 -3
  53. package/.agents/scripts/lib/orchestration/planning-risk.js +1 -1
  54. package/.agents/scripts/lib/orchestration/remote-verifier.js +165 -0
  55. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +10 -0
  56. package/.agents/scripts/lib/orchestration/spec-freshness.js +1 -1
  57. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +1 -1
  58. package/.agents/scripts/lib/orchestration/ticketing/reads.js +11 -2
  59. package/.agents/scripts/lib/plan-phase-cleanup.js +16 -0
  60. package/.agents/scripts/lib/presentation/manifest-persistence.js +2 -3
  61. package/.agents/scripts/lib/templates/spec-author-prompts.js +74 -0
  62. package/.agents/scripts/plan-context.js +186 -0
  63. package/.agents/scripts/plan-critics.js +227 -0
  64. package/.agents/scripts/plan-persist.js +383 -0
  65. package/.agents/scripts/pr-watch-with-update.js +8 -7
  66. package/.agents/scripts/run-lint.js +10 -11
  67. package/.agents/scripts/single-story-init.js +22 -0
  68. package/.agents/scripts/story-plan.js +19 -7
  69. package/.agents/scripts/sync-claude-commands.js +10 -5
  70. package/.agents/skills/core/knowledge-transfer/SKILL.md +11 -7
  71. package/.agents/workflows/audit-documentation.md +5 -7
  72. package/.agents/workflows/audit-lighthouse.md +1 -0
  73. package/.agents/workflows/audit-security.md +1 -0
  74. package/.agents/workflows/audit-to-stories.md +16 -5
  75. package/.agents/workflows/deliver.md +8 -0
  76. package/.agents/workflows/git-deliver.md +76 -243
  77. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  78. package/.agents/workflows/helpers/code-review.md +7 -6
  79. package/.agents/workflows/helpers/deliver-epic.md +16 -4
  80. package/.agents/workflows/helpers/plan-epic-reference.md +109 -96
  81. package/.agents/workflows/helpers/plan-epic.md +246 -999
  82. package/.agents/workflows/helpers/plan-story.md +14 -14
  83. package/.agents/workflows/helpers/scope-triage-gate.md +6 -4
  84. package/.agents/workflows/helpers/single-story-deliver.md +13 -4
  85. package/.agents/workflows/helpers/worktree-lifecycle.md +9 -7
  86. package/.agents/workflows/mandrel-update.md +144 -466
  87. package/.agents/workflows/plan.md +73 -143
  88. package/docs/CHANGELOG.md +20 -0
  89. package/lib/cli/registry.js +21 -3
  90. package/package.json +1 -1
  91. package/.agents/schemas/loop-unit.schema.json +0 -70
  92. package/.agents/scripts/assert-branch.js +0 -81
  93. package/.agents/scripts/check-loop-units.js +0 -204
  94. package/.agents/scripts/detect-merges.js +0 -111
  95. package/.agents/scripts/git-pr-quality-gate.js +0 -205
  96. package/.agents/scripts/git-rebase-and-resolve.js +0 -234
  97. package/.agents/scripts/hierarchy-gate.js +0 -192
  98. package/.agents/scripts/hydrate-context.js +0 -179
  99. package/.agents/scripts/lib/loop-units/validate-loop-unit.js +0 -197
  100. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/cli.js +0 -167
  101. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/cli-args.js +0 -69
  102. package/.agents/scripts/lib/orchestration/plan-runner/plan-router.js +0 -86
  103. package/.agents/scripts/loc-delta.js +0 -205
  104. package/.agents/scripts/render-manifest.js +0 -143
  105. package/.agents/scripts/run-audit-suite.js +0 -97
  106. package/.agents/scripts/select-audits.js +0 -155
  107. package/.agents/scripts/update-mutation-baseline.js +0 -189
  108. package/.agents/workflows/explain.md +0 -118
  109. package/.agents/workflows/git-merge-pr.md +0 -377
  110. package/.agents/workflows/helpers/epic-plan-decompose.md +0 -22
  111. package/.agents/workflows/helpers/epic-plan-spec.md +0 -22
  112. package/.agents/workflows/loops/README.md +0 -65
  113. package/.agents/workflows/loops/fix-failing-tests.md +0 -74
  114. package/.agents/workflows/loops/nightly-audit.md +0 -81
  115. package/.agents/workflows/loops/watch-ci.md +0 -68
@@ -2,7 +2,7 @@
2
2
  description: >-
3
3
  Reference companion to plan-epic.md — the recovery procedures, --resume
4
4
  mechanics, troubleshooting, and background rationale blocks moved out of the
5
- runtime core so every /plan run ingests only the phase flow. Read on demand
5
+ runtime core so every /plan run ingests only the step flow. Read on demand
6
6
  from the trigger-point pointers in plan-epic.md.
7
7
  caller: plan-epic.md
8
8
  ---
@@ -11,126 +11,139 @@ caller: plan-epic.md
11
11
 
12
12
  > **Not a slash command.** This file lives in `helpers/` and is a
13
13
  > path-included reference module (not projected into the plugin command
14
- > tree). [`plan-epic.md`](plan-epic.md) is the runtime core — the phase
15
- > flow, commands, and gate contracts. This file holds the secondary
16
- > material a run needs only when it hits an edge (a recovery path, a
17
- > troubleshooting symptom) or wants the design rationale behind a phase.
18
- > Each section below is reached from a one-line pointer at its trigger
19
- > point in the core.
14
+ > tree). [`plan-epic.md`](plan-epic.md) is the runtime core — the 3-step
15
+ > flow, commands, and gate contracts. This file holds the secondary material
16
+ > a run needs only when it hits an edge (a recovery path, a troubleshooting
17
+ > symptom) or wants the design rationale behind a persist guard.
20
18
 
21
- ## Phase 7 — background rationale
19
+ ## Persist guards — background rationale
22
20
 
23
- The Phase 7 (Tech Spec & Acceptance Spec) core carries only the commands and
24
- the gate contract. The design rationale for the phase's guards and managed
25
- sections lives here.
21
+ The persist step's core carries only the commands and the ordered gate list.
22
+ The design rationale for its guards and managed sections lives here.
26
23
 
27
24
  ### Epic-lease preflight (workflow guard)
28
25
 
29
- Before any Phase 7 mutation, `epic-plan-spec.js` acquires the Epic-lease via
30
- the assignee-as-lease primitive (`lib/orchestration/ticket-lease.js`, wired
31
- through `lib/orchestration/epic-plan-lease-guard.js`). The lease rides the
32
- Epic's single assignee: the operator (`github.operatorHandle` in
33
- `.agentrc.json`) claims the Epic for the duration of the plan. The guard
34
- **fails closed**: `/plan` emits no `story.heartbeat` during its run
35
- (heartbeats are a delivery-time signal), so there is no live-heartbeat source
36
- to judge a concurrent plan's liveness from. Any **foreign assignee** is
37
- therefore treated as a live claim the persist half **exits non-zero and
38
- names the current owner**, so two `/plan` runs cannot drive the same Epic
39
- concurrently. Pass **`--steal`** to forcibly transfer a foreign claim once you
40
- have confirmed the other run is dead. An **unassigned** Epic, or one **already
41
- held by this operator**, is taken (or re-affirmed) silently. The lease is
42
- **released after Phase 8** (decompose) completes.
26
+ Before any mutation, `plan-persist.js` acquires the Epic-lease via the
27
+ assignee-as-lease primitive (`lib/orchestration/ticket-lease.js`). The lease
28
+ rides the Epic's single assignee: the operator (`github.operatorHandle` in
29
+ `.agentrc.json`) claims the Epic for the duration of the persist. The guard
30
+ **fails closed**: `/plan` emits no `story.heartbeat` during its run, so any
31
+ **foreign assignee** is treated as a live claim — the persist exits non-zero
32
+ and names the current owner, so two `/plan` runs cannot drive the same Epic
33
+ concurrently. Pass **`--steal`** to forcibly transfer a foreign claim once
34
+ you have confirmed the other run is dead. An **unassigned** Epic, or one
35
+ **already held by this operator**, is taken (or re-affirmed) silently. The
36
+ lease is released on every exit path success, gate failure, and throw
37
+ alike.
43
38
 
44
39
  ### Idempotent managed sections
45
40
 
46
- The persist half is section-scoped and keyed on the Epic body: a re-run that
41
+ The persist is section-scoped and keyed on the Epic body: a re-run that
47
42
  finds the requested sections already present
48
43
  (`<!-- mandrel:tech-spec:start/end -->` /
49
44
  `<!-- mandrel:acceptance-table:start/end -->`) short-circuits as
50
- `already-planned` instead of duplicating content. Pass `--force` to overwrite
51
- the managed sections in place (same Epic issue, refreshed section bodies).
45
+ `already-planned` instead of duplicating content. Pass `--force` to
46
+ overwrite the managed sections in place (same Epic issue, refreshed section
47
+ bodies, one regeneration audit comment).
52
48
 
53
49
  ### One planning document
54
50
 
55
51
  A `/plan` Epic run creates exactly **one** issue — the Epic. The planning
56
- artifacts land as marker-delimited managed sections of the Epic body: the Tech
57
- Spec (opening with `## Delivery Slicing`) inside
58
- `<!-- mandrel:tech-spec:start/end -->`, and the Acceptance Spec's AC-ID table
59
- (headed `## Acceptance Table`) inside
60
- `<!-- mandrel:acceptance-table:start/end -->`. The PRD artifact class was
61
- retired (Story #4314) its one novel section, **User Stories**, lives inline
62
- in the Epic body as a `## User Stories` section and Story #4324 retired the
63
- `context::tech-spec` / `context::acceptance-spec` ticket classes the same way.
64
- The `## Acceptance Table` section captures the stable-ID acceptance criteria
65
- table (`| AC ID | Outcome | Feature File | Scenario | Disposition |`) that
66
- drives close-time reconciliation during `/deliver` Phase 6. Operators may opt
67
- out for refactor-only or docs-only Epics by applying the `acceptance::n-a`
68
- label to the Epic ticket — when present, the `epic-plan-spec-author` skill
69
- skips the Acceptance Table output and the runtime gates (start gate, finalize
70
- reconciler) honour the waiver — the section need not be authored when the
71
- waiver is set. See [SDLC § Acceptance Table — the second folded planning
72
- section](../../docs/SDLC.md#acceptance-table--the-second-folded-planning-section)
52
+ artifacts land as marker-delimited managed sections of the Epic body: the
53
+ Tech Spec (opening with `## Delivery Slicing`) inside
54
+ `<!-- mandrel:tech-spec:start/end -->`, and the Acceptance Spec's AC-ID
55
+ table (headed `## Acceptance Table`) inside
56
+ `<!-- mandrel:acceptance-table:start/end -->`. The `## Acceptance Table`
57
+ section captures the stable-ID acceptance criteria table
58
+ (`| AC ID | Outcome | Feature File | Scenario | Disposition |`) that drives
59
+ close-time reconciliation during `/deliver`. Operators may opt out for
60
+ refactor-only or docs-only Epics by applying the `acceptance::n-a` label to
61
+ the Epic the authoring skill then skips the Acceptance Table and the
62
+ runtime gates honour the waiver. See
63
+ [SDLC § Acceptance Table the second folded planning section](../../docs/SDLC.md#acceptance-table--the-second-folded-planning-section)
73
64
  for the full lifecycle.
74
65
 
75
66
  ### Parallel-safe file naming (per-Epic tree)
76
67
 
77
- Multiple Epics may be planned or decomposed concurrently. Every temp file
78
- written in the workflow lives under the per-Epic tree
79
- (`temp/epic-[Epic_ID]/<artifact>`) — e.g.
80
- `temp/epic-[Epic_ID]/planner-context.json`,
81
- `temp/epic-[Epic_ID]/techspec.md`,
82
- `temp/epic-[Epic_ID]/decomposer-context.json`,
83
- `temp/epic-[Epic_ID]/tickets.json`. The directory namespace is the isolation
84
- boundary; basenames inside it are stable. Do **not** reuse bare flat names
85
- like `temp/techspec.md` or the legacy `temp/<artifact>-epic-<id>.<ext>` shape
86
- both have been retired.
87
-
88
- **Durability.** The per-Epic tree is durable across runs: only the wrapper
89
- scripts perform intra-phase cleanup of files they wrote in the same invocation
90
- (see [`lib/plan-phase-cleanup.js`](../../scripts/lib/plan-phase-cleanup.js)).
91
- Nothing else garbage-collects the tree, so cross-Epic artifacts — retros, perf
92
- reports, signals, manifests accumulate until an operator explicitly removes
93
- them.
94
-
95
- ## Phase 8 — `--resume` recovery (secondary rate limit)
96
-
97
- The Phase 8 (Work Breakdown Decomposition) core carries the normal-path and
98
- `--force` persist commands. The `--resume` recovery path — reached when a
99
- large decomposition aborts mid-persist — lives here.
68
+ Multiple Epics may be planned concurrently. Every temp file written in the
69
+ workflow lives under the per-Epic tree (`temp/epic-[Epic_ID]/<artifact>`) —
70
+ e.g. `temp/epic-[Epic_ID]/plan-context.json`,
71
+ `temp/epic-[Epic_ID]/techspec.md`, `temp/epic-[Epic_ID]/tickets.json`. The
72
+ directory namespace is the isolation boundary; basenames inside it are
73
+ stable. (The ideation entry, which has no Epic id yet, namespaces under
74
+ `temp/plan-ideation/<slug>/` instead.) Do **not** reuse bare flat names like
75
+ `temp/techspec.md`.
76
+
77
+ **Durability.** The per-Epic tree is durable across runs: `plan-persist.js`
78
+ cleans its temp files **only at terminal success**
79
+ ([`lib/plan-phase-cleanup.js`](../../scripts/lib/plan-phase-cleanup.js)), so
80
+ a failed persist leaves every authored artifact in place for `--force` /
81
+ `--resume` reuse. Nothing else garbage-collects the tree.
82
+
83
+ ## Persist`--resume` recovery (secondary rate limit)
100
84
 
101
85
  **Secondary rate limit on large Epics.** For backlogs over ~60 tickets,
102
- GitHub's secondary rate limit (HTTP 403, body contains "secondary rate limit")
103
- can trip mid-decomposition after ~80 issue creations. The http-client retries
104
- automatically with a 30–120s backoff and the decomposer drops `concurrencyCap`
105
- to 1 for the rest of the run on the first observation. If the run still aborts
106
- (network drop, exhausted retries, etc.), resume from the partial backlog with:
86
+ GitHub's secondary rate limit (HTTP 403, body contains "secondary rate
87
+ limit") can trip mid-persist after ~80 issue creations. The http-client
88
+ retries automatically with a 30–120s backoff. If the run still aborts
89
+ (network drop, exhausted retries, etc.), resume from the partial backlog
90
+ with:
107
91
 
108
92
  ```bash
109
- node .agents/scripts/epic-plan-decompose.js --epic [Epic_ID] \
110
- --tickets temp/epic-[Epic_ID]/tickets.json --resume
93
+ node .agents/scripts/plan-persist.js --epic [Epic_ID] --resume
111
94
  ```
112
95
 
113
- `--resume` is idempotent: the reconciler recovers the slug→issue map from
114
- `temp/epic-[Epic_ID]/[Epic_ID].state.json`, and when that file is missing or
115
- incomplete it **reseeds the map from live GitHub state** by matching each spec
116
- slug against the open children of the Epic by title. Slugs that resolve to an
117
- existing open child diff as Updates/no-ops; only the genuinely-missing children
118
- are created — the existing tree is never duplicated. To force-throttle from the
119
- first call on a known-large Epic, set `(framework constant: decomposer
120
- concurrency): 1` in `.agentrc.json`.
96
+ `--resume` is idempotent: the managed sections short-circuit
97
+ `already-planned`, and the reconciler recovers the slug→issue map from its
98
+ per-slug state ledger (`temp/epic-[Epic_ID]/[Epic_ID].state.json`)
99
+ reseeding from live GitHub state when the file is missing so only the
100
+ genuinely-missing children are created; the existing tree is never
101
+ duplicated.
102
+
103
+ ## Measurement the G2 acceptance gate (Epic #4474)
104
+
105
+ The 3-step collapse is **measured, not asserted**. The acceptance bar the
106
+ next benchmark cohort reads as the gate:
107
+
108
+ - **Turns-per-plan ≤ ~15** at the epic rung (from the 55–72-turn 12-phase
109
+ baseline). The turns proxy is the plan-metrics invocation ledger
110
+ (`temp/epic-<id>/plan-metrics.json`) plus the host session's turn
111
+ accounting — ledger records count CLI invocations from the parent
112
+ session's perspective, not sub-agent turns.
113
+ - **Plan tokens ≤ ~1.5M** at the epic rung (from 7.3–8.9M) — owned by the
114
+ host's session accounting (mandrel-bench `modelUsage`), not by any
115
+ in-repo counter.
116
+ - **Unchanged validator coverage** — every deterministic gate of the
117
+ retired pipeline still fires on the persist path: section gate, ticket
118
+ validator, file-assumption, DAG, budget, draft reachability, inline
119
+ healthcheck, mode-coherence. The enumerated receipt is
120
+ `tests/contract/planning/plan-persist-validator-coverage.test.js`.
121
+
122
+ Where to read the measurement:
123
+
124
+ - The `plan-summary` structured comment on the Epic carries the
125
+ plan-metrics roll-up line (invocations, per-CLI counts, span, critic
126
+ skips) — no runner-disk access needed.
127
+ - `node .agents/scripts/analyze-execution.js --epic <id> --plan-metrics-json`
128
+ prints the compact machine-readable envelope
129
+ (`{ epicId, planMetrics, summaryLine }`) — local read-only, stdout-pure.
121
130
 
122
131
  ## Troubleshooting
123
132
 
124
- - If `epic-plan-spec.js --emit-context` fails, confirm the Epic exists and
125
- has a body with enough initial context.
126
- - If `epic-plan-decompose.js` rejects the tickets file, re-read the
127
- validator's error message the most common causes are a ticket whose
128
- `type` is not `story`, a Story missing its inline `acceptance[]` /
129
- `verify[]` contract, or a dependency cycle in the Story `depends_on`
130
- graph.
131
- - If decomposition persisted the tickets but the Epic is not on `agent::ready`,
132
- you likely called `runDecomposePhase` from `epic-plan-decompose.js`
133
- directly without completing the persist flowonly the CLI surface
134
- (`node epic-plan-decompose.js --tickets ...`) drives the full
135
- reconciler pipeline and flips the lifecycle label. Apply `agent::ready`
136
- by hand and re-run via the CLI next time.
133
+ - If `plan-context.js` fails, confirm the Epic exists and has a body with
134
+ enough initial context (epic mode), or that the one-pager file is
135
+ non-empty (ideation mode).
136
+ - If `plan-persist.js` rejects the tickets file, re-read the validator's
137
+ error message the most common causes are a ticket whose `type` is not
138
+ `story`, a Story missing its inline `acceptance[]` / `verify[]` contract,
139
+ a file-assumption declaration that contradicts the base branch, or a
140
+ dependency cycle in the Story `depends_on` graph.
141
+ - If `plan-persist.js` refuses with a mode-coherence error, the risk
142
+ verdict's `deliveryShape` contradicts the tickets payloada `"single"`
143
+ verdict with a `tickets.json` on disk (delete or re-shape it), or a
144
+ fan-out verdict with no tickets authored.
145
+ - If the persist completed but the Epic is not on `agent::ready`, the
146
+ inline healthcheck refused the flip — read the failing check's `reason`
147
+ in the persist output, resolve it (or apply
148
+ `planning::healthcheck-waived` for a triaged environmental failure), and
149
+ re-run the persist.