@milehimikey/em 1.14.1 → 1.15.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 (98) hide show
  1. package/.claude/skills/event-modeling/SKILL.md +3 -3
  2. package/.claude/skills/event-modeling-conform/SKILL.md +1 -1
  3. package/.claude/skills/event-modeling-design/SKILL.md +29 -18
  4. package/.claude/skills/event-modeling-discover/SKILL.md +1 -1
  5. package/.claude/skills/event-modeling-engagement/SKILL.md +54 -54
  6. package/.claude/skills/event-modeling-engagement/reference/engagement.md +5 -19
  7. package/.claude/skills/event-modeling-implement/SKILL.md +1 -1
  8. package/.claude/skills/event-modeling-implement/reference/implement.md +29 -23
  9. package/.claude/skills/event-modeling-review/SKILL.md +13 -3
  10. package/.claude/skills/event-modeling-shared/reference/em-dsl.md +230 -227
  11. package/.claude/skills/event-modeling-shared/reference/operating-principles.md +3 -3
  12. package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +58 -27
  13. package/.claude/skills/event-modeling-shared/templates/constitution.md +5 -7
  14. package/.claude-plugin/marketplace.json +2 -2
  15. package/README.md +12 -0
  16. package/dist/catalog/docJoin.d.ts +17 -1
  17. package/dist/catalog/docJoin.js +7 -1
  18. package/dist/catalog/docJoin.js.map +1 -1
  19. package/dist/catalog/driftSignal.d.ts +16 -12
  20. package/dist/catalog/driftSignal.js +14 -9
  21. package/dist/catalog/driftSignal.js.map +1 -1
  22. package/dist/catalog/sliceDoc.d.ts +51 -0
  23. package/dist/catalog/sliceDoc.js +47 -0
  24. package/dist/catalog/sliceDoc.js.map +1 -1
  25. package/dist/catalog/sliceReadyValidate.js +12 -0
  26. package/dist/catalog/sliceReadyValidate.js.map +1 -1
  27. package/dist/cli/conformScope.d.ts +4 -0
  28. package/dist/cli/conformScope.js +2 -2
  29. package/dist/cli/conformScope.js.map +1 -1
  30. package/dist/cli/coverage.js +7 -3
  31. package/dist/cli/coverage.js.map +1 -1
  32. package/dist/cli/defer.d.ts +61 -2
  33. package/dist/cli/defer.js +204 -23
  34. package/dist/cli/defer.js.map +1 -1
  35. package/dist/cli/engagement.d.ts +13 -5
  36. package/dist/cli/engagement.js +26 -19
  37. package/dist/cli/engagement.js.map +1 -1
  38. package/dist/cli/findings.d.ts +2 -2
  39. package/dist/cli/findings.js +2 -2
  40. package/dist/cli/frontmatterSurgery.d.ts +3 -3
  41. package/dist/cli/frontmatterSurgery.js +3 -3
  42. package/dist/cli/frontmatterSurgery.js.map +1 -1
  43. package/dist/cli/markImplemented.d.ts +20 -9
  44. package/dist/cli/markImplemented.js +112 -14
  45. package/dist/cli/markImplemented.js.map +1 -1
  46. package/dist/cli/ratify.d.ts +36 -6
  47. package/dist/cli/ratify.js +130 -35
  48. package/dist/cli/ratify.js.map +1 -1
  49. package/dist/cli/review.js +3 -3
  50. package/dist/cli/review.js.map +1 -1
  51. package/dist/cli/revise.d.ts +57 -0
  52. package/dist/cli/revise.js +207 -0
  53. package/dist/cli/revise.js.map +1 -0
  54. package/dist/cli/sliceConform.d.ts +4 -3
  55. package/dist/cli/sliceConform.js +29 -12
  56. package/dist/cli/sliceConform.js.map +1 -1
  57. package/dist/cli/status.d.ts +8 -0
  58. package/dist/cli/status.js +7 -4
  59. package/dist/cli/status.js.map +1 -1
  60. package/dist/cli/upgrade.js +7 -4
  61. package/dist/cli/upgrade.js.map +1 -1
  62. package/dist/cli.js +118 -77
  63. package/dist/cli.js.map +1 -1
  64. package/dist/emit/json.d.ts +1 -1
  65. package/dist/emit/json.js +13 -1
  66. package/dist/emit/json.js.map +1 -1
  67. package/dist/emit/statusJson.d.ts +1 -1
  68. package/dist/emit/statusJson.js +4 -1
  69. package/dist/emit/statusJson.js.map +1 -1
  70. package/dist/mcp/server.js +5 -5
  71. package/dist/mcp/server.js.map +1 -1
  72. package/dist/model/rules.d.ts +8 -0
  73. package/dist/model/rules.js +8 -0
  74. package/dist/model/rules.js.map +1 -1
  75. package/dist/model/sliceDocIndex.d.ts +3 -0
  76. package/dist/model/sliceDocIndex.js +5 -4
  77. package/dist/model/sliceDocIndex.js.map +1 -1
  78. package/dist/templates.d.ts +1 -1
  79. package/dist/templates.js +5 -7
  80. package/dist/templates.js.map +1 -1
  81. package/package.json +2 -2
  82. package/plugin/.claude-plugin/plugin.json +2 -2
  83. package/plugin/shared/reference/em-dsl.md +230 -227
  84. package/plugin/shared/reference/operating-principles.md +3 -3
  85. package/plugin/shared/reference/slice-doc-schema.md +58 -27
  86. package/plugin/shared/templates/constitution.md +5 -7
  87. package/plugin/skills/conform/SKILL.md +1 -1
  88. package/plugin/skills/design/SKILL.md +29 -18
  89. package/plugin/skills/discover/SKILL.md +1 -1
  90. package/plugin/skills/engagement/SKILL.md +54 -54
  91. package/plugin/skills/engagement/reference/engagement.md +5 -19
  92. package/plugin/skills/event-modeling/SKILL.md +3 -3
  93. package/plugin/skills/implement/SKILL.md +1 -1
  94. package/plugin/skills/implement/reference/implement.md +29 -23
  95. package/plugin/skills/review/SKILL.md +13 -3
  96. package/dist/cli/reratify.d.ts +0 -58
  97. package/dist/cli/reratify.js +0 -238
  98. package/dist/cli/reratify.js.map +0 -1
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: event-modeling
3
- em-version: 1.14.1
3
+ em-version: 1.15.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.1
3
+ em-version: 1.15.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.1
3
+ em-version: 1.15.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.1
3
+ em-version: 1.15.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.1
3
+ em-version: 1.15.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.
@@ -94,17 +99,16 @@ parallel. For each slice the plan lists as not held:
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
101
  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.
