@milehimikey/em 1.14.2 → 1.16.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 (125) hide show
  1. package/.claude/agents/em-implementer.md +12 -2
  2. package/.claude/agents/em-validator.md +2 -1
  3. package/.claude/skills/event-modeling/SKILL.md +3 -3
  4. package/.claude/skills/event-modeling-conform/SKILL.md +1 -1
  5. package/.claude/skills/event-modeling-design/SKILL.md +29 -18
  6. package/.claude/skills/event-modeling-discover/SKILL.md +1 -1
  7. package/.claude/skills/event-modeling-engagement/SKILL.md +60 -56
  8. package/.claude/skills/event-modeling-engagement/reference/engagement.md +13 -19
  9. package/.claude/skills/event-modeling-implement/SKILL.md +3 -3
  10. package/.claude/skills/event-modeling-implement/reference/implement.md +40 -27
  11. package/.claude/skills/event-modeling-review/SKILL.md +13 -3
  12. package/.claude/skills/event-modeling-shared/reference/em-dsl.md +234 -228
  13. package/.claude/skills/event-modeling-shared/reference/operating-principles.md +3 -3
  14. package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +69 -27
  15. package/.claude/skills/event-modeling-shared/templates/constitution.md +5 -7
  16. package/.claude-plugin/marketplace.json +2 -2
  17. package/dist/catalog/deferQueue.d.ts +20 -0
  18. package/dist/catalog/deferQueue.js +63 -0
  19. package/dist/catalog/deferQueue.js.map +1 -0
  20. package/dist/catalog/docJoin.d.ts +22 -1
  21. package/dist/catalog/docJoin.js +13 -4
  22. package/dist/catalog/docJoin.js.map +1 -1
  23. package/dist/catalog/docModelConsistencyValidate.js +4 -8
  24. package/dist/catalog/docModelConsistencyValidate.js.map +1 -1
  25. package/dist/catalog/driftSignal.d.ts +16 -12
  26. package/dist/catalog/driftSignal.js +14 -9
  27. package/dist/catalog/driftSignal.js.map +1 -1
  28. package/dist/catalog/sliceDoc.d.ts +51 -0
  29. package/dist/catalog/sliceDoc.js +47 -0
  30. package/dist/catalog/sliceDoc.js.map +1 -1
  31. package/dist/catalog/sliceReadyValidate.js +19 -1
  32. package/dist/catalog/sliceReadyValidate.js.map +1 -1
  33. package/dist/catalog/sliceSections.d.ts +5 -0
  34. package/dist/catalog/sliceSections.js +11 -2
  35. package/dist/catalog/sliceSections.js.map +1 -1
  36. package/dist/cli/conformScope.d.ts +4 -0
  37. package/dist/cli/conformScope.js +2 -2
  38. package/dist/cli/conformScope.js.map +1 -1
  39. package/dist/cli/coverage.js +7 -3
  40. package/dist/cli/coverage.js.map +1 -1
  41. package/dist/cli/defer.d.ts +106 -2
  42. package/dist/cli/defer.js +357 -24
  43. package/dist/cli/defer.js.map +1 -1
  44. package/dist/cli/engagement.d.ts +26 -5
  45. package/dist/cli/engagement.js +55 -28
  46. package/dist/cli/engagement.js.map +1 -1
  47. package/dist/cli/engagementFile.d.ts +2 -0
  48. package/dist/cli/engagementFile.js +5 -3
  49. package/dist/cli/engagementFile.js.map +1 -1
  50. package/dist/cli/findings.d.ts +2 -2
  51. package/dist/cli/findings.js +2 -2
  52. package/dist/cli/frontmatterSurgery.d.ts +3 -3
  53. package/dist/cli/frontmatterSurgery.js +3 -3
  54. package/dist/cli/frontmatterSurgery.js.map +1 -1
  55. package/dist/cli/markImplemented.d.ts +23 -18
  56. package/dist/cli/markImplemented.js +99 -15
  57. package/dist/cli/markImplemented.js.map +1 -1
  58. package/dist/cli/ratify.d.ts +36 -6
  59. package/dist/cli/ratify.js +130 -35
  60. package/dist/cli/ratify.js.map +1 -1
  61. package/dist/cli/review.js +3 -3
  62. package/dist/cli/review.js.map +1 -1
  63. package/dist/cli/revise.d.ts +67 -0
  64. package/dist/cli/revise.js +229 -0
  65. package/dist/cli/revise.js.map +1 -0
  66. package/dist/cli/sliceConform.d.ts +4 -3
  67. package/dist/cli/sliceConform.js +29 -12
  68. package/dist/cli/sliceConform.js.map +1 -1
  69. package/dist/cli/status.d.ts +30 -6
  70. package/dist/cli/status.js +59 -19
  71. package/dist/cli/status.js.map +1 -1
  72. package/dist/cli/upgrade.js +17 -12
  73. package/dist/cli/upgrade.js.map +1 -1
  74. package/dist/cli.js +173 -85
  75. package/dist/cli.js.map +1 -1
  76. package/dist/emit/engagementJson.d.ts +7 -4
  77. package/dist/emit/engagementJson.js +11 -4
  78. package/dist/emit/engagementJson.js.map +1 -1
  79. package/dist/emit/json.d.ts +1 -1
  80. package/dist/emit/json.js +18 -5
  81. package/dist/emit/json.js.map +1 -1
  82. package/dist/emit/statusJson.d.ts +1 -1
  83. package/dist/emit/statusJson.js +6 -1
  84. package/dist/emit/statusJson.js.map +1 -1
  85. package/dist/mcp/server.js +5 -5
  86. package/dist/mcp/server.js.map +1 -1
  87. package/dist/model/continuation.d.ts +11 -1
  88. package/dist/model/continuation.js +29 -0
  89. package/dist/model/continuation.js.map +1 -1
  90. package/dist/model/resolveSlice.d.ts +19 -0
  91. package/dist/model/resolveSlice.js +69 -0
  92. package/dist/model/resolveSlice.js.map +1 -0
  93. package/dist/model/rules.d.ts +8 -0
  94. package/dist/model/rules.js +8 -0
  95. package/dist/model/rules.js.map +1 -1
  96. package/dist/model/sliceDocIndex.d.ts +5 -0
  97. package/dist/model/sliceDocIndex.js +6 -4
  98. package/dist/model/sliceDocIndex.js.map +1 -1
  99. package/dist/model/validate.js +5 -2
  100. package/dist/model/validate.js.map +1 -1
  101. package/dist/parser/parser.js +55 -1
  102. package/dist/parser/parser.js.map +1 -1
  103. package/dist/templates.d.ts +1 -1
  104. package/dist/templates.js +5 -7
  105. package/dist/templates.js.map +1 -1
  106. package/package.json +1 -1
  107. package/plugin/.claude-plugin/plugin.json +2 -2
  108. package/plugin/agents/em-implementer.md +12 -2
  109. package/plugin/agents/em-validator.md +2 -1
  110. package/plugin/shared/reference/em-dsl.md +234 -228
  111. package/plugin/shared/reference/operating-principles.md +3 -3
  112. package/plugin/shared/reference/slice-doc-schema.md +69 -27
  113. package/plugin/shared/templates/constitution.md +5 -7
  114. package/plugin/skills/conform/SKILL.md +1 -1
  115. package/plugin/skills/design/SKILL.md +29 -18
  116. package/plugin/skills/discover/SKILL.md +1 -1
  117. package/plugin/skills/engagement/SKILL.md +60 -56
  118. package/plugin/skills/engagement/reference/engagement.md +13 -19
  119. package/plugin/skills/event-modeling/SKILL.md +3 -3
  120. package/plugin/skills/implement/SKILL.md +3 -3
  121. package/plugin/skills/implement/reference/implement.md +40 -27
  122. package/plugin/skills/review/SKILL.md +13 -3
  123. package/dist/cli/reratify.d.ts +0 -58
  124. package/dist/cli/reratify.js +0 -238
  125. package/dist/cli/reratify.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: em-implementer
