@milehimikey/em 1.14.2 → 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 (97) 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 +26 -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/dist/catalog/docJoin.d.ts +17 -1
  16. package/dist/catalog/docJoin.js +7 -1
  17. package/dist/catalog/docJoin.js.map +1 -1
  18. package/dist/catalog/driftSignal.d.ts +16 -12
  19. package/dist/catalog/driftSignal.js +14 -9
  20. package/dist/catalog/driftSignal.js.map +1 -1
  21. package/dist/catalog/sliceDoc.d.ts +51 -0
  22. package/dist/catalog/sliceDoc.js +47 -0
  23. package/dist/catalog/sliceDoc.js.map +1 -1
  24. package/dist/catalog/sliceReadyValidate.js +12 -0
  25. package/dist/catalog/sliceReadyValidate.js.map +1 -1
  26. package/dist/cli/conformScope.d.ts +4 -0
  27. package/dist/cli/conformScope.js +2 -2
  28. package/dist/cli/conformScope.js.map +1 -1
  29. package/dist/cli/coverage.js +7 -3
  30. package/dist/cli/coverage.js.map +1 -1
  31. package/dist/cli/defer.d.ts +61 -2
  32. package/dist/cli/defer.js +204 -23
  33. package/dist/cli/defer.js.map +1 -1
  34. package/dist/cli/engagement.d.ts +13 -5
  35. package/dist/cli/engagement.js +26 -19
  36. package/dist/cli/engagement.js.map +1 -1
  37. package/dist/cli/findings.d.ts +2 -2
  38. package/dist/cli/findings.js +2 -2
  39. package/dist/cli/frontmatterSurgery.d.ts +3 -3
  40. package/dist/cli/frontmatterSurgery.js +3 -3
  41. package/dist/cli/frontmatterSurgery.js.map +1 -1
  42. package/dist/cli/markImplemented.d.ts +20 -18
  43. package/dist/cli/markImplemented.js +94 -15
  44. package/dist/cli/markImplemented.js.map +1 -1
  45. package/dist/cli/ratify.d.ts +36 -6
  46. package/dist/cli/ratify.js +130 -35
  47. package/dist/cli/ratify.js.map +1 -1
  48. package/dist/cli/review.js +3 -3
  49. package/dist/cli/review.js.map +1 -1
  50. package/dist/cli/revise.d.ts +57 -0
  51. package/dist/cli/revise.js +207 -0
  52. package/dist/cli/revise.js.map +1 -0
  53. package/dist/cli/sliceConform.d.ts +4 -3
  54. package/dist/cli/sliceConform.js +29 -12
  55. package/dist/cli/sliceConform.js.map +1 -1
  56. package/dist/cli/status.d.ts +8 -0
  57. package/dist/cli/status.js +7 -4
  58. package/dist/cli/status.js.map +1 -1
  59. package/dist/cli/upgrade.js +7 -4
  60. package/dist/cli/upgrade.js.map +1 -1
  61. package/dist/cli.js +117 -77
  62. package/dist/cli.js.map +1 -1
  63. package/dist/emit/json.d.ts +1 -1
  64. package/dist/emit/json.js +13 -1
  65. package/dist/emit/json.js.map +1 -1
  66. package/dist/emit/statusJson.d.ts +1 -1
  67. package/dist/emit/statusJson.js +4 -1
  68. package/dist/emit/statusJson.js.map +1 -1
  69. package/dist/mcp/server.js +5 -5
  70. package/dist/mcp/server.js.map +1 -1
  71. package/dist/model/rules.d.ts +8 -0
  72. package/dist/model/rules.js +8 -0
  73. package/dist/model/rules.js.map +1 -1
  74. package/dist/model/sliceDocIndex.d.ts +3 -0
  75. package/dist/model/sliceDocIndex.js +5 -4
  76. package/dist/model/sliceDocIndex.js.map +1 -1
  77. package/dist/templates.d.ts +1 -1
  78. package/dist/templates.js +5 -7
  79. package/dist/templates.js.map +1 -1
  80. package/package.json +1 -1
  81. package/plugin/.claude-plugin/plugin.json +2 -2
  82. package/plugin/shared/reference/em-dsl.md +230 -227
  83. package/plugin/shared/reference/operating-principles.md +3 -3
  84. package/plugin/shared/reference/slice-doc-schema.md +58 -27
  85. package/plugin/shared/templates/constitution.md +5 -7
  86. package/plugin/skills/conform/SKILL.md +1 -1
  87. package/plugin/skills/design/SKILL.md +29 -18
  88. package/plugin/skills/discover/SKILL.md +1 -1
  89. package/plugin/skills/engagement/SKILL.md +54 -54
  90. package/plugin/skills/engagement/reference/engagement.md +5 -19
  91. package/plugin/skills/event-modeling/SKILL.md +3 -3
  92. package/plugin/skills/implement/SKILL.md +1 -1
  93. package/plugin/skills/implement/reference/implement.md +26 -23
  94. package/plugin/skills/review/SKILL.md +13 -3
  95. package/dist/cli/reratify.d.ts +0 -58
  96. package/dist/cli/reratify.js +0 -238
  97. package/dist/cli/reratify.js.map +0 -1
@@ -120,12 +120,12 @@ including sessions started from bare `/em:event-modeling`.
120
120
  - **Version rule: never bump a draft's `version:` on edit.** A `draft`/`reviewed` doc is edited
121
121
  in place. Check the release state with `em status <model>.em --json`: the model is
122
122
  **pre-release** when its `modelVersion` entry has `design: null` and
123
- `slices.byStatus.implemented === 0`. Pre-release: never run `em slice reratify`; edit
123
+ `slices.byStatus.shipped === 0`. Pre-release: never run `em slice revise`; edit
124
124
  `draft`/`reviewed` docs in place and leave `version:` as it is. A pre-release doc that is
125
125
  already ratified (`ready-to-implement` with `ratifiedBy`) carries a human sign-off: STOP,