102
+ constitution and the implement contract. Give it no plan, no other slice, and no merge
103
+ instructions.
99
104
 
100
105
  ## 4. Validate, review, criticise
101
106
 
102
107
  When the implementer returns a PR URL (and a per-invariant test map):
103
108
 
104
109
  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.
110
+ base: `gh pr view <url> --json baseRefName` must be `main`. If not, fix it with
111
+ `gh pr edit <url> --base main`. That is a lead step; the implementer never changes a base.
108
112
  2. Dispatch `em-validator` (`em:em-validator`) with the slice key and the worktree path. It
109
113
  returns one PASS/FAIL line per check and `OVERALL: PASS` or a failure.
110
114
  3. On `OVERALL: PASS`: `em engagement set <model>.em <slug> <key> --state review`. Dispatch
@@ -125,36 +129,31 @@ When the implementer returns a PR URL (and a per-invariant test map):
125
129
  human.
126
130
  6. `minor` findings do not loop. They go in the evidence bundle.
127
131
 
128
- ## 5. Hand the human the stack, bottom first
132
+ ## 5. Hand the human each PR as it passes
129
133
 
130
134
  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.
135
+ Hand the human the PR with its evidence bundle (`reference/engagement.md`): the validator table,
136
+ the reviewer's and critic's findings and any disagreement, and the per-invariant test map. Every
137
+ PR is independent — against `main`, carrying only its own slice — so the human merges them in
138
+ any order, with the project's usual merge strategy (squash included), and nothing else needs
139
+ retargeting or restacking. Suggest level order (upstream slices first) because it reads better,
140
+ not because anything depends on it.
138
141
 