3
- description: Implements exactly one ratified event-modeling slice in an assigned worktree and branch and opens its pull request; the engagement skill dispatches it once per slice with only the slice key and the worktree path.
3
+ description: Implements exactly one ratified event-modeling slice in an assigned worktree and branch and opens its pull request; the engagement skill dispatches it once per slice with only the slice key, the worktree path and, when there is one, a tracking key.
4
4
  tools: Read, Write, Edit, Bash, Grep, Glob, Skill
5
5
  ---
6
6
  <!-- managed by em — `em skill sync` overwrites; `Bash` cannot be partially allowed, so read-only agents rely on their instructions for Bash -->
@@ -18,6 +18,16 @@ You are the em implementer. You build one slice, in one worktree, on one branch,
18
18
  - Write code and tests inside that slice's package, as the constitution's layout rule describes it.
19
19
  - Every invariant and scenario in the slice doc gets a test that cites its `INV-*` id.
20
20
 
21
+ ## Tracking key
22
+
23
+ If your prompt carries a tracking key (an issue-tracker key such as `PROJ-123`, or a URL), the lead has already resolved it for this slice: the slice doc's own `tracking:` wins over the engagement's. Use it as given:
24
+
25
+ - Title the pull request `<key>: <slice name>`.
26
+ - Cite it in the pull request body.
27
+ - Put it in a commit message only when the constitution's commit convention asks for a ticket key.
28
+
29
+ With no tracking key, title the pull request as you would without one and invent none.
30
+
21
31
  ## Hard lines
22
32
 
23
33
  - Never edit the slice doc, the `.em` model, another slice's package, shared infrastructure, or the engagement file.
@@ -29,6 +39,6 @@ You are the em implementer. You build one slice, in one worktree, on one branch,
29
39
 
30
40
  Reply with:
31
41
 
32
- - The pull request URL.
42
+ - The pull request URL (its title carries the tracking key when you were given one).
33
43
  - A per-invariant test map: one line per `INV-*` id, `INV-<id> -> <test file>::<test name>`.
34
44
  - Any gap you stopped on, stated as the doc line and the question.
@@ -9,7 +9,7 @@ You are the em validator. You run checks and report what they say. You make no j
9
9
 
10
10
  ## Scope
11
11
 
12
- You were given a slice key and the worktree path of its pull request. You read output; you never change anything. Use Bash only to run the checks below and read-only git or `gh` commands. Do not write, edit, create, delete, commit, or push anything.
12
+ You were given a slice key and the worktree path of its pull request, and, when the slice has one, a tracking key. You read output; you never change anything. Use Bash only to run the checks below and read-only git or `gh` commands. Do not write, edit, create, delete, commit, or push anything.
13
13
 
14
14
  ## Checks
15
15
 
@@ -21,6 +21,7 @@ Run each one and record pass or fail:
21
21
  4. Diff footprint: every changed path sits inside the slice's package, as the constitution's layout rule describes it. This is a judgment against that rule; quote the rule and list any path outside it.
22
22
  5. No diff under `slices/**`, `*.em`, `constitution.md`, or `engagements/`. Use `git diff --name-only <base>...HEAD`.
23
23
  6. The pull request body cites the slice doc.
24
+ 7. Only when a tracking key was given: the pull request title carries it (`gh pr view <pr> --json title`; the title starts with `<key>:`). Without a tracking key, skip this check and say so.
24
25
 
25
26
  ## Output
26
27
 
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: event-modeling
3
- em-version: 1.14.2
3
+ em-version: 1.16.0
4
4
  description: >-
5
5
  Use when the user runs `/event-modeling` (with or without a phase name), or wants to resume an
6
6
  event-modeling session without specifying which part of the process applies. Reads the model's
7
7
  `.event-modeling.md` state (or the given phase name) and routes to the right focused skill —
8
8
  event-modeling-discover, event-modeling-design, event-modeling-implement, event-modeling-conform,
9
9
  or event-modeling-review — or, for building a planned set of ready slices through scoped
10
- sub-agents to a stack of PRs (an `em engagement`), event-modeling-engagement. If you already
10
+ sub-agents to one PR per slice against main (an `em engagement`), event-modeling-engagement. If you already
11
11
  know which of those applies — starting a new model, extracting from existing code,
12
12
  slicing/writing specs, implementing a ratified slice, leading an engagement, checking drift, or
13
13
  running a live/stakeholder view — invoke that skill directly instead of this one.
@@ -28,7 +28,7 @@ phase lives in.
28
28
  | `implement` | `event-modeling-implement` — building one ratified slice into merged, tested code |
29
29
  | `conform`, `validate` | `event-modeling-conform` — drift-checking a model against its codebase, walking validation diagnostics |
30
30
  | `watch`, `review` | `event-modeling-review` — the live browser viewer, facilitated stakeholder walkthroughs |