126
126
  record the needed change as an open question, and let the ratifier decide. Released (either
127
- condition false): changing an `implemented` or ratified doc goes through `em slice reratify`
128
- (see `em:design`).
127
+ condition false): changing a shipped or ratified doc goes through `em slice revise`, which
128
+ opens the next version as a `draft` (see `em:design`).
129
129
  - **Pre-commit check (STOP on any finding).** Stage the session's files, then run both:
130
130
  1. `em system scope --staged` from the repository root. Any `seam-crossing` error → STOP:
131
131
  unstage the other model's files and record a seam change request instead.
@@ -68,8 +68,13 @@ to decide `frontmatter-invalid` without re-deriving frontmatter-shape rules of i
68
68
  | `reviewedOn` | string | `YYYY-MM-DD` | written only by `em slice review` (MIL-201); joined into `em export`'s `slice.doc.reviewedOn` (schema `1.11`) |
69
69
  | `ratifiedBy` | string | free text (typically a person's name) | written only by `em slice ratify` (MIL-165 — see [cli.md](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-slice-ratify-file-slice-key---by-name)); joined into `em export`'s `slice.doc.ratifiedBy` (schema `1.8`) and `em slice index`'s Ratified by column |
70
70
  | `ratifiedOn` | string | `YYYY-MM-DD` | written only by `em slice ratify` (MIL-165); joined into `em export`'s `slice.doc.ratifiedOn` (schema `1.8`) |
71
- | `meaningConfirmed` | boolean | `true` | written only by `em slice ratify`/`reratify --meaning-unchanged` (MIL-238 — see [cli.md](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-slice-ratify-file-slice-key---by-name)): the API-first sign-off on a public-touching slice — this version does not change what the public contract means. Joined into `em export`'s `slice.doc.meaningConfirmed` (schema `1.15`; `false` when absent) |
72
- | `contractChange` | string | quoted free text (`contractChange: "<why>"`) | written only by `em slice ratify`/`reratify --contract-change "<why>"` (MIL-238): the API-first sign-off on a public-touching slice — why a consumer must read this change differently. Joined into `em export`'s `slice.doc.contractChange` (schema `1.15`, quotes stripped; `null` when absent) |
71
+ | `ratifiedRef` | string | full commit sha | written only by `em slice ratify` (MIL-284 — see [cli.md](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-slice-ratify-file-slice-key---by-name)) when the model directory is inside a git repository: `HEAD` at ratification, the commit whose tree holds the body that was signed (ratify refuses a doc with uncommitted changes so this holds). Absent when ratified before 1.15 or outside git. Cleared by `em slice reratify`. Joined into `em export`'s `slice.doc.ratifiedRef` (schema `1.16`). Not a target-repo revision: `em slice conform --at` still names that itself |
72
+ | `ratifiedHash` | string | `sha256:<64 hex>` | written only by `em slice ratify` (MIL-284): `sha256` over the doc body (everything after the frontmatter fence, EOLs normalised) — the signed content's identity without git. Cleared by `em slice reratify`. Read by `em validate --slice-ready` (`slice-ready-body-changed-since-ratification`); joined into `em export`'s `slice.doc.ratifiedHash` (schema `1.16`) |
73
+ | `shippedVersion` | integer | positive integer | written only by `em slice mark-implemented` (MIL-284): the doc's `version:` when the merge was recorded. With `shippedRef`/`shippedOn`/`implementedIn`, joined into `em export`'s `slice.doc.shipped` (schema `1.16`). Additive in 1.15 — `status`/`implementedIn` still carry the lifecycle for every reader |
74
+ | `shippedRef` | string | full commit sha | written only by `em slice mark-implemented` (MIL-284): the doc's `ratifiedRef` at merge time, i.e. the ref the shipped version was signed at; absent when the doc had none |
75
+ | `shippedOn` | string | `YYYY-MM-DD` | written only by `em slice mark-implemented` (MIL-284): the local date of the merge record, or `--on <date>` |
76
+ | `meaningConfirmed` | boolean | `true` | written only by `em slice ratify --meaning-unchanged` (MIL-238 — see [cli.md](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-slice-ratify-file-slice-key---by-name)): the API-first sign-off on a public-touching slice — this version does not change what the public contract means. Joined into `em export`'s `slice.doc.meaningConfirmed` (schema `1.15`; `false` when absent) |
77
+ | `contractChange` | string | quoted free text (`contractChange: "<why>"`) | written only by `em slice ratify --contract-change "<why>"` (MIL-238): the API-first sign-off on a public-touching slice — why a consumer must read this change differently. Joined into `em export`'s `slice.doc.contractChange` (schema `1.15`, quotes stripped; `null` when absent) |
73
78
  | `owner` | string | free text (typically a person or team name) | hand-filled — no `em` command writes it; joined into `em export`'s `slice.doc.owner` (schema `1.9`, MIL-171), `em slice index`'s Owner column, and `em status`'s per-slice `owners[]` |
74
79
  | `tracking` | string | free text (typically an external ticket/issue URL) | hand-filled — no `em` command writes it; joined into `em export`'s `slice.doc.tracking` (schema `1.9`, MIL-171) and `em slice index`'s Tracking column. This is the exact field `em-tracker-bridge` reads to find the ticket mirroring this slice — `em` only stores and displays it, it never talks to a tracker itself |
75
80
  | `conformedVersion` | integer | positive integer | written only by `em slice conform` (MIL-214 — see [cli.md](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-slice-conform-file-slice-key---at-rev)): this slice's `version:` at the time a conform sweep last certified it. Joined into `em export`'s `slice.doc.conformedVersion` (schema `1.13`); paired with `version` to compute `slice.doc.driftSignal`'s `"uncertified"` case |
@@ -246,7 +251,7 @@ straight through to the originating slice's own doc, exactly the way a ratified
246
251
  binding resolves a covered slice — same `doc.found`/`status`/`driftSignal`, plus a
247
252
  `continuationOf: <originating-key>` field naming why. `em export`, `em status`, `em coverage`,
248
253
  `em slice index`, `em catalog`, and the render pipeline's Slice Status legend all resolve a
249
- continuation slice this way; `em slice ratify`/`review`/`reratify`/`mark-implemented` and
254
+ continuation slice this way; `em slice ratify`/`review`/`revise`/`mark-implemented` and
250
255
  `em slice new --wire` refuse on one outright, naming the originating slice to act on instead —
251
256
  a continuation slice has no status/ratification of its own to flip.
252
257
 
@@ -483,7 +488,7 @@ prior one — exactly the ambiguity a live, current-version-only section avoids.
483
488
  **Deferral marker (MIL-275).** A question this version will not answer is not left `- [ ]` and
484
489
  not deleted: `em slice defer` checks it and rewrites it as `- [x] <original> — v<current>:
485
490
  <decision>; deferred to v<n> (<date>[, <by>])`. The `deferred to v<n>` marker is what
486
- `em slice reratify` reads: when a bump reaches v<n> it rewrites each such item back to
491
+ `em slice revise` (and `mark-implemented`, which opens v<n> at merge when something is deferred to it) reads: when the doc reaches v<n> it rewrites each such item back to
487
492
  `- [ ] <original>`, so the question must be resolved or re-deferred before `--slice-ready` passes
488
493
  again. The prune rule above does not apply to a deferred item before v<n> (it stays as the
489
494
  record); once reopened it is an ordinary open question.
@@ -498,26 +503,51 @@ actually happened on re-ratification).
498
503
 