139
142
  You never merge.
140
143
 
141
144
  ## 6. After each human merge
142
145
 
143
146
  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:
147
+ 2. `em engagement set <model>.em <slug> <key> --state merged`, then remove the worktree:
149
148
  `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
149
+ 3. When every slice of a level is `merged` or `gap`, open one follow-up PR for that level from
151
150
  `main`: `git switch -c engagement/<slug>-level-<n> main`, run
152
151
  `em slice mark-implemented <model>.em <key> <pr-url>` for each slice merged in the level,
153
152
  then `em slice index <model>.em`, commit, and `gh pr create --base main`. The human merges it
154
153
  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.
154
+ 4. Recompute: `em engagement plan <model>.em <slug>`. A merge can release an
155
+ `upstream-outside-engagement-unmerged` hold once that upstream's doc reads `implemented`.
156
+ Continue with step 3 for anything newly startable.
158
157
 
159
158
  ## 7. Gaps
160
159
 
@@ -182,11 +181,12 @@ constitution), follow the gap protocol (`reference/engagement.md`):
182
181
  | Rule | Because |
183
182
  |---|---|
184
183
  | 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) |
184
+ | 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 |
185
+ | Never rebase a slice branch | The branch is the implementer's; the lead orchestrates and records, it does not rewrite history |
187
186
  | 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
187
  | 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 |
188
+ | Never cut a slice branch from the current HEAD | The base is `main` from the plan; the lead's HEAD may be anything |
189
+ | 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 |
190
+ | Never merge a PR | The human merges, in any order |
191
191
  | Never show the critic the reviewer's findings | The critic's value is an independent view; disagreement is a finding |
192
192
  | 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
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: event-modeling-implement
3
- em-version: 1.14.1
3
+ em-version: 1.15.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
@@ -158,11 +158,15 @@ undocumented ordering, a contradiction with adjacent code. The discipline:
158
158
  answered open question or a small ratified delta alongside your fix, so the decision is
159
159
  recorded instead of buried in an implementation diff.
160
160
  - **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
161
+ `ratifiedBy` set): once the human has answered, the doc changes by `em slice revise
162
+ <model>.em <slice-key>` (MIL-283: opens the next version as a `draft` — `version:` bumped,
163
+ the old sign-off cleared; the ratification of the unshipped version is withdrawn),
164
+ the answer is written into the doc and committed, the room reviews it (`em slice review
165
+ --by`), and the human re-signs with `em slice ratify
166
+ <model>.em <slice-key> --by <name>` (it records the commit it signs and refuses uncommitted
167
+ changes, MIL-284) — on a slice owning a `public` element that `ratify` also needs
168
+ `--meaning-unchanged` or `--contract-change "<why>"` (MIL-238; `revise` takes neither — the
169
+ confirmation belongs to the new version's sign-off). That is the human's step, not
166
170
  yours — you never run `ratify`, and
167
171
  the doc is not ratified again until they do; resume the build after that.
168
172
  - **Never edit the ratified doc to record your own answer**, and never quietly pick a behavior
@@ -228,7 +232,15 @@ a bump here is a ledger defect.
228
232
  `em slice mark-implemented <model>.em <slice-key> <pr-url>` does the flip for you (MIL-103) —
229
233
  resolves the doc via the same note-binding join `--slice-ready` uses, is idempotent on a re-run
230
234
  with the same URL, and refuses (never silently overwrites) if the doc is already `implemented`
231
- with a different URL. Prefer it over hand-editing the doc's frontmatter.
235
+ with a different URL. It also refuses a doc that isn't `ready-to-implement` (MIL-277): if it
236
+ reports `doc is \`status: draft\``/`reviewed`, the slice was never ratified — stop and surface
237
+ that to the human rather than editing the frontmatter by hand; the §1 gate should have caught it.
238
+ Prefer it over hand-editing the doc's frontmatter. It also writes the **shipped record**
239
+ (`shippedVersion:`/`shippedRef:`/`shippedOn:`, MIL-284) — what every reader decides "has this
240
+ shipped?" on since 1.15.0 — and, when the ratified doc deferred a question to the next version,
241
+ **opens that version as a `draft` on the same write** (MIL-283: `status: draft`, `version` bumped,
242
+ the question back to `- [ ]`; the version you built stays shipped). If it prints `opened draft
243
+ v<N+1>`, say so in your report: the slice has known work, and a design session, not you, decides it.
232
244
 
