mandrel 2.49.0 → 2.50.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.
@@ -8,8 +8,8 @@
8
8
  * - the **creator** — `audit-labels-bootstrap.js`, which ran `gh label create`
9
9
  * over the `audit::<lens>` list and nothing else;
10
10
  * - the **generator** — `audit-to-stories/build-story-body.js`, which emitted
11
- * `type::story`, `agent::ready`, `audit::<lens>` and — as a bare string
12
- * literal — `risk::high`.
11
+ * `type::story`, `audit::<lens>` and — as a bare string literal —
12
+ * `risk::high`.
13
13
  *
14
14
  * `risk::high` was therefore generated by the filer and defined by **no**
15
15
  * taxonomy: not `LABEL_TAXONOMY` (the repo-wide bootstrap), not the audit
@@ -136,6 +136,14 @@ const AUDIT_STORY_AXIS_LABELS = Object.freeze([
136
136
  color: hex(LABEL_COLORS.TYPE),
137
137
  description: 'Story work item',
138
138
  },
139
+ // Created, never generated — the one deliberate asymmetry in this module.
140
+ // The filer emits no `agent::` state (see `STATIC_LABELS` in
141
+ // build-story-body.js): a freshly-filed audit Story is not delivery-ready,
142
+ // and `/mandrel-plan` stamps this label as its terminal flip after
143
+ // enrichment. The bootstrap still creates it so that flip has a label to
144
+ // apply on a repo where only the audit bootstrap has been run. The drift
145
+ // this module guards runs the other way — a generator inventing names the
146
+ // creator never made — so a creator-only entry is safe (Story #5229).
139
147
  {
140
148
  name: AGENT_LABELS.READY,
141
149
  color: hex(LABEL_COLORS.AGENT),
@@ -10,9 +10,9 @@
10
10
  * Pure: returns { title, body, labels }. Labels carry one canonical
11
11
  * `audit::<lens>` per distinct source report represented in the merge
12
12
  * (derived from each finding's `sourceReport` basename, NEVER from the
13
- * fine-grained `dimension` text — see Story #4195), plus the standard
14
- * `type::story`, `agent::ready`, and (when any finding is Critical)
15
- * `risk::high`.
13
+ * fine-grained `dimension` text — see Story #4195), plus `type::story` and
14
+ * (when any finding is Critical) `risk::high`. Deliberately **no `agent::`
15
+ * state label** — see {@link STATIC_LABELS}.
16
16
  *
17
17
  * The body is serialized via the canonical story-body serializer
18
18
  * (`.agents/scripts/lib/story-body/story-body.js`) so the output round-trips
@@ -23,7 +23,7 @@
23
23
  */
24
24
 
25
25
  import path from 'node:path';
26
- import { AGENT_LABELS, RISK_LABELS, TYPE_LABELS } from '../label-constants.js';
26
+ import { RISK_LABELS, TYPE_LABELS } from '../label-constants.js';
27
27
  import { serialize } from '../story-body/story-body.js';
28
28
  import { definesAuditLabel } from './audit-label-taxonomy.js';
29
29
  import { auditLabelsForFindings } from './audit-lenses.js';
@@ -32,7 +32,26 @@ import {
32
32
  renderSemanticKeyFooter,
33
33
  } from './finding-adapter.js';
34
34
 
35
- const STATIC_LABELS = Object.freeze([TYPE_LABELS.STORY, AGENT_LABELS.READY]);
35
+ // The story-axis labels every generated audit Story carries, and the one it
36
+ // deliberately does NOT: an `agent::` state.
37
+ //
38
+ // This used to be `[TYPE_LABELS.STORY, AGENT_LABELS.READY]`, which put every
39
+ // Story the sweep filed one step from execution. `agent::ready` is precisely
40
+ // what `/mandrel-deliver` reads as "available for pickup", and the bodies
41
+ // reaching this function are audit prose — a synthesized acceptance line per
42
+ // finding and an Agent Prompts section that is empty whenever the lens
43
+ // captured no `agentPrompt`. Filing them ready contradicted the sweep's own
44
+ // shipped runbook, whose enrich-before-you-deliver step says not to point
45
+ // `/mandrel-deliver` at a freshly-filed audit Story; the label said the
46
+ // opposite of the prose, and the label is the half a machine reads.
47
+ //
48
+ // The state axis therefore belongs to whoever enriches the finding:
49
+ // `/mandrel-plan` stamps `agent::ready` as its terminal flip once the Story
50
+ // has a `## Spec`, real acceptance criteria and runnable verify lines. An
51
+ // absent `agent::` label is a legal initial state — `isValidTransition`
52
+ // treats a null from-state as the initial-entry edge and permits any target —
53
+ // so nothing downstream has to special-case the gap (Story #5229).
54
+ const STATIC_LABELS = Object.freeze([TYPE_LABELS.STORY]);
36
55
 
37
56
  // The verify[] contract every generated audit Story carries. These commands
38
57
  // exist in this repo's harness (package.json scripts) so the Story satisfies
@@ -145,10 +145,18 @@ Audit-sourced Stories carry a closed label set, so they can be filtered out of
145
145
  | Label | Meaning |
146
146
  | --- | --- |
147
147
  | `type::story` | Every emitted Story — the sweep never opens Epics or tasks. |
148
- | `agent::ready` | Filed and available for pickup. |
149
148
  | `audit::<lens>` | One per lens represented in the group; a cross-audit merge carries several. |
150
149
  | `risk::high` | Added when any finding in the group is Critical. |
151
150
 
151
+ **There is no `agent::` state label in that set, and that is the point.** The
152
+ sweep files a Story it has deliberately not made deliverable — Step 5 above is
153
+ the reason. `agent::ready` is what `/mandrel-deliver` reads as "available for
154
+ pickup", so a sweep that applied it would route unenriched audit prose straight
155
+ into delivery, which is the outcome Step 5 tells you to avoid. The label is
156
+ applied by `/mandrel-plan`, at the end of planning, once the finding is a
157
+ scoped slice. If you file these Issues by hand, apply the emitted `labels[]`
158
+ verbatim and do not top it up with a state.
159
+
152
160
  The lens labels are a **closed taxonomy**: only the canonical `audit::<lens>`
153
161
  names are valid, and the filer refuses to emit a label the repository has never
154
162
  created. Create them once with `audit-labels-bootstrap.js` before the first live
@@ -211,11 +211,17 @@ shared helper's `fingerprintFooter(sha)`
211
211
  Labels applied:
212
212
 
213
213
  - `type::story`
214
- - `agent::ready`
215
214
  - `audit::<dimension>` — one per dimension represented in the merge
216
215
  (cross-audit groups carry multiple).
217
216
  - `risk::high` — added when any finding in the group is Critical.
218
217
 
218
+ **No `agent::` state label, deliberately.** The filer used to emit
219
+ `agent::ready`, which is exactly what `/mandrel-deliver` reads as "available
220
+ for pickup" — and these bodies are audit prose, not a delivery-ready Spec. A
221
+ Story with no `agent::` label is a legal initial state; `/mandrel-plan` stamps
222
+ `agent::ready` as its terminal flip once the finding has become a scoped
223
+ capability slice. Do not re-add it here or apply it by hand at create time.
224
+
219
225
  ### Phase 5c — Wire the cohort's declared ordering (**required**)
220
226
 
221
227
  Creating the Issues is only the first pass. `groupFindings` detects `edges[]`
package/docs/CHANGELOG.md CHANGED
@@ -15,6 +15,13 @@ All notable changes to this project will be documented in this file.
15
15
  -->
16
16
  <!-- markdownlint-disable-file MD004 MD012 MD037 -->
17
17
 
18
+ ## [2.50.0](https://github.com/dsj1984/mandrel/compare/mandrel-v2.49.0...mandrel-v2.50.0) (2026-09-08)
19
+
20
+
21
+ ### Fixed
22
+
23
+ * stop /audit-to-stories emitting agent::ready on generated audit Stories… ([#5229](https://github.com/dsj1984/mandrel/issues/5229)) ([#5230](https://github.com/dsj1984/mandrel/issues/5230)) ([d095608](https://github.com/dsj1984/mandrel/commit/d09560866c42084aed3fb92fb91d8c9a49fe66e3))
24
+
18
25
  ## [2.49.0](https://github.com/dsj1984/mandrel/compare/mandrel-v2.48.0...mandrel-v2.49.0) (2026-09-08)
19
26
 
20
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mandrel",
3
- "version": "2.49.0",
3
+ "version": "2.50.0",
4
4
  "description": "Claude Code-first opinionated workflow framework: instructions, skills, rules, and SDLC workflows that govern AI coding assistants.",
5
5
  "files": [
6
6
  ".agents/",