31
- | `engagement` | `event-modeling-engagement` — build a planned set of ready slices through scoped sub-agents to a stack of PRs |
31
+ | `engagement` | `event-modeling-engagement` — build a planned set of ready slices through scoped sub-agents to one PR per slice, each against main |
32
32
 
33
33
  ## Routing logic
34
34
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: event-modeling-conform
3
- em-version: 1.14.2
3
+ em-version: 1.16.0
4
4
  description: >-
5
5
  Use when checking a ratified event model (and its slice docs) for drift against the codebase
6
6
  that implements it — advisory only, never a gate, never an unprompted edit — or when walking
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: event-modeling-design
3
- em-version: 1.14.2
3
+ em-version: 1.16.0
4
4
  description: >-
5
5
  Use when structuring a draft event model into swimlanes and the four patterns (State Change,
6
6
  State View, Automation, Translation), evaluating a model's structural completeness, or writing
@@ -51,10 +51,10 @@ evidence"). In short:
51
51
  - **Evidence rule.** The `.em` model and the slice docs are the evidence for modeling
52
52
  decisions. Never read implementation source, generated contracts or `specs/` to decide a
53
53
  modeling question — ask the user. Code is read only in `extract` and `conform`.
54
- - **Version rule.** Never bump a draft's `version:` on edit. Before any `em slice reratify`,
54
+ - **Version rule.** Never bump a draft's `version:` on edit. Before any `em slice revise`,
55
55
  run `em status <model>.em --json`: pre-release = the model's `modelVersion` entry has
56
- `design: null` **and** `slices.byStatus.implemented === 0`. Pre-release → never run
57
- `reratify`; edit `draft`/`reviewed` docs in place. Released → the re-ratification path in
56
+ `design: null` **and** `slices.byStatus.shipped === 0`. Pre-release → never run
57
+ `revise`; edit `draft`/`reviewed` docs in place. Released → the revision path in
58
58
  the `slice` phase below.
59
59
  - **Pre-commit check.** Stage the session's files, run `em system scope --staged` (STOP on any
60
60
  `seam-crossing`), then `git diff --cached --name-only` (STOP on any path outside this model's
@@ -151,7 +151,7 @@ For each slice:
151
151
  it in place and leave its `version:` alone. If `slices/<slice-name>.md` already exists with
152
152
  `status: implemented` (or is ratified and needs a change), run `em status <model>.em --json`
153
153
  first. **Pre-release** (the model's `modelVersion` entry has `design: null` and
154
- `slices.byStatus.implemented === 0`): never run `em slice reratify`; a ratified doc holds a
154
+ `slices.byStatus.shipped === 0`): never run `em slice revise`; a ratified doc holds a
155
155
  human sign-off, so STOP, park the change as an open question, and let the ratifier decide.
156
156
  **Released** (either condition false): a doc with `status: implemented` is a
157
157
  re-ratification, not fresh authoring: hold a Socratic
@@ -212,6 +212,11 @@ For each slice:
212
212
  `--slice-ready` refuses it). A doc written before em 1.14 has no markers; leave it as it is
213
213
  unless you are re-creating it (`em slice new … --wire --force`, carrying the prose across).
214
214
  A question this version will not answer is deferred with `em slice defer <model> <key> "<question>" --until v<n> --decision "<what this version does>"` — never left `- [ ]`, never deleted, never answered by guessing.
215
+ When the question lives on the diagram as an `issue "..."` note rather than on the doc, use
216
+ `em slice defer <model> <key> --from-issue "<text>" --until v<n> --decision "<what this version does>"`
217
+ instead: it writes the deferred item into the doc's Open Questions and removes the note in one
218
+ step. A question that is *answered* is an edit to the authored section plus deleting the note —
219
+ never a deferral.
215
220
  2. **First-time authoring:** scaffold the doc mechanically rather than hand-writing the
216
221
  frontmatter — `em slice new "<slice name>" --pattern <state-change|state-view|automation|
217
222
  translation> --swimlane "<Persona> → <Context>" --wire <model>.em` writes `slices/<slice-name>.md`
@@ -236,23 +241,29 @@ For each slice:
236
241
  lineage key(s) by hand (`split-from`/`merged-from`/`superseded-by`, `<slice-key>@v<N>` grammar
237
242
  — see `../event-modeling-shared/reference/slice-doc-schema.md` for the full schema; `em validate` catches a malformed one
238
243
  after the fact, see the `lineage-*` rules below).
239
- **Re-ratification (step 0) — released models only.** Confirm the model is released first
244
+ **Revision (step 0) — released models only.** Confirm the model is released first
240
245
  (`em status <model>.em --json`: the `modelVersion` entry's `design` is not `null`, or
241
- `slices.byStatus.implemented > 0`); on a pre-release model never run `reratify`. The doc
246
+ `slices.byStatus.shipped > 0`); on a pre-release model never run `revise`. The doc
242
247
  already exists, so `em slice new` doesn't apply here