233
245
  Then, if the project keeps a model README (from `../../event-modeling-shared/templates/model-readme.md`), run
234
246
  `em slice index <model-name>.em` so its generated Slices table reflects the new status and
@@ -308,23 +320,17 @@ sibling slice's package to reuse it — the boundary the constitution drew is go
308
320
  contract into a pre-empted slice.
309
321
  2. **It merges before any slice PR opens.** Every slice branch is cut *after* the foundation PR
310
322
  has landed on `main` — never from a commit that predates it, and never alongside an open,
311
- unmerged foundation PR. Within an engagement, cut the slice branch from the base the
312
- engagement plan names (`em engagement plan`); outside an engagement, from `main`. A slice PR
313
- never carries foundation files. Because: a slice PR opened while the foundation is still in
314
- review shows a diff dominated by files the slice didn't write and can't be held accountable
315
- for, and its merge depends on someone else's review timeline instead of its own. The plan's
316
- base is either `main` or `impl/<upstream>` (the one unmerged upstream slice this slice builds
317
- on); either way it already contains the foundation.
318
-
319
- 2a. **While a dependent PR is open, the lower PR merges with a merge commit; squash is forbidden
320
- in that state (it strands the dependent's history).** A PR is the *lower* one when another
321
- open PR targets its branch as its base. Once no open PR depends on it, the project's usual
322
- merge strategy applies. Because: a squash rewrites the lower branch's commits into one new
323
- commit on `main`, so the dependent branch still carries the originals and its diff against
324
- `main` shows them again — it then needs a hand rebase (`git rebase --onto main <old base
325
- tip>`). A merge commit keeps the original commits: once the lower branch is merged and
326
- deleted, the dependent is retargeted to `main` and its diff shrinks to its own commits with
327
- no rebase.
323
+ unmerged foundation PR. Every slice branch is cut from `main` and every slice PR targets
324
+ `main` — inside an engagement (`em engagement plan` names `main` as every slice's base) and
325
+ outside one alike; never from another slice's branch, never targeting another slice's PR. A
326
+ slice PR never carries foundation files. Because: a slice PR opened while the foundation is
327
+ still in review shows a diff dominated by files the slice didn't write and can't be held
328
+ accountable for, and its merge depends on someone else's review timeline instead of its own.
329
+ And because the foundation already holds every event and rule 3 keeps a slice out of its
330
+ siblings' code, no slice needs another slice's branch to compile or test: a PR cut from a
331
+ sibling's branch (a "stack") carries a dependency this contract forbids, and turns N isolated
332
+ slices into one landing with merge-commit and retargeting ceremony attached. `main` already
333
+ contains the foundation; that is all a slice needs.
328
334
 
329
335
  3. **A slice never creates, edits, or reaches into another slice's code.** It *imports* events —
330
336
  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.1
3
+ em-version: 1.15.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**