499
504
  ## `status` under re-ratification
500
505
 
501
- When a new version is ratified for a slice whose previous version already shipped, `status`
502
- tracks the **current version's** implementation state, not a running "has this ever shipped"
503
- flag. Ratifying v2 on an `implemented` slice flips `status` back to `ready-to-implement`, while
504
- `implementedIn` keeps naming the v1 PR until v2 ships. That deliberate mismatch — version 2,
505
- implemented-link still pointing at v1's work — is not staleness, it's the **drift signal**: a
506
- reader, `em export`'s `slice.doc.driftSignal` (`"unpropagated-delta"`, schema `1.5`, MIL-85), and
507
- the event-modeling skill's `conform` phase all read it the same way — a ratified delta hasn't
508
- shipped yet, not a fresh finding against the still-live v1 code. `em validate`'s
509
- frontmatter-coherence check (MIL-85) deliberately never flags this combination — only
510
- `status: implemented` with no `implementedIn` link at all is checkable incoherence; see
506
+ Since 1.15.0 (MIL-283) two separate facts live in the frontmatter, and every reader knows which
507
+ one it is asking about:
508
+
509
+ - **`status` is the working state** of the doc's current `version:` — `draft`, `reviewed`,
510
+ `ready-to-implement`, `implemented`.
511
+ - **The shipped record is what is in production**: `shippedVersion:`/`shippedRef:`/`shippedOn:`
512
+ (written by `em slice mark-implemented`, MIL-284) together with `implementedIn:`. For a doc
513
+ shipped before 1.15 — no `shippedVersion:` — the read-both rule applies: `status: implemented`
514
+ means "shipped at the current `version:`". The one function that answers "has a version of this
515
+ slice shipped, and which" is `shippedRecordOf()` (`src/catalog/sliceDoc.ts`); `em export`
516
+ publishes its answer as `slice.doc.shipped`.
517
+
518
+ So a shipped slice can be a `draft` again. `em slice revise <key>`
519
+ ([cli.md](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-slice-revise-file-slice-key)) opens v<N+1> as `status: draft`, bumps
520
+ `version:`, clears the prior version's review and sign-off, and leaves `implementedIn`/`shipped*`
521
+ alone — v<N> stays shipped. `em slice mark-implemented` does the same automatically at merge when a
522
+ question was deferred to v<N+1> (`em slice defer`), so known work is on the list the moment the
523
+ previous version lands. Version 2 then takes both human gates like version 1 did: `em slice review
524
+ --by`, then `em slice ratify --by` (which records a fresh `ratifiedRef`/`ratifiedHash`).
525
+
526
+ The deliberate mismatch — `version: 2` open while `implementedIn`/`shippedVersion` still name v1's
527
+ work — is not staleness, it's the **drift signal**: `em export`'s `slice.doc.driftSignal` is
528
+ `"unpropagated-delta"` whenever `version` is past the shipped version (MIL-85/283), and the
529
+ event-modeling skill's `conform` phase reads it as "a delta hasn't shipped yet", not a fresh finding
530
+ against the still-live v1 code. `em validate`'s frontmatter-coherence check (MIL-85) never flags it;
531
+ only a shipped slice with no `implementedIn` link at all is checkable incoherence
532
+ (`implemented-without-link`); see
511
533
  [validation.md#frontmatter-coherence](https://github.com/milehimikey/em/blob/main/docs/validation.md#frontmatter-coherence).
512
534
 
513
- **An unshipped version has nothing to flip back** (MIL-258). A ratified doc that has not shipped
514
- yet (`status: ready-to-implement` with `ratifiedBy:` set) changes the same way: `em slice
515
- reratify` bumps `version:` and clears `ratifiedBy`/`ratifiedOn`/`reviewedBy`/`reviewedOn` (and `meaningConfirmed`/`contractChange`, MIL-238), but
516
- leaves `status` at `ready-to-implement` (and any `implementedIn` as it was — an absent one stays
517
- absent). This is the path for an answered gap mid-build. In both cases the new version is not
518
- ratified until `em slice ratify --by <name>` records the sign-off. A `ready-to-implement` doc with
519
- no `ratifiedBy` is awaiting that sign-off, so a second `reratify` refuses rather than
520
- double-bump; `draft`/`reviewed` docs are not ratified and are simply edited.
535
+ **Which readers decide on the shipped record, not `status`** (MIL-283): `em status`'s
536
+ `byStatus.shipped` count and its conformance scope, `em coverage --strict`'s default scope, `em
537
+ conform-scope` / `em conform-supersede`'s in-scope slices, `em slice conform` (legal when shipped;
538
+ `conformedVersion:` is the **shipped** version), the engagement Ledger's inferred `merged` and its
539
+ outside-upstream hold, `em upgrade`'s pre-release signal, `em slice ratify`'s upstream advisory, and
540
+ `driftSignal`. `byStatus.implemented`, the render/legend colouring and `--slice-ready` still read the
541
+ working `status` — that is what they are about.
542
+
543
+ **A ratified version that never shipped** (`status: ready-to-implement` with `ratifiedBy:` set — a
544
+ gap answered mid-build) is revised the same way: `draft`, `version + 1`, sign-off cleared; the
545
+ ratification of v<N> is withdrawn and nothing shipped, so no shipped record is written. **A
546
+ `ready-to-implement` doc with no `ratifiedBy`** is the leftover of a pre-1.15 `reratify` (which
547
+ bumped the version and left the doc unsigned at that status); no command produces it any more and
548
+ `em slice ratify` no longer accepts it — `em slice revise` reopens it as a `draft` at the same
549
+ version, and the normal road follows. `draft`/`reviewed` docs are not ratified and are simply
550
+ edited; `revise` refuses them ("the next version is already open").
521
551
 
522
552
  Pair a re-ratification with a `## Delta` section (see
523
553
  [Delta section: grammar and lifecycle](#delta-section-grammar-and-lifecycle) above) recording
@@ -527,10 +557,11 @@ the ratified change in typed operation blocks, so it's reviewable without openin
527
557
  see [cli.md#em-ledger-file](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-ledger-file)) checks that `version:` and a slice doc's
528
558
  content (body + lineage refs) always change together across two git revisions — a version bump
529
559
  with no real content change, or a content change with no version bump, is a ledger bug.
530
- It **deliberately excludes `status`/`implementedIn`** from what counts as "content" for exactly
531
- the reason this section explains: a re-ratification legitimately flips `status` and leaves
532
- `implementedIn` naming prior work, with no version bump of its own — including either field in
533
- the comparison would flag every ordinary lifecycle transition as a false positive.
560
+ It **deliberately excludes `status`/`implementedIn`** (and the `shipped*` keys) from what counts
561
+ as "content" for exactly the reason this section explains: a lifecycle transition legitimately
562
+ moves `status` and leaves `implementedIn`/`shippedVersion` naming prior work, with no version bump
563
+ of its own — including those fields in the comparison would flag every ordinary lifecycle
564
+ transition as a false positive.
534
565
 
535
566
  ## Unknown keys
536
567
 
@@ -564,7 +595,7 @@ legacy form; they're frontmatter-only from the day they were introduced.
564
595
  - [cli.md](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-render-file) — slice status colors
565
596
  - [cli.md](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-catalog-files) — pattern / doc lookup
566
597
  - [cli.md](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-slice-ratify-file-slice-key---by-name) — `em slice ratify`, the mechanized ratification act (`ratifiedBy`/`ratifiedOn`, schema `1.8`, MIL-165)
567
- - [cli.md](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-slice-reratify-file-slice-key) — `em slice reratify`, the mechanized re-ratification version bump/status flip (MIL-161)
598
+ - [cli.md](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-slice-revise-file-slice-key) — `em slice revise`, which opens the next version as a draft (the successor of `reratify`)
568
599
  - [cli.md](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-export-file) — the `em export` join (`slice.pattern`/`slice.doc`, schema `1.4`, MIL-91), including `owner`/`tracking` (schema `1.9`, MIL-171)
569
600
  - [cli.md](https://github.com/milehimikey/em/blob/main/docs/cli.md#em-diff-old-new) — the `em diff` lineage annotation (schema `1.6`, MIL-84)
570
601
  - [validation.md#lineage](https://github.com/milehimikey/em/blob/main/docs/validation.md#lineage) — `em validate`'s lineage-ref resolution (MIL-84)
@@ -24,9 +24,9 @@ NAMED human and an ISO date, hand-filled at sign-off (no `em` command writes thi
24
24
  unratified, says so, and does not proceed on unilateral style or stack decisions for a first slice.
25
25
 
26
26
  `em status` reports this document as present or absent per model — existence only. em never reads
27
- or validates its content, and the CLI parses nothing here. Three lines are read as plain text by
27
+ or validates its content, and the CLI parses nothing here. Two lines are read as plain text by
28
28
  the engagement skill and its sub-agents, so keep their exact shape: `- **Test command:**` (the
29
- validator), `- **Merge strategy:**` and `- **Agent models:**` (the engagement skill). In a spec-kit
29
+ validator) and `- **Agent models:**` (the engagement skill). In a spec-kit
30
30
  project they merge under the same headings in `.specify/memory/constitution.md`.
31
31
  -->
32
32
 
@@ -121,11 +121,9 @@ it is silent, these apply.
121
121
  amend** — a `covers:` doc ships as one PR for both keys; a read model is one doc, so a later
122
122
  `again` instance is a continuation of the doc that first declared it, not a PR of its own. See
123
123
  the agent guide's §5/§10.
124
- - **Merge strategy:** merge-commits-when-stacked
125
- {{**How do PRs merge, and what happens when one PR depends on another?** Merge commits whenever
126
- a dependent PR is open; squash only a PR with no open dependent (implement contract §8 rule 2a).
127
- Keep this exact line: it is the only value the engagement skill accepts, and it refuses to run
128
- without it.}}
124
+ - **Merge strategy:** {{squash | merge commit | rebase — the project's own choice. Every slice PR
125
+ is cut from and targets `main` (implement contract §8 rule 2), so no PR ever depends on
126
+ another and any strategy works; em reads nothing from this line.}}
129
127
  - **Agent models:** implementer=sonnet, validator=sonnet, reviewer=sonnet, critic=opus
130
128
  {{**Which model runs each em sub-agent?** Keep this exact line shape, with the defaults shown or
131
129
  your own choices. The critic must run on a different model from the implementer; `critic=codex`
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: conform
3
- em-version: 1.14.2
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: design
3
- em-version: 1.14.2
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
@@ -52,10 +52,10 @@ evidence"). In short:
52
52
  - **Evidence rule.** The `.em` model and the slice docs are the evidence for modeling
53
53
  decisions. Never read implementation source, generated contracts or `specs/` to decide a
54
54
  modeling question — ask the user. Code is read only in `extract` and `conform`.
55
- - **Version rule.** Never bump a draft's `version:` on edit. Before any `em slice reratify`,
55
+ - **Version rule.** Never bump a draft's `version:` on edit. Before any `em slice revise`,
56
56
  run `em status <model>.em --json`: pre-release = the model's `modelVersion` entry has
57
- `design: null` **and** `slices.byStatus.implemented === 0`. Pre-release → never run
58
- `reratify`; edit `draft`/`reviewed` docs in place. Released → the re-ratification path in
57
+ `design: null` **and** `slices.byStatus.shipped === 0`. Pre-release → never run
58
+ `revise`; edit `draft`/`reviewed` docs in place. Released → the revision path in
59
59
  the `slice` phase below.
60
60
  - **Pre-commit check.** Stage the session's files, run `em system scope --staged` (STOP on any
61
61
  `seam-crossing`), then `git diff --cached --name-only` (STOP on any path outside this model's
@@ -152,7 +152,7 @@ For each slice:
152
152
  it in place and leave its `version:` alone. If `slices/<slice-name>.md` already exists with
153
153
  `status: implemented` (or is ratified and needs a change), run `em status <model>.em --json`
154
154
  first. **Pre-release** (the model's `modelVersion` entry has `design: null` and
155
- `slices.byStatus.implemented === 0`): never run `em slice reratify`; a ratified doc holds a
155
+ `slices.byStatus.shipped === 0`): never run `em slice revise`; a ratified doc holds a
156
156
  human sign-off, so STOP, park the change as an open question, and let the ratifier decide.
157
157
  **Released** (either condition false): a doc with `status: implemented` is a
158
158
  re-ratification, not fresh authoring: hold a Socratic
@@ -213,6 +213,11 @@ For each slice:
213
213
  `--slice-ready` refuses it). A doc written before em 1.14 has no markers; leave it as it is
214
214
  unless you are re-creating it (`em slice new … --wire --force`, carrying the prose across).
215
215
  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.
216
+ When the question lives on the diagram as an `issue "..."` note rather than on the doc, use
217
+ `em slice defer <model> <key> --from-issue "<text>" --until v<n> --decision "<what this version does>"`
218
+ instead: it writes the deferred item into the doc's Open Questions and removes the note in one
219
+ step. A question that is *answered* is an edit to the authored section plus deleting the note —
220
+ never a deferral.
216
221
  2. **First-time authoring:** scaffold the doc mechanically rather than hand-writing the
217
222
  frontmatter — `em slice new "<slice name>" --pattern <state-change|state-view|automation|
218
223
  translation> --swimlane "<Persona> → <Context>" --wire <model>.em` writes `slices/<slice-name>.md`
@@ -237,23 +242,29 @@ For each slice:
237
242
  lineage key(s) by hand (`split-from`/`merged-from`/`superseded-by`, `<slice-key>@v<N>` grammar
238
243
  — see `${CLAUDE_PLUGIN_ROOT}/shared/reference/slice-doc-schema.md` for the full schema; `em validate` catches a malformed one
239
244
  after the fact, see the `lineage-*` rules below).
240
- **Re-ratification (step 0) — released models only.** Confirm the model is released first
245
+ **Revision (step 0) — released models only.** Confirm the model is released first
241
246
  (`em status <model>.em --json`: the `modelVersion` entry's `design` is not `null`, or
242
- `slices.byStatus.implemented > 0`); on a pre-release model never run `reratify`. The doc
247
+ `slices.byStatus.shipped > 0`); on a pre-release model never run `revise`. The doc
243
248
  already exists, so `em slice new` doesn't apply here
244
249
  (it refuses to overwrite an existing file without `--force`, and forcing would blow away the
245
- doc's authored body) — run `em slice reratify <model>.em <slice-key>` instead: it bumps
246
- `version` and flips `status` back to `ready-to-implement` in the existing frontmatter,
247
- clearing any stale `ratifiedBy:`/`ratifiedOn:` from the prior version so a follow-up
248
- `em slice ratify --by <name>` (if the team records that) applies cleanly. The same command
249
- changes a ratified doc that **never shipped** (`ready-to-implement` with `ratifiedBy` set — a
250
- gap answered mid-build, MIL-258): it bumps `version` and clears the sign-off but leaves
251
- `status` alone. Either way the doc is not ratified until `em slice ratify --by <name>` records
252
- the new sign-off. A `ready-to-implement` doc with no `ratifiedBy` is already awaiting that
253
- sign-off and refuses a second `reratify`; a `draft`/`reviewed` doc is simply edited, and its
254
- `version:` never moves.
250
+ doc's authored body) — run `em slice revise <model>.em <slice-key>` instead (MIL-283): it
251
+ opens the next version as a **`draft`** in the existing frontmatter — `version` bumped,
252
+ `status: draft`, the prior version's review and sign-off cleared — while the shipped version
253
+ stays shipped in the shipped record (`implementedIn:`/`shippedVersion:`, untouched). If a
254
+ question was deferred to this version, `em slice mark-implemented` already opened the draft
255
+ at merge and the question is back on the list; `revise` then refuses ("the next version is
256
+ already open") and you simply edit. The same command revises a ratified doc that **never
257
+ shipped** (`ready-to-implement` with `ratifiedBy` set — a gap answered mid-build): the
258
+ ratification is withdrawn and the draft opens. Either way the new version is a new spec:
259
+ write the delta into `## Delta`, walk it in a review session (`em slice review --by`), and
260
+ only then does `em slice ratify --by <name>` sign it. **Commit before ratifying (MIL-284):**
261
+ `em slice ratify` records the commit and body hash it signs and refuses a doc with uncommitted
262
+ changes — finish the doc's edits (deferrals included: `em slice defer` rewrites a body line, so
263
+ a deferral after sign-off trips `slice-ready-body-changed-since-ratification`), commit, then
264
+ ratify. A `draft`/`reviewed` doc is simply edited, and its `version:` never moves.
255
265
  **Public-touching slices (MIL-238).** On a slice that owns a `public` command, event or view,
256
- `em slice ratify --by <name>` and `em slice reratify` refuse without one of two flags: pass
266
+ `em slice ratify --by <name>` refuses without one of two flags (`revise` takes neither — the
267
+ confirmation belongs to the new version's ratification): pass
257
268
  `--meaning-unchanged` when this version does not change what the public contract means, or
258
269
  `--contract-change "<why>"` when a consumer must read the change differently. Without
259
270
  either, both refuse with `slice "<key>" touches the public surface — pass
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: discover
3
- em-version: 1.14.2
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,12 +1,12 @@
1
1
  ---
2
2
  name: engagement
3
- em-version: 1.14.2
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 em: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 em:implement instead.
10
10
  ---
11
11
  <!-- GENERATED FILE from .claude/skills/event-modeling-engagement/SKILL.md by scripts/build-plugin.ts — do not hand-edit; run npm run docs:generate -->
12
12
 
@@ -14,12 +14,20 @@ description: >-
14
14
 
15
15
  Goal: take an engagement (a named chunk of the model, `<model dir>/engagements/<slug>.md`) from
16
16
  its plan to merged PRs. You are the **lead**: you cut worktrees, dispatch scoped sub-agents,
17
- record every step in the Ledger with `em engagement set`, and hand the human a stack of PRs to
18
- merge bottom-first. You never write slice code, never merge, and never rebase a slice branch.
17
+ record every step in the Ledger with `em engagement set`, and hand the human one PR per slice,
18
+ each cut from and targeting `main`, to merge in any order. You never write slice code, never
19
+ merge, and never rebase a slice branch.
20
+
21
+ An engagement is a *related set* of isolated slices — a workflow, a lifecycle — built together.
22
+ It is not a stack: no slice branch is ever cut from another slice's branch, and no PR ever
23
+ targets another PR (MIL-280). The foundation PR (implement.md §8) already holds every event, and
24
+ a slice never reaches into a sibling's code (§8 rule 3), so each PR compiles, tests and merges
25
+ on its own. Levels order the work for the human's review and your dispatch; they never gate a
26
+ merge.
19
27
 
20
28
  **Read `reference/engagement.md` before the first dispatch.** It holds the Ledger state machine,
21
- the evidence bundle format, the retarget check, the gap protocol and the model-selection rule
22
- this file uses by name. Each sub-agent runs `em:implement`'s contract
29
+ the evidence bundle format, the gap protocol and the model-selection rule this file uses by
30
+ name. Each sub-agent runs `em:implement`'s contract
23
31
  (`${CLAUDE_PLUGIN_ROOT}/skills/implement/reference/implement.md`) for its one slice; that contract is
24
32
  theirs, not yours.
25
33
 
@@ -43,21 +51,17 @@ Run the shared preconditions first (tool check, bundle currency, locate the mode
43
51
  2. **Foundation PR merged.** Ask the human for the foundation PR (implement.md §8) and confirm it
44
52
  has merged into `main` (`gh pr view <n> --json state` shows `MERGED`). STOP if there is none
45
53
  or it is still open. No slice branch is cut before it lands.
46
- 3. **Merge strategy.** The constitution's "Review and merge norms" must carry the line
47
- `- **Merge strategy:** merge-commits-when-stacked`. STOP if the line is absent or names any
48
- other value: tell the human the engagement needs that norm and point at the constitution
49
- template's "Review and merge norms" prompt
50
- (`${CLAUDE_PLUGIN_ROOT}/shared/templates/constitution.md`). The constitution is the human's to
51
- amend and ratify, never yours.
52
- 4. **Agent models.** Read the line `- **Agent models:** implementer=<model>,
54
+ 3. **Agent models.** Read the line `- **Agent models:** implementer=<model>,
53
55
  validator=<model>, reviewer=<model>, critic=<model|codex>`. If it is absent, say once:
54
56
  "no Agent models line — using implementer=sonnet, validator=sonnet, reviewer=sonnet,
55
57
  critic=opus", and proceed. Apply the model-selection rule in `reference/engagement.md`
56
- (the critic never runs on the implementer's model).
57
- 5. **Worktrees are ignored.** `git check-ignore -q .claude/worktrees/x` must succeed. If it
58
+ (the critic never runs on the implementer's model). A constitution that still carries a
59
+ `- **Merge strategy:**` line from em ≤ 1.14.2 is fine: the line is ignored, never a reason to
60
+ stop — PRs merge with whatever strategy the project uses.
61
+ 4. **Worktrees are ignored.** `git check-ignore -q .claude/worktrees/x` must succeed. If it
58
62
  fails, STOP and ask the human to add `.claude/worktrees/` to `.gitignore` in its own commit
59
63
  on `main`.
60
- 6. **The engagement exists.** `em engagement status <model>.em <slug>`. If there is no such
64
+ 5. **The engagement exists.** `em engagement status <model>.em <slug>`. If there is no such
61
65
  engagement, ask the human which slices it covers (a list, a context, or "everything
62
66
  downstream of X") and run `em engagement new <model>.em <slug> --slices a,b,c` (or
63
67
  `--context <C>`, or `--downstream-of <ref>`) `--by "<their name>"`. When `new` warns that the
@@ -67,9 +71,9 @@ Run the shared preconditions first (tool check, bundle currency, locate the mode
67
71
  ## 2. Plan and confirm the ceiling once
68
72
 
69
73
  Run `em engagement plan <model>.em <slug>` (`--json` when you need the fields). Present it in
70
- plain terms: each level, its width against the ceiling (`parallel`), each slice's branch and
71
- base, and every held slice with its reason (`not-ready`, `upstream-outside-engagement-unmerged`,
72
- `multiple-unmerged-upstreams`, or `human`). Then ask exactly one question:
74
+ plain terms: each level, its width against the ceiling (`parallel`), each slice's branch (every
75
+ base is `main`), and every held slice with its reason (`not-ready`,
76
+ `upstream-outside-engagement-unmerged`, or `human`). Then ask exactly one question:
73
77
 
74
78
  > "Ceiling N from the plan; proceed?"
75
79
 
@@ -79,13 +83,14 @@ A held slice is never started; the plan releases it when its hold clears.
79
83
 
80
84
  ## 3. Per level: cut the worktree, then dispatch the implementer
81
85
 
82
- Work level by level, in order. A slice in level n+1 starts only when its upstream has reached
83
- `awaiting-merge` or `merged`, so the base it is cut from no longer moves. Within a level, keep up
84
- to the ceiling of slices in flight (`building`, `validating` or `review`) at once, dispatched in
85
- parallel. For each slice the plan lists as not held:
86
+ Work level by level, in order: a level's slices are dispatched before the next level's, so the
87
+ human sees upstream slices first. Nothing in level n+1 waits for a merge — every slice is cut
88
+ from `main`. Keep up to the ceiling of slices in flight (`building`, `validating` or `review`)
89
+ at once, dispatched in parallel; when a slot frees, take the next not-held slice in level order.
90
+ For each slice the plan lists as not held:
86
91
 
87
- 1. Take `base` from the plan for this slice: `main`, or `impl/<upstream>`. **Never the current
88
- HEAD**, and never a branch you picked yourself.
92
+ 1. Take `base` from the plan for this slice. It is always `main`. **Never the current HEAD**,
93
+ never another slice's branch, and never a branch you picked yourself.
89
94
  2. If `impl/<key>` already exists (`git rev-parse --verify --quiet impl/<key>`) or
90
95
  `.claude/worktrees/<key>` already exists, STOP for that slice and report it. Never delete,
91
96
  reuse or reset someone's branch.
@@ -95,17 +100,16 @@ parallel. For each slice the plan lists as not held:
95
100
  `em engagement set <model>.em <slug> <key> --state building --branch impl/<key> --base <base>`
96
101
  5. Dispatch `em-implementer` (`em:em-implementer` under the plugin) on the implementer model.
97
102
  Its prompt is ONLY the slice key and the absolute worktree path. It reads its own spec, the
98
- constitution and the implement contract. Give it no plan, no other slice, and no merge or
99
- stacking instructions.
103
+ constitution and the implement contract. Give it no plan, no other slice, and no merge
104
+ instructions.
100
105
 
101
106
  ## 4. Validate, review, criticise
102
107
 
103
108
  When the implementer returns a PR URL (and a per-invariant test map):
104
109
 
105
110
  1. `em engagement set <model>.em <slug> <key> --state validating --pr <url>`. Check the PR's
106
- base: `gh pr view <url> --json baseRefName` must equal the Ledger's base. If not, fix it
107
- with `gh pr edit <url> --base <base>`. That is a lead step; the implementer never changes a
108
- base.
111
+ base: `gh pr view <url> --json baseRefName` must be `main`. If not, fix it with
112
+ `gh pr edit <url> --base main`. That is a lead step; the implementer never changes a base.
109
113
  2. Dispatch `em-validator` (`em:em-validator`) with the slice key and the worktree path. It
110
114
  returns one PASS/FAIL line per check and `OVERALL: PASS` or a failure.
111
115
  3. On `OVERALL: PASS`: `em engagement set <model>.em <slug> <key> --state review`. Dispatch
@@ -126,36 +130,31 @@ When the implementer returns a PR URL (and a per-invariant test map):
126
130
  human.
127
131
  6. `minor` findings do not loop. They go in the evidence bundle.
128
132
 
129
- ## 5. Hand the human the stack, bottom first
133
+ ## 5. Hand the human each PR as it passes
130
134
 
131
135
  When a slice passes review: `em engagement set <model>.em <slug> <key> --state awaiting-merge`.
132
- Hand the human the PRs bottom-first, lowest level first, each with its evidence bundle
133
- (`reference/engagement.md`): the validator table, the reviewer's and critic's findings and any
134
- disagreement, and the per-invariant test map. Tell them, every time:
135
-
136
- - merge bottom-first, with a **merge commit** while any PR stacks on this one (implement.md §8
137
- rule 2a). Squash is forbidden in that state;
138
- - delete the head branch on merge, so GitHub retargets the PRs that stacked on it.
136
+ Hand the human the PR with its evidence bundle (`reference/engagement.md`): the validator table,
137
+ the reviewer's and critic's findings and any disagreement, and the per-invariant test map. Every
138
+ PR is independent — against `main`, carrying only its own slice — so the human merges them in
139
+ any order, with the project's usual merge strategy (squash included), and nothing else needs
140
+ retargeting or restacking. Suggest level order (upstream slices first) because it reads better,
141
+ not because anything depends on it.
139
142
 
140
143
  You never merge.
141
144
 
142
145
  ## 6. After each human merge
143
146
 
144
147
  1. Update `main` in your own checkout: `git switch main && git pull --ff-only`.
145
- 2. **Retarget check** (`reference/engagement.md`): `gh pr list --base impl/<key> --state open`
146
- must be empty. For each PR still listed (the head branch was not deleted),
147
- `gh pr edit <n> --base main`. Then record the new base on each dependent, keeping its state:
148
- `em engagement set <model>.em <slug> <dependent> --state <its state> --base main`.
149
- 3. `em engagement set <model>.em <slug> <key> --state merged`, then remove the worktree:
148
+ 2. `em engagement set <model>.em <slug> <key> --state merged`, then remove the worktree:
150
149
  `git worktree remove .claude/worktrees/<key>`.
151
- 4. When every slice of a level is `merged` or `gap`, open one follow-up PR for that level from
150
+ 3. When every slice of a level is `merged` or `gap`, open one follow-up PR for that level from
152
151
  `main`: `git switch -c engagement/<slug>-level-<n> main`, run
153
152
  `em slice mark-implemented <model>.em <key> <pr-url>` for each slice merged in the level,
154
153
  then `em slice index <model>.em`, commit, and `gh pr create --base main`. The human merges it
155
154
  like any other PR.
156
- 5. Recompute: `em engagement plan <model>.em <slug>`. Merges release holds
157
- (`multiple-unmerged-upstreams` drops to one upstream, a base moves to `main`). Continue with
158
- step 3 for anything newly startable.
155
+ 4. Recompute: `em engagement plan <model>.em <slug>`. A merge can release an
156
+ `upstream-outside-engagement-unmerged` hold once that upstream's doc reads `implemented`.
157
+ Continue with step 3 for anything newly startable.
159
158
 
160
159
  ## 7. Gaps
161
160
 
@@ -183,11 +182,12 @@ constitution), follow the gap protocol (`reference/engagement.md`):
183
182
  | Rule | Because |
184
183
  |---|---|
185
184
  | Never hand-edit `engagements/<slug>.md` | `em engagement set` and `close` are the only write paths; the Ledger table is generated |
186
- | Never restack or rebase a slice branch | Merge commits make restacking unnecessary; a rebase rewrites history a dependent was cut from |
187
- | Never squash a PR with an open dependent | It strands the dependent's history (implement.md §8 rule 2a) |
185
+ | 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 |
186
+ | Never rebase a slice branch | The branch is the implementer's; the lead orchestrates and records, it does not rewrite history |
188
187
  | Never run the implementer's work yourself | The lead orchestrates; code comes from a scoped implementer working from its own read of the spec |
189
188
  | Never dispatch beyond the ceiling | The ceiling was confirmed once for the engagement; exceeding it breaks that agreement |
190
- | 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 |
191
- | Never merge a PR | The human merges, bottom-first |
189
+ | Never cut a slice branch from the current HEAD | The base is `main` from the plan; the lead's HEAD may be anything |
190
+ | 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 |
191
+ | Never merge a PR | The human merges, in any order |
192
192
  | Never show the critic the reviewer's findings | The critic's value is an independent view; disagreement is a finding |
193
193
  | Never start a held slice, or ask "which slice first" | The plan decides order and holds; the human confirms only the ceiling |
@@ -27,17 +27,17 @@ closed engagement refuses every `set`.
27
27
  `em engagement close <model>.em <slug>` succeeds only when every slice is `merged` (recorded or
28
28
  inferred) or `gap`; `em engagement status` reports this as `closable`.
29
29
 
30
- A dependent's base changes once, when its upstream merges: record it with the dependent's
31
- current state and `--base main` (step 6.2), so the Ledger matches the PR's real base.
30
+ Every slice's `base` is `main` (MIL-280): recorded once at `building`, never changed. A Ledger
31
+ that still shows an `impl/<upstream>` base came from em ≤ 1.14.2; `plan` reports `main` and the
32
+ next `set` on that slice should record `--base main`.
32
33
 
33
34
  ## The evidence bundle (step 5)
34
35
 
35
- Hand the human one block per PR, bottom-first, in this shape:
36
+ Hand the human one block per PR as it passes review, in this shape:
36
37
 
37
38
  ```markdown
38
39
  ### <level n> · `<key>` · <PR URL>
39
- Base: `<base>` · Ledger: awaiting-merge · Stacked on it: <PR URLs of open dependents, or "none">
40
- Merge with: a merge commit (<a dependent is open | squash allowed: no open dependent>)
40
+ Base: `main` · Ledger: awaiting-merge · Independent: merges in any order with the project's usual strategy
41
41
 
42
42
  Validator (em-validator, <model>):
43
43
  | Check | Result |
@@ -61,20 +61,6 @@ Per-invariant tests (from em-implementer):
61
61
 
62
62
  Copy the agents' lines verbatim; never summarise a finding away.
63
63
 
64
- ## The retarget check (step 6.2)
65
-
66
- GitHub retargets every open PR whose base was a merged head branch to the merged PR's base, but
67
- only when that head branch is deleted. After each merge of `impl/<key>`:
68
-
69
- 1. `gh pr list --base impl/<key> --state open --json number,headRefName` must return `[]`.
70
- 2. For each PR it does list, run `gh pr edit <number> --base main`. Then record it:
71
- `em engagement set <model>.em <slug> <dependent> --state <its current state> --base main`.
72
- 3. Confirm with `gh pr view <number> --json baseRefName`.
73
-
74
- Because the lower PR merged with a merge commit, the dependent's diff against `main` shrinks to
75
- its own commits by itself. Never rebase it. If its diff still shows the upstream's commits, the
76
- lower PR was squashed: STOP and tell the human. Restacking that PR is their decision.
77
-
78
64
  ## The gap protocol (step 7)
79
65
 
80
66
  A gap is a question only the model can answer: the doc is wrong, incomplete, or contradicts the
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: event-modeling
3
- em-version: 1.14.2
3
+ em-version: 1.15.0
4
4
  description: >-
5
5
  Use when the user runs `/em: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
  em:discover, em:design, em:implement, em:conform,
9
9
  or em:review — or, for building a planned set of ready slices through scoped
10
- sub-agents to a stack of PRs (an `em engagement`), em:engagement. If you already
10
+ sub-agents to one PR per slice against main (an `em engagement`), em: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.
@@ -29,7 +29,7 @@ phase lives in.
29
29
  | `implement` | `em:implement` — building one ratified slice into merged, tested code |
30
30
  | `conform`, `validate` | `em:conform` — drift-checking a model against its codebase, walking validation diagnostics |
31
31
  | `watch`, `review` | `em:review` — the live browser viewer, facilitated stakeholder walkthroughs |
32
- | `engagement` | `em:engagement` — build a planned set of ready slices through scoped sub-agents to a stack of PRs |
32
+ | `engagement` | `em:engagement` — build a planned set of ready slices through scoped sub-agents to one PR per slice, each against main |
33
33
 
34
34
  ## Routing logic
35
35
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: implement
3
- em-version: 1.14.2
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