243
248
  (it refuses to overwrite an existing file without `--force`, and forcing would blow away the
244
- doc's authored body) — run `em slice reratify <model>.em <slice-key>` instead: it bumps
245
- `version` and flips `status` back to `ready-to-implement` in the existing frontmatter,
246
- clearing any stale `ratifiedBy:`/`ratifiedOn:` from the prior version so a follow-up
247
- `em slice ratify --by <name>` (if the team records that) applies cleanly. The same command
248
- changes a ratified doc that **never shipped** (`ready-to-implement` with `ratifiedBy` set — a
249
- gap answered mid-build, MIL-258): it bumps `version` and clears the sign-off but leaves
250
- `status` alone. Either way the doc is not ratified until `em slice ratify --by <name>` records
251
- the new sign-off. A `ready-to-implement` doc with no `ratifiedBy` is already awaiting that
252
- sign-off and refuses a second `reratify`; a `draft`/`reviewed` doc is simply edited, and its
253
- `version:` never moves.
249
+ doc's authored body) — run `em slice revise <model>.em <slice-key>` instead (MIL-283): it
250
+ opens the next version as a **`draft`** in the existing frontmatter — `version` bumped,
251
+ `status: draft`, the prior version's review and sign-off cleared — while the shipped version
252
+ stays shipped in the shipped record (`implementedIn:`/`shippedVersion:`, untouched). If a
253
+ question was deferred to this version, `em slice mark-implemented` already opened the draft
254
+ at merge and the question is back on the list; `revise` then refuses ("the next version is
255
+ already open") and you simply edit. The same command revises a ratified doc that **never
256
+ shipped** (`ready-to-implement` with `ratifiedBy` set — a gap answered mid-build): the
257
+ ratification is withdrawn and the draft opens. Either way the new version is a new spec:
258
+ write the delta into `## Delta`, walk it in a review session (`em slice review --by`), and
259
+ only then does `em slice ratify --by <name>` sign it. **Commit before ratifying (MIL-284):**
260
+ `em slice ratify` records the commit and body hash it signs and refuses a doc with uncommitted
261
+ changes — finish the doc's edits (deferrals included: `em slice defer` rewrites a body line, so
262
+ a deferral after sign-off trips `slice-ready-body-changed-since-ratification`), commit, then
263
+ ratify. A `draft`/`reviewed` doc is simply edited, and its `version:` never moves.
254
264
  **Public-touching slices (MIL-238).** On a slice that owns a `public` command, event or view,
255
- `em slice ratify --by <name>` and `em slice reratify` refuse without one of two flags: pass
265
+ `em slice ratify --by <name>` refuses without one of two flags (`revise` takes neither — the
266
+ confirmation belongs to the new version's ratification): pass
256
267
  `--meaning-unchanged` when this version does not change what the public contract means, or
257
268
  `--contract-change "<why>"` when a consumer must read the change differently. Without
258
269
  either, both refuse with `slice "<key>" touches the public surface — pass
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: event-modeling-discover
3
- em-version: 1.14.2
3
+ em-version: 1.16.0
4
4
  description: >-
5
5
  Use when starting a brand-new event model from scratch — greenfield discovery: brainstorming
6
6
  past-tense events, storyboarding the happy path, finding the commands and read models — or when
@@ -1,24 +1,32 @@
1
1
  ---
2
2
  name: event-modeling-engagement
3
- em-version: 1.14.2
3
+ em-version: 1.16.0
4
4
  description: >-
5
5
  Use when leading an engagement: building a named set of ratified event-modeling slices
6
- (`em engagement`) into a stack of PRs by dispatching the em-implementer, em-validator,
7
- em-reviewer and em-critic sub-agents, level by level, and handing the human the stack
8
- bottom-first to merge. The lead session orchestrates and never writes slice code itself. To
9
- build one slice by hand, use event-modeling-implement instead.
6
+ (`em engagement`) into one independent PR per slice, each against main, by dispatching the
7
+ em-implementer, em-validator, em-reviewer and em-critic sub-agents, level by level, and handing
8
+ the human each PR with its evidence as it passes review. The lead session orchestrates and never
9
+ writes slice code itself. To build one slice by hand, use event-modeling-implement instead.
10
10
  ---
11
11
 
12
12
  # Event Modeling — engagement (lead session)
13
13
 
14
14
  Goal: take an engagement (a named chunk of the model, `<model dir>/engagements/<slug>.md`) from
15
15
  its plan to merged PRs. You are the **lead**: you cut worktrees, dispatch scoped sub-agents,
16
- record every step in the Ledger with `em engagement set`, and hand the human a stack of PRs to
17
- merge bottom-first. You never write slice code, never merge, and never rebase a slice branch.
16
+ record every step in the Ledger with `em engagement set`, and hand the human one PR per slice,
17
+ each cut from and targeting `main`, to merge in any order. You never write slice code, never
18
+ merge, and never rebase a slice branch.
19
+
20
+ An engagement is a *related set* of isolated slices — a workflow, a lifecycle — built together.
21
+ It is not a stack: no slice branch is ever cut from another slice's branch, and no PR ever
22
+ targets another PR (MIL-280). The foundation PR (implement.md §8) already holds every event, and
23
+ a slice never reaches into a sibling's code (§8 rule 3), so each PR compiles, tests and merges
24
+ on its own. Levels order the work for the human's review and your dispatch; they never gate a
25
+ merge.
18
26
 
19
27
  **Read `reference/engagement.md` before the first dispatch.** It holds the Ledger state machine,
20
- the evidence bundle format, the retarget check, the gap protocol and the model-selection rule
21
- this file uses by name. Each sub-agent runs `event-modeling-implement`'s contract
28
+ the evidence bundle format, the gap protocol and the model-selection rule this file uses by
29
+ name. Each sub-agent runs `event-modeling-implement`'s contract
22
30
  (`../event-modeling-implement/reference/implement.md`) for its one slice; that contract is
23
31
  theirs, not yours.
24
32
 
@@ -42,21 +50,17 @@ Run the shared preconditions first (tool check, bundle currency, locate the mode
42
50
  2. **Foundation PR merged.** Ask the human for the foundation PR (implement.md §8) and confirm it
43
51
  has merged into `main` (`gh pr view <n> --json state` shows `MERGED`). STOP if there is none
44
52
  or it is still open. No slice branch is cut before it lands.
45
- 3. **Merge strategy.** The constitution's "Review and merge norms" must carry the line
46
- `- **Merge strategy:** merge-commits-when-stacked`. STOP if the line is absent or names any
47
- other value: tell the human the engagement needs that norm and point at the constitution
48
- template's "Review and merge norms" prompt
49
- (`../event-modeling-shared/templates/constitution.md`). The constitution is the human's to
50
- amend and ratify, never yours.
51
- 4. **Agent models.** Read the line `- **Agent models:** implementer=<model>,
53
+ 3. **Agent models.** Read the line `- **Agent models:** implementer=<model>,
52
54
  validator=<model>, reviewer=<model>, critic=<model|codex>`. If it is absent, say once:
53
55
  "no Agent models line — using implementer=sonnet, validator=sonnet, reviewer=sonnet,
54
56
  critic=opus", and proceed. Apply the model-selection rule in `reference/engagement.md`
55
- (the critic never runs on the implementer's model).
56
- 5. **Worktrees are ignored.** `git check-ignore -q .claude/worktrees/x` must succeed. If it
57
+ (the critic never runs on the implementer's model). A constitution that still carries a
58
+ `- **Merge strategy:**` line from em ≤ 1.14.2 is fine: the line is ignored, never a reason to
59
+ stop — PRs merge with whatever strategy the project uses.
60
+ 4. **Worktrees are ignored.** `git check-ignore -q .claude/worktrees/x` must succeed. If it
57
61
  fails, STOP and ask the human to add `.claude/worktrees/` to `.gitignore` in its own commit
58
62
  on `main`.
59
- 6. **The engagement exists.** `em engagement status <model>.em <slug>`. If there is no such
63
+ 5. **The engagement exists.** `em engagement status <model>.em <slug>`. If there is no such
60
64
  engagement, ask the human which slices it covers (a list, a context, or "everything
61
65
  downstream of X") and run `em engagement new <model>.em <slug> --slices a,b,c` (or
62
66
  `--context <C>`, or `--downstream-of <ref>`) `--by "<their name>"`. When `new` warns that the
@@ -66,9 +70,9 @@ Run the shared preconditions first (tool check, bundle currency, locate the mode
66
70
  ## 2. Plan and confirm the ceiling once
67
71
 
68
72
  Run `em engagement plan <model>.em <slug>` (`--json` when you need the fields). Present it in
69
- plain terms: each level, its width against the ceiling (`parallel`), each slice's branch and
70
- base, and every held slice with its reason (`not-ready`, `upstream-outside-engagement-unmerged`,
71
- `multiple-unmerged-upstreams`, or `human`). Then ask exactly one question:
73
+ plain terms: each level, its width against the ceiling (`parallel`), each slice's branch (every
74
+ base is `main`), and every held slice with its reason (`not-ready`,
75
+ `upstream-outside-engagement-unmerged`, or `human`). Then ask exactly one question:
72
76
 
73
77
  > "Ceiling N from the plan; proceed?"
74
78
 
@@ -78,13 +82,14 @@ A held slice is never started; the plan releases it when its hold clears.
78
82
 
79
83
  ## 3. Per level: cut the worktree, then dispatch the implementer
80
84
 
81
- Work level by level, in order. A slice in level n+1 starts only when its upstream has reached
82
- `awaiting-merge` or `merged`, so the base it is cut from no longer moves. Within a level, keep up
83
- to the ceiling of slices in flight (`building`, `validating` or `review`) at once, dispatched in
84
- parallel. For each slice the plan lists as not held:
85
+ Work level by level, in order: a level's slices are dispatched before the next level's, so the
86
+ human sees upstream slices first. Nothing in level n+1 waits for a merge — every slice is cut
87
+ from `main`. Keep up to the ceiling of slices in flight (`building`, `validating` or `review`)
88
+ at once, dispatched in parallel; when a slot frees, take the next not-held slice in level order.
89
+ For each slice the plan lists as not held:
85
90
 
86
- 1. Take `base` from the plan for this slice: `main`, or `impl/<upstream>`. **Never the current
87
- HEAD**, and never a branch you picked yourself.
91
+ 1. Take `base` from the plan for this slice. It is always `main`. **Never the current HEAD**,
92
+ never another slice's branch, and never a branch you picked yourself.
88
93
  2. If `impl/<key>` already exists (`git rev-parse --verify --quiet impl/<key>`) or
89
94
  `.claude/worktrees/<key>` already exists, STOP for that slice and report it. Never delete,
90
95
  reuse or reset someone's branch.
@@ -93,19 +98,22 @@ parallel. For each slice the plan lists as not held:
93
98
  4. Record it:
94
99
  `em engagement set <model>.em <slug> <key> --state building --branch impl/<key> --base <base>`
95
100
  5. Dispatch `em-implementer` (`em:em-implementer` under the plugin) on the implementer model.
96
- Its prompt is ONLY the slice key and the absolute worktree path. It reads its own spec, the
97
- constitution and the implement contract. Give it no plan, no other slice, and no merge or
98
- stacking instructions.
101
+ Its prompt is ONLY the slice key, the absolute worktree path and, when the plan's slice
102
+ carries one, its tracking key (`tracking` in `em engagement plan --json` — GH #241). That
103
+ field is already resolved: the slice doc's own `tracking:` wins over the engagement's
104
+ `--tracking`, and it is `null` when neither is set (then say nothing about tracking). It reads
105
+ its own spec, the constitution and the implement contract. Give it no plan, no other slice,
106
+ and no merge instructions.
99
107
 
100
108
  ## 4. Validate, review, criticise
101
109
 
102
110
  When the implementer returns a PR URL (and a per-invariant test map):
103
111
 
104
112
  1. `em engagement set <model>.em <slug> <key> --state validating --pr <url>`. Check the PR's
105
- base: `gh pr view <url> --json baseRefName` must equal the Ledger's base. If not, fix it
106
- with `gh pr edit <url> --base <base>`. That is a lead step; the implementer never changes a
107
- base.
108
- 2. Dispatch `em-validator` (`em:em-validator`) with the slice key and the worktree path. It
113
+ base: `gh pr view <url> --json baseRefName` must be `main`. If not, fix it with
114
+ `gh pr edit <url> --base main`. That is a lead step; the implementer never changes a base.
115
+ 2. Dispatch `em-validator` (`em:em-validator`) with the slice key, the worktree path and the same
116
+ tracking key (when the slice has one). It
109
117
  returns one PASS/FAIL line per check and `OVERALL: PASS` or a failure.
110
118
  3. On `OVERALL: PASS`: `em engagement set <model>.em <slug> <key> --state review`. Dispatch
111
119
  `em-reviewer` (`em:em-reviewer`) with the slice key and the PR URL. Dispatch `em-critic`
@@ -125,36 +133,31 @@ When the implementer returns a PR URL (and a per-invariant test map):
125
133
  human.
126
134
  6. `minor` findings do not loop. They go in the evidence bundle.
127
135
 
128
- ## 5. Hand the human the stack, bottom first
136
+ ## 5. Hand the human each PR as it passes
129
137
 
130
138
  When a slice passes review: `em engagement set <model>.em <slug> <key> --state awaiting-merge`.
131
- Hand the human the PRs bottom-first, lowest level first, each with its evidence bundle
132
- (`reference/engagement.md`): the validator table, the reviewer's and critic's findings and any
133
- disagreement, and the per-invariant test map. Tell them, every time:
134
-
135
- - merge bottom-first, with a **merge commit** while any PR stacks on this one (implement.md §8
136
- rule 2a). Squash is forbidden in that state;
137
- - delete the head branch on merge, so GitHub retargets the PRs that stacked on it.
139
+ Hand the human the PR with its evidence bundle (`reference/engagement.md`): the validator table,
140
+ the reviewer's and critic's findings and any disagreement, and the per-invariant test map. Every
141
+ PR is independent — against `main`, carrying only its own slice — so the human merges them in
142
+ any order, with the project's usual merge strategy (squash included), and nothing else needs
143
+ retargeting or restacking. Suggest level order (upstream slices first) because it reads better,
144
+ not because anything depends on it.
138
145
 
139
146
  You never merge.
140
147
 
141
148
  ## 6. After each human merge
142
149
 
143
150
  1. Update `main` in your own checkout: `git switch main && git pull --ff-only`.
144
- 2. **Retarget check** (`reference/engagement.md`): `gh pr list --base impl/<key> --state open`
145
- must be empty. For each PR still listed (the head branch was not deleted),
146
- `gh pr edit <n> --base main`. Then record the new base on each dependent, keeping its state:
147
- `em engagement set <model>.em <slug> <dependent> --state <its state> --base main`.
148
- 3. `em engagement set <model>.em <slug> <key> --state merged`, then remove the worktree:
151
+ 2. `em engagement set <model>.em <slug> <key> --state merged`, then remove the worktree:
149
152
  `git worktree remove .claude/worktrees/<key>`.
150
- 4. When every slice of a level is `merged` or `gap`, open one follow-up PR for that level from
153
+ 3. When every slice of a level is `merged` or `gap`, open one follow-up PR for that level from
151
154
  `main`: `git switch -c engagement/<slug>-level-<n> main`, run
152
155
  `em slice mark-implemented <model>.em <key> <pr-url>` for each slice merged in the level,
153
156
  then `em slice index <model>.em`, commit, and `gh pr create --base main`. The human merges it
154
157
  like any other PR.
155
- 5. Recompute: `em engagement plan <model>.em <slug>`. Merges release holds
156
- (`multiple-unmerged-upstreams` drops to one upstream, a base moves to `main`). Continue with
157
- step 3 for anything newly startable.
158
+ 4. Recompute: `em engagement plan <model>.em <slug>`. A merge can release an
159
+ `upstream-outside-engagement-unmerged` hold once that upstream's doc reads `implemented`.
160
+ Continue with step 3 for anything newly startable.
158
161
 
159
162
  ## 7. Gaps
160
163
 
@@ -182,11 +185,12 @@ constitution), follow the gap protocol (`reference/engagement.md`):
182
185
  | Rule | Because |
183
186
  |---|---|
184
187
  | Never hand-edit `engagements/<slug>.md` | `em engagement set` and `close` are the only write paths; the Ledger table is generated |
185
- | Never restack or rebase a slice branch | Merge commits make restacking unnecessary; a rebase rewrites history a dependent was cut from |
186
- | Never squash a PR with an open dependent | It strands the dependent's history (implement.md §8 rule 2a) |
188
+ | Never cut a slice branch from another slice's branch, or make a PR target another PR | Every slice PR is cut from and targets `main` (MIL-280); a stack turns isolated slices into one landing and adds merge ceremony the contract never needed |
189
+ | Never rebase a slice branch | The branch is the implementer's; the lead orchestrates and records, it does not rewrite history |
187
190
  | Never run the implementer's work yourself | The lead orchestrates; code comes from a scoped implementer working from its own read of the spec |
188
191
  | Never dispatch beyond the ceiling | The ceiling was confirmed once for the engagement; exceeding it breaks that agreement |
189
- | Never cut a slice branch from the current HEAD | The base comes from the plan; any other base stacks the PR on the wrong history |
190
- | Never merge a PR | The human merges, bottom-first |
192
+ | Never cut a slice branch from the current HEAD | The base is `main` from the plan; the lead's HEAD may be anything |
193
+ | Never hold a PR back for an upstream merge | Slices do not depend on each other's branches (§8 rules 2 and 3); level order is for reading, not gating |
194
+ | Never merge a PR | The human merges, in any order |
191
195
  | Never show the critic the reviewer's findings | The critic's value is an independent view; disagreement is a finding |
192
196
  | Never start a held slice, or ask "which slice first" | The plan decides order and holds; the human confirms only the ceiling |
@@ -26,17 +26,17 @@ closed engagement refuses every `set`.
26
26
  `em engagement close <model>.em <slug>` succeeds only when every slice is `merged` (recorded or
27
27
  inferred) or `gap`; `em engagement status` reports this as `closable`.
28
28
 
29
- A dependent's base changes once, when its upstream merges: record it with the dependent's
30
- current state and `--base main` (step 6.2), so the Ledger matches the PR's real base.
29
+ Every slice's `base` is `main` (MIL-280): recorded once at `building`, never changed. A Ledger
30
+ that still shows an `impl/<upstream>` base came from em ≤ 1.14.2; `plan` reports `main` and the
31
+ next `set` on that slice should record `--base main`.
31
32
 
32
33
  ## The evidence bundle (step 5)
33
34
 
34
- Hand the human one block per PR, bottom-first, in this shape:
35
+ Hand the human one block per PR as it passes review, in this shape:
35
36
 
36
37
  ```markdown
37
38
  ### <level n> · `<key>` · <PR URL>
38
- Base: `<base>` · Ledger: awaiting-merge · Stacked on it: <PR URLs of open dependents, or "none">
39
- Merge with: a merge commit (<a dependent is open | squash allowed: no open dependent>)
39
+ Base: `main` · Ledger: awaiting-merge · Independent: merges in any order with the project's usual strategy
40
40
 
41
41
  Validator (em-validator, <model>):
42
42
  | Check | Result |
@@ -60,20 +60,6 @@ Per-invariant tests (from em-implementer):
60
60
 
61
61
  Copy the agents' lines verbatim; never summarise a finding away.
62
62
 
63
- ## The retarget check (step 6.2)
64
-
65
- GitHub retargets every open PR whose base was a merged head branch to the merged PR's base, but
66
- only when that head branch is deleted. After each merge of `impl/<key>`:
67
-
68
- 1. `gh pr list --base impl/<key> --state open --json number,headRefName` must return `[]`.
69
- 2. For each PR it does list, run `gh pr edit <number> --base main`. Then record it:
70
- `em engagement set <model>.em <slug> <dependent> --state <its current state> --base main`.
71
- 3. Confirm with `gh pr view <number> --json baseRefName`.
72
-
73
- Because the lower PR merged with a merge commit, the dependent's diff against `main` shrinks to
74
- its own commits by itself. Never rebase it. If its diff still shows the upstream's commits, the
75
- lower PR was squashed: STOP and tell the human. Restacking that PR is their decision.
76
-
77
63
  ## The gap protocol (step 7)
78
64
 
79
65
  A gap is a question only the model can answer: the doc is wrong, incomplete, or contradicts the
@@ -88,6 +74,14 @@ constitution. The implementer stops and reports it as the doc line plus the ques
88
74
  4. Carry on with every other startable slice. Never answer the question yourself, never edit the
89
75
  doc, and never let the implementer guess.
90
76
 
77
+ A question the build can finish without (it does not block the slice) is not a gap: queue it with
78
+ `em slice defer <model>.em <key> "<question>" --until v<n> --decision "<what this version does>"`
79
+ (GH #236). On a ratified doc that never edits the body — `ratifiedHash` and `--slice-ready` stay
80
+ green — and records the question in `.event-modeling.md` for `<key>@v<N+1>`; `mark-implemented`
81
+ at merge opens v<N+1> as a draft with it in Open Questions. Never write the `- [ ]` into the
82
+ ratified doc, and do not run `em slice revise` for it (an unshipped ratified doc refuses
83
+ `revise` without `--withdraw`).
84
+
91
85
  The question is answered in a design session (`event-modeling-design`), which re-ratifies the
92
86
  doc. The slice is then built in a later engagement.
93
87
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: event-modeling-implement
3
- em-version: 1.14.2
3
+ em-version: 1.16.0
4
4
  description: >-
5
5
  Use when building a single ratified event-modeling slice (status: ready-to-implement) into
6
6
  merged, tested code — the one phase where the agent builds rather than facilitates. Gates on
@@ -34,8 +34,8 @@ em-sdd-bridge (redirect mode) and never run `/speckit.specify`.
34
34
  **Gate: no constitution, no first slice.** The constitution is the project's ratified house rules
35
35
  — stack and architectural shape (including which implementation skill each slice pattern routes
36
36
  to), code style, testing norms, NFR baselines, review/merge norms. It lives at
37
- `.specify/memory/constitution.md` in a spec-kit project, otherwise `constitution.md` beside the
38
- model; `em status` reports which, and whether it's there. If it's missing — or its `ratifiedBy:`
37
+ `.specify/memory/constitution.md` in a spec-kit project (when that file exists), otherwise
38
+ `constitution.md` beside the model; `em status` reports which, and whether it's there. If it's missing — or its `ratifiedBy:`
39
39
  is empty, meaning nobody has signed it off — run `reference/implement.md` §7 ("Before the first
40
40
  slice: the constitution") first: ask its questions conversationally, write the answers in, and
41
41
  have a human ratify them. Don't decide the project's stack or style yourself to get moving.
@@ -48,12 +48,14 @@ facilitated session, not in an implementation branch.
48
48
 
49
49
  **First, read the project's constitution** — the house rules for *how* implementation happens
50
50
  here (stack and architectural shape, which implementation skill each slice pattern routes to,
51
- code style, testing norms, NFR baselines, review and merge norms). It lives in one of exactly two
52
- places, never both:
51
+ code style, testing norms, NFR baselines, review and merge norms). It lives in one place, found by
52
+ one lookup (shared by `em status` and `em upgrade`):
53
53
 
54
54
  - **spec-kit project** (a `.specify/` directory exists at or above the model):
55
- `.specify/memory/constitution.md` — spec-kit's own slot, which em defers to.
56
- - **anything else**: `constitution.md` beside the model, where `em scaffold` writes it.
55
+ `.specify/memory/constitution.md` — spec-kit's own slot, which em defers to — wins whenever it
56
+ exists.
57
+ - **otherwise, or while that slot is empty**: `constitution.md` beside the model, where
58
+ `em scaffold` writes it (a symlink to a repo-root file counts).
57
59
 
58
60
  `em status <model>.em --json` reports which one applies and whether it's there
59
61
  (`conformance[].constitution`) — existence only; nothing in `em` reads or judges its content.
@@ -157,12 +159,23 @@ undocumented ordering, a contradiction with adjacent code. The discipline:
157
159
  your recommendation. The human resolves it — at the model, where the resolution lands as an
158
160
  answered open question or a small ratified delta alongside your fix, so the decision is
159
161
  recorded instead of buried in an implementation diff.
162
+ - **A question this build will not wait on is queued, never written into the doc** (GH #236). On a
163
+ ratified doc the body is the signed spec: `em slice defer <model>.em <slice-key> "<question>"
164
+ --until v<n> --decision "<what this version does>"` records it in `.event-modeling.md` as queued
165
+ for `<key>@v<N+1>` and leaves the doc — and `ratifiedHash`, and `--slice-ready` — untouched. When
166
+ the slice merges (`mark-implemented`) or is revised, the queued question is injected into the
167
+ v<N+1> draft's Open Questions. Never add the `- [ ]` item to the ratified doc yourself.
160
168
  - **How a delta is ratified on a doc that never shipped** (it is `ready-to-implement` with
161
- `ratifiedBy` set): once the human has answered, the doc changes by `em slice reratify
162
- <model>.em <slice-key>` (bumps `version:`, clears the old sign-off, leaves `status` alone),
163
- the answer is written into the doc, and the human re-signs with `em slice ratify <model>.em
164
- <slice-key> --by <name>` — on a slice owning a `public` element both commands also need
165
- `--meaning-unchanged` or `--contract-change "<why>"` (MIL-238). That is the human's step, not
169
+ `ratifiedBy` set) when the spec itself must change: once the human has answered, the doc changes
170
+ by `em slice revise <model>.em <slice-key> --withdraw` (MIL-283: opens the next version as a
171
+ `draft` — `version:` bumped, the old sign-off cleared; the ratification of the unshipped version
172
+ is withdrawn, which is why GH #236 makes you pass `--withdraw` — plain `revise` refuses),
173
+ the answer is written into the doc and committed, the room reviews it (`em slice review
174
+ --by`), and the human re-signs with `em slice ratify
175
+ <model>.em <slice-key> --by <name>` (it records the commit it signs and refuses uncommitted
176
+ changes, MIL-284) — on a slice owning a `public` element that `ratify` also needs
177
+ `--meaning-unchanged` or `--contract-change "<why>"` (MIL-238; `revise` takes neither — the
178
+ confirmation belongs to the new version's sign-off). That is the human's step, not
166
179
  yours — you never run `ratify`, and
167
180
  the doc is not ratified again until they do; resume the build after that.
168
181
  - **Never edit the ratified doc to record your own answer**, and never quietly pick a behavior
@@ -231,7 +244,13 @@ with the same URL, and refuses (never silently overwrites) if the doc is already
231
244
  with a different URL. It also refuses a doc that isn't `ready-to-implement` (MIL-277): if it
232
245
  reports `doc is \`status: draft\``/`reviewed`, the slice was never ratified — stop and surface
233
246
  that to the human rather than editing the frontmatter by hand; the §1 gate should have caught it.
234
- Prefer it over hand-editing the doc's frontmatter.
247
+ Prefer it over hand-editing the doc's frontmatter. It also writes the **shipped record**
248
+ (`shippedVersion:`/`shippedRef:`/`shippedOn:`, MIL-284) — what every reader decides "has this
249
+ shipped?" on since 1.15.0 — and, when the ratified doc deferred a question to the next version,
250
+ **opens that version as a `draft` on the same write** (MIL-283: `status: draft`, `version` bumped,
251
+ the question back to `- [ ]`; the version you built stays shipped) — questions queued with `em slice
252
+ defer` while the doc was ratified (GH #236) are injected into that draft too. If it prints `opened draft
253
+ v<N+1>`, say so in your report: the slice has known work, and a design session, not you, decides it.
235
254
 
236
255
  Then, if the project keeps a model README (from `../../event-modeling-shared/templates/model-readme.md`), run
237
256
  `em slice index <model-name>.em` so its generated Slices table reflects the new status and
@@ -311,23 +330,17 @@ sibling slice's package to reuse it — the boundary the constitution drew is go
311
330
  contract into a pre-empted slice.
312
331
  2. **It merges before any slice PR opens.** Every slice branch is cut *after* the foundation PR
313
332
  has landed on `main` — never from a commit that predates it, and never alongside an open,
314
- unmerged foundation PR. Within an engagement, cut the slice branch from the base the
315
- engagement plan names (`em engagement plan`); outside an engagement, from `main`. A slice PR
316
- never carries foundation files. Because: a slice PR opened while the foundation is still in
317
- review shows a diff dominated by files the slice didn't write and can't be held accountable
318
- for, and its merge depends on someone else's review timeline instead of its own. The plan's
319
- base is either `main` or `impl/<upstream>` (the one unmerged upstream slice this slice builds
320
- on); either way it already contains the foundation.
321
-
322
- 2a. **While a dependent PR is open, the lower PR merges with a merge commit; squash is forbidden
323
- in that state (it strands the dependent's history).** A PR is the *lower* one when another
324
- open PR targets its branch as its base. Once no open PR depends on it, the project's usual
325
- merge strategy applies. Because: a squash rewrites the lower branch's commits into one new
326
- commit on `main`, so the dependent branch still carries the originals and its diff against
327
- `main` shows them again — it then needs a hand rebase (`git rebase --onto main <old base
328
- tip>`). A merge commit keeps the original commits: once the lower branch is merged and
329
- deleted, the dependent is retargeted to `main` and its diff shrinks to its own commits with
330
- no rebase.
333
+ unmerged foundation PR. Every slice branch is cut from `main` and every slice PR targets
334
+ `main` — inside an engagement (`em engagement plan` names `main` as every slice's base) and
335
+ outside one alike; never from another slice's branch, never targeting another slice's PR. A
336
+ slice PR never carries foundation files. Because: a slice PR opened while the foundation is
337
+ still in review shows a diff dominated by files the slice didn't write and can't be held
338
+ accountable for, and its merge depends on someone else's review timeline instead of its own.
339
+ And because the foundation already holds every event and rule 3 keeps a slice out of its
340
+ siblings' code, no slice needs another slice's branch to compile or test: a PR cut from a
341
+ sibling's branch (a "stack") carries a dependency this contract forbids, and turns N isolated
342
+ slices into one landing with merge-commit and retargeting ceremony attached. `main` already
343
+ contains the foundation; that is all a slice needs.
331
344
 
332
345
  3. **A slice never creates, edits, or reaches into another slice's code.** It *imports* events —
333
346
  only events — from wherever the foundation placed them; a sibling slice's handlers, storage,
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: event-modeling-review
3
- em-version: 1.14.2
3
+ em-version: 1.16.0
4
4
  description: >-
5
5
  Use when starting em's live browser viewer (`em watch --serve`) so a team can watch a model
6
6
  update in real time, or facilitating a SCHEDULED stakeholder walkthrough that steps through
@@ -53,10 +53,20 @@ walk each one with the user, same as any open issue. Update the state file's Par
53
53
  section with who attended, and run `em state set-review <date>` to set the `Last stakeholder
54
54
  review:` marker (mirrors `Last conformance:`).
55
55
 
56
- **Per-slice outcome.** A slice whose open questions are all resolved in the room →
56
+ **Per-slice outcome.** Walk the slice's questions — the doc's `## Open Questions` and every
57
+ `issue "..."` note the room added to its elements — and give each one of three endings:
58
+
59
+ - **Answered in the room** → edit the doc's authored section with the answer and delete the
60
+ `issue` note by hand. Defer is never used to record an answer.
61
+ - **Raised in the room, not for this version** → `em slice defer <model> <key> --from-issue "<text>" --until v<n> --decision "<what this version does>"`:
62
+ promotes the captured `issue` into the doc's Open Questions as a deferred item, mirrors it
63
+ into the state file and removes the red note — one command, no hand edit mid-session.
64
+ - **Already on the doc, not for this version** → the positional form. A question this version will not answer is deferred with `em slice defer <model> <key> "<question>" --until v<n> --decision "<what this version does>"` — never left `- [ ]`, never deleted, never answered by guessing.
65
+
66
+ Then, and only then: a slice with nothing left `- [ ]` and no open `issue` →
57
67
  `em slice review <model>.em <key> --by <name>` (flips its doc to `status: reviewed` and records
58
68
  `reviewedBy:`/`reviewedOn:`). Anything still open stays `draft` — the walkthrough doesn't decide
59
- it, the next session or the open-questions list does. A question this version will not answer is deferred with `em slice defer <model> <key> "<question>" --until v<n> --decision "<what this version does>"` — never left `- [ ]`, never deleted, never answered by guessing.
69
+ it, the next session or the open-questions list does.
60
70
 
61
71
  **The facilitator never ratifies, never offers to ratify, and never suggests ratification in a
62
72
  review session. Ratification is a separate human gate after review**