@milehimikey/em 1.13.1 → 1.14.1

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 (235) hide show
  1. package/.claude/agents/em-critic.md +26 -0
  2. package/.claude/agents/em-implementer.md +34 -0
  3. package/.claude/agents/em-reviewer.md +31 -0
  4. package/.claude/agents/em-validator.md +27 -0
  5. package/.claude/skills/event-modeling/SKILL.md +50 -11
  6. package/.claude/skills/event-modeling-conform/SKILL.md +1 -1
  7. package/.claude/skills/event-modeling-design/SKILL.md +127 -18
  8. package/.claude/skills/event-modeling-discover/SKILL.md +1 -1
  9. package/.claude/skills/event-modeling-engagement/SKILL.md +192 -0
  10. package/.claude/skills/event-modeling-engagement/reference/engagement.md +143 -0
  11. package/.claude/skills/event-modeling-implement/SKILL.md +1 -1
  12. package/.claude/skills/event-modeling-implement/reference/implement.md +38 -11
  13. package/.claude/skills/event-modeling-review/SKILL.md +2 -2
  14. package/.claude/skills/event-modeling-shared/reference/em-dsl.md +279 -189
  15. package/.claude/skills/event-modeling-shared/reference/operating-principles.md +61 -0
  16. package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +116 -5
  17. package/.claude/skills/event-modeling-shared/templates/constitution.md +18 -1
  18. package/.claude/skills/event-modeling-shared/templates/slice.md +64 -39
  19. package/.claude/skills/event-modeling-shared/templates/state.md +5 -1
  20. package/.claude-plugin/marketplace.json +14 -0
  21. package/README.md +25 -11
  22. package/dist/catalog/apiFirst.d.ts +28 -0
  23. package/dist/catalog/apiFirst.js +49 -0
  24. package/dist/catalog/apiFirst.js.map +1 -0
  25. package/dist/catalog/docJoin.d.ts +13 -0
  26. package/dist/catalog/docJoin.js +11 -0
  27. package/dist/catalog/docJoin.js.map +1 -1
  28. package/dist/catalog/docModelConsistencyValidate.js +44 -4
  29. package/dist/catalog/docModelConsistencyValidate.js.map +1 -1
  30. package/dist/catalog/invariantsValidate.d.ts +4 -0
  31. package/dist/catalog/invariantsValidate.js +102 -0
  32. package/dist/catalog/invariantsValidate.js.map +1 -0
  33. package/dist/catalog/scenarios.d.ts +15 -0
  34. package/dist/catalog/scenarios.js +97 -0
  35. package/dist/catalog/scenarios.js.map +1 -0
  36. package/dist/catalog/sliceDoc.d.ts +8 -0
  37. package/dist/catalog/sliceDoc.js +9 -0
  38. package/dist/catalog/sliceDoc.js.map +1 -1
  39. package/dist/catalog/sliceReadyValidate.d.ts +31 -4
  40. package/dist/catalog/sliceReadyValidate.js +66 -8
  41. package/dist/catalog/sliceReadyValidate.js.map +1 -1
  42. package/dist/catalog/sliceSections.d.ts +55 -0
  43. package/dist/catalog/sliceSections.js +317 -0
  44. package/dist/catalog/sliceSections.js.map +1 -0
  45. package/dist/cli/agentsMd.js +7 -1
  46. package/dist/cli/agentsMd.js.map +1 -1
  47. package/dist/cli/api.d.ts +90 -0
  48. package/dist/cli/api.js +318 -0
  49. package/dist/cli/api.js.map +1 -0
  50. package/dist/cli/ciInit.d.ts +82 -21
  51. package/dist/cli/ciInit.js +468 -64
  52. package/dist/cli/ciInit.js.map +1 -1
  53. package/dist/cli/conformScope.d.ts +28 -0
  54. package/dist/cli/conformScope.js +67 -0
  55. package/dist/cli/conformScope.js.map +1 -1
  56. package/dist/cli/coverage.d.ts +9 -0
  57. package/dist/cli/coverage.js +60 -8
  58. package/dist/cli/coverage.js.map +1 -1
  59. package/dist/cli/defer.d.ts +55 -0
  60. package/dist/cli/defer.js +244 -0
  61. package/dist/cli/defer.js.map +1 -0
  62. package/dist/cli/engagement.d.ts +210 -0
  63. package/dist/cli/engagement.js +444 -0
  64. package/dist/cli/engagement.js.map +1 -0
  65. package/dist/cli/engagementFile.d.ts +86 -0
  66. package/dist/cli/engagementFile.js +255 -0
  67. package/dist/cli/engagementFile.js.map +1 -0
  68. package/dist/cli/metrics.d.ts +10 -0
  69. package/dist/cli/metrics.js +49 -1
  70. package/dist/cli/metrics.js.map +1 -1
  71. package/dist/cli/pluginPin.d.ts +55 -0
  72. package/dist/cli/pluginPin.js +188 -0
  73. package/dist/cli/pluginPin.js.map +1 -0
  74. package/dist/cli/ratify.d.ts +27 -2
  75. package/dist/cli/ratify.js +112 -13
  76. package/dist/cli/ratify.js.map +1 -1
  77. package/dist/cli/reratify.d.ts +4 -2
  78. package/dist/cli/reratify.js +41 -16
  79. package/dist/cli/reratify.js.map +1 -1
  80. package/dist/cli/scopeInputs.d.ts +48 -0
  81. package/dist/cli/scopeInputs.js +176 -0
  82. package/dist/cli/scopeInputs.js.map +1 -0
  83. package/dist/cli/skillCheck.d.ts +15 -1
  84. package/dist/cli/skillCheck.js +22 -1
  85. package/dist/cli/skillCheck.js.map +1 -1
  86. package/dist/cli/skillDirs.d.ts +5 -0
  87. package/dist/cli/skillDirs.js +13 -1
  88. package/dist/cli/skillDirs.js.map +1 -1
  89. package/dist/cli/skillSync.d.ts +4 -0
  90. package/dist/cli/skillSync.js +23 -0
  91. package/dist/cli/skillSync.js.map +1 -1
  92. package/dist/cli/sliceNew.d.ts +11 -7
  93. package/dist/cli/sliceNew.js +91 -18
  94. package/dist/cli/sliceNew.js.map +1 -1
  95. package/dist/cli/sliceSync.d.ts +50 -0
  96. package/dist/cli/sliceSync.js +170 -0
  97. package/dist/cli/sliceSync.js.map +1 -0
  98. package/dist/cli/status.d.ts +24 -1
  99. package/dist/cli/status.js +20 -1
  100. package/dist/cli/status.js.map +1 -1
  101. package/dist/cli/systemInputs.d.ts +53 -10
  102. package/dist/cli/systemInputs.js +186 -11
  103. package/dist/cli/systemInputs.js.map +1 -1
  104. package/dist/cli/upgrade.d.ts +16 -3
  105. package/dist/cli/upgrade.js +366 -30
  106. package/dist/cli/upgrade.js.map +1 -1
  107. package/dist/cli/usageLog.d.ts +4 -2
  108. package/dist/cli/usageLog.js +4 -2
  109. package/dist/cli/usageLog.js.map +1 -1
  110. package/dist/cli.js +599 -94
  111. package/dist/cli.js.map +1 -1
  112. package/dist/emit/api.d.ts +29 -0
  113. package/dist/emit/api.js +220 -0
  114. package/dist/emit/api.js.map +1 -0
  115. package/dist/emit/apiCheckJson.d.ts +3 -0
  116. package/dist/emit/apiCheckJson.js +21 -0
  117. package/dist/emit/apiCheckJson.js.map +1 -0
  118. package/dist/emit/codeownersJson.d.ts +3 -0
  119. package/dist/emit/codeownersJson.js +19 -0
  120. package/dist/emit/codeownersJson.js.map +1 -0
  121. package/dist/emit/diffJson.d.ts +1 -1
  122. package/dist/emit/diffJson.js +8 -1
  123. package/dist/emit/diffJson.js.map +1 -1
  124. package/dist/emit/engagementJson.d.ts +8 -0
  125. package/dist/emit/engagementJson.js +46 -0
  126. package/dist/emit/engagementJson.js.map +1 -0
  127. package/dist/emit/glossaryJson.d.ts +1 -1
  128. package/dist/emit/glossaryJson.js +4 -1
  129. package/dist/emit/glossaryJson.js.map +1 -1
  130. package/dist/emit/json.d.ts +17 -1
  131. package/dist/emit/json.js +30 -1
  132. package/dist/emit/json.js.map +1 -1
  133. package/dist/emit/metricsJson.d.ts +1 -1
  134. package/dist/emit/metricsJson.js +4 -1
  135. package/dist/emit/metricsJson.js.map +1 -1
  136. package/dist/emit/queryJson.d.ts +1 -1
  137. package/dist/emit/queryJson.js +7 -1
  138. package/dist/emit/queryJson.js.map +1 -1
  139. package/dist/emit/scopeJson.d.ts +12 -0
  140. package/dist/emit/scopeJson.js +26 -0
  141. package/dist/emit/scopeJson.js.map +1 -0
  142. package/dist/emit/skillCheckJson.d.ts +3 -2
  143. package/dist/emit/skillCheckJson.js +10 -2
  144. package/dist/emit/skillCheckJson.js.map +1 -1
  145. package/dist/emit/statusJson.d.ts +1 -1
  146. package/dist/emit/statusJson.js +15 -1
  147. package/dist/emit/statusJson.js.map +1 -1
  148. package/dist/emit/systemJson.d.ts +15 -8
  149. package/dist/emit/systemJson.js +28 -13
  150. package/dist/emit/systemJson.js.map +1 -1
  151. package/dist/emit/validateJson.d.ts +3 -3
  152. package/dist/emit/validateJson.js +10 -4
  153. package/dist/emit/validateJson.js.map +1 -1
  154. package/dist/mcp/server.d.ts +1 -1
  155. package/dist/mcp/server.js +163 -31
  156. package/dist/mcp/server.js.map +1 -1
  157. package/dist/model/diff.d.ts +4 -1
  158. package/dist/model/diff.js +44 -8
  159. package/dist/model/diff.js.map +1 -1
  160. package/dist/model/glossary.d.ts +2 -0
  161. package/dist/model/glossary.js +1 -0
  162. package/dist/model/glossary.js.map +1 -1
  163. package/dist/model/model.d.ts +55 -2
  164. package/dist/model/model.js +57 -0
  165. package/dist/model/model.js.map +1 -1
  166. package/dist/model/qualifiedRef.d.ts +18 -0
  167. package/dist/model/qualifiedRef.js +26 -0
  168. package/dist/model/qualifiedRef.js.map +1 -1
  169. package/dist/model/queryIndex.d.ts +9 -1
  170. package/dist/model/queryIndex.js +18 -2
  171. package/dist/model/queryIndex.js.map +1 -1
  172. package/dist/model/rules.d.ts +143 -2
  173. package/dist/model/rules.js +162 -3
  174. package/dist/model/rules.js.map +1 -1
  175. package/dist/model/validate.d.ts +40 -0
  176. package/dist/model/validate.js +147 -1
  177. package/dist/model/validate.js.map +1 -1
  178. package/dist/parser/ast.d.ts +31 -3
  179. package/dist/parser/parser.js +148 -14
  180. package/dist/parser/parser.js.map +1 -1
  181. package/dist/query/format.js +1 -1
  182. package/dist/query/format.js.map +1 -1
  183. package/dist/query/verbs.d.ts +6 -0
  184. package/dist/query/verbs.js +6 -2
  185. package/dist/query/verbs.js.map +1 -1
  186. package/dist/system/adaptation.d.ts +14 -0
  187. package/dist/system/adaptation.js +49 -0
  188. package/dist/system/adaptation.js.map +1 -0
  189. package/dist/system/codeowners.d.ts +77 -0
  190. package/dist/system/codeowners.js +242 -0
  191. package/dist/system/codeowners.js.map +1 -0
  192. package/dist/system/manifest.d.ts +10 -5
  193. package/dist/system/manifest.js +54 -26
  194. package/dist/system/manifest.js.map +1 -1
  195. package/dist/system/migrateManifest.d.ts +28 -0
  196. package/dist/system/migrateManifest.js +155 -0
  197. package/dist/system/migrateManifest.js.map +1 -0
  198. package/dist/system/scope.d.ts +46 -0
  199. package/dist/system/scope.js +132 -0
  200. package/dist/system/scope.js.map +1 -0
  201. package/dist/system/verify.d.ts +50 -13
  202. package/dist/system/verify.js +179 -58
  203. package/dist/system/verify.js.map +1 -1
  204. package/dist/templates.d.ts +2 -2
  205. package/dist/templates.js +23 -2
  206. package/dist/templates.js.map +1 -1
  207. package/package.json +5 -2
  208. package/plugin/.claude-plugin/plugin.json +18 -0
  209. package/plugin/agents/em-critic.md +27 -0
  210. package/plugin/agents/em-implementer.md +35 -0
  211. package/plugin/agents/em-reviewer.md +32 -0
  212. package/plugin/agents/em-validator.md +28 -0
  213. package/plugin/shared/reference/em-dsl.md +871 -0
  214. package/plugin/shared/reference/methodology.md +329 -0
  215. package/plugin/shared/reference/operating-principles.md +222 -0
  216. package/plugin/shared/reference/slice-doc-schema.md +574 -0
  217. package/plugin/shared/templates/conformance-report.md +85 -0
  218. package/plugin/shared/templates/constitution.md +136 -0
  219. package/plugin/shared/templates/model-readme.md +46 -0
  220. package/plugin/shared/templates/slice.md +251 -0
  221. package/plugin/shared/templates/state.md +77 -0
  222. package/plugin/skills/conform/SKILL.md +93 -0
  223. package/plugin/skills/conform/reference/conform.md +428 -0
  224. package/plugin/skills/design/SKILL.md +298 -0
  225. package/plugin/skills/discover/SKILL.md +90 -0
  226. package/plugin/skills/discover/reference/extract.md +147 -0
  227. package/plugin/skills/engagement/SKILL.md +193 -0
  228. package/plugin/skills/engagement/reference/engagement.md +144 -0
  229. package/plugin/skills/event-modeling/SKILL.md +132 -0
  230. package/plugin/skills/implement/SKILL.md +61 -0
  231. package/plugin/skills/implement/reference/implement.md +439 -0
  232. package/plugin/skills/review/SKILL.md +74 -0
  233. package/dist/emit/typespec.d.ts +0 -26
  234. package/dist/emit/typespec.js +0 -356
  235. package/dist/emit/typespec.js.map +0 -1
@@ -0,0 +1,192 @@
1
+ ---
2
+ name: event-modeling-engagement
3
+ em-version: 1.14.1
4
+ description: >-
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.
10
+ ---
11
+
12
+ # Event Modeling — engagement (lead session)
13
+
14
+ Goal: take an engagement (a named chunk of the model, `<model dir>/engagements/<slug>.md`) from
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.
18
+
19
+ **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
22
+ (`../event-modeling-implement/reference/implement.md`) for its one slice; that contract is
23
+ theirs, not yours.
24
+
25
+ The sub-agents are `em-implementer`, `em-validator`, `em-reviewer` and `em-critic`. Under the
26
+ plugin their dispatch names are `em:em-implementer`, `em:em-validator`, `em:em-reviewer` and
27
+ `em:em-critic`. In a vendored repo they live in `.claude/agents/`; if they are missing, STOP and
28
+ tell the user to run `em skill sync` (or `em upgrade`).
29
+
30
+ Throughout, `<model>.em` is the model file and `<slug>` the engagement's name. Every command
31
+ below is real; run it as written.
32
+
33
+ ## 1. Preconditions — STOP on each
34
+
35
+ Run the shared preconditions first (tool check, bundle currency, locate the model):
36
+ `../event-modeling-shared/reference/operating-principles.md` ("Preconditions"). Then:
37
+
38
+ 1. **Constitution ratified.** `em status <model>.em` names the constitution (`constitution.md`
39
+ beside the model, or `.specify/memory/constitution.md`). STOP if it is missing or its
40
+ `ratifiedBy:` is empty (spec-kit: no `**Ratified**:` footer). Say so and point at
41
+ `event-modeling-implement`'s §7; never draft house rules to get moving.
42
+ 2. **Foundation PR merged.** Ask the human for the foundation PR (implement.md §8) and confirm it
43
+ has merged into `main` (`gh pr view <n> --json state` shows `MERGED`). STOP if there is none
44
+ 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>,
52
+ validator=<model>, reviewer=<model>, critic=<model|codex>`. If it is absent, say once:
53
+ "no Agent models line — using implementer=sonnet, validator=sonnet, reviewer=sonnet,
54
+ 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
+ fails, STOP and ask the human to add `.claude/worktrees/` to `.gitignore` in its own commit
58
+ on `main`.
59
+ 6. **The engagement exists.** `em engagement status <model>.em <slug>`. If there is no such
60
+ engagement, ask the human which slices it covers (a list, a context, or "everything
61
+ downstream of X") and run `em engagement new <model>.em <slug> --slices a,b,c` (or
62
+ `--context <C>`, or `--downstream-of <ref>`) `--by "<their name>"`. When `new` warns that the
63
+ selection has several unconnected components, relay its suggestion (one engagement each)
64
+ and let the human decide before going on.
65
+
66
+ ## 2. Plan and confirm the ceiling once
67
+
68
+ 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:
72
+
73
+ > "Ceiling N from the plan; proceed?"
74
+
75
+ Ask it once per engagement. If the human names a lower number, use it for this session. **Never
76
+ ask "which slice first"**: the levels decide the order, and the ceiling decides how many at once.
77
+ A held slice is never started; the plan releases it when its hold clears.
78
+
79
+ ## 3. Per level: cut the worktree, then dispatch the implementer
80
+
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
+
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.
88
+ 2. If `impl/<key>` already exists (`git rev-parse --verify --quiet impl/<key>`) or
89
+ `.claude/worktrees/<key>` already exists, STOP for that slice and report it. Never delete,
90
+ reuse or reset someone's branch.
91
+ 3. Cut the worktree yourself:
92
+ `git worktree add .claude/worktrees/<key> -b impl/<key> <base>`
93
+ 4. Record it:
94
+ `em engagement set <model>.em <slug> <key> --state building --branch impl/<key> --base <base>`
95
+ 5. Dispatch `em-implementer` (`em:em-implementer` under the plugin) on the implementer model.
96
+ Its prompt is ONLY the slice key and the absolute worktree path. It reads its own spec, the
97
+ constitution and the implement contract. Give it no plan, no other slice, and no merge or
98
+ stacking instructions.
99
+
100
+ ## 4. Validate, review, criticise
101
+
102
+ When the implementer returns a PR URL (and a per-invariant test map):
103
+
104
+ 1. `em engagement set <model>.em <slug> <key> --state validating --pr <url>`. Check the PR's
105
+ base: `gh pr view <url> --json baseRefName` must equal the Ledger's base. If not, fix it
106
+ with `gh pr edit <url> --base <base>`. That is a lead step; the implementer never changes a
107
+ base.
108
+ 2. Dispatch `em-validator` (`em:em-validator`) with the slice key and the worktree path. It
109
+ returns one PASS/FAIL line per check and `OVERALL: PASS` or a failure.
110
+ 3. On `OVERALL: PASS`: `em engagement set <model>.em <slug> <key> --state review`. Dispatch
111
+ `em-reviewer` (`em:em-reviewer`) with the slice key and the PR URL. Dispatch `em-critic`
112
+ (`em:em-critic`) with the same two inputs, on the critic model, in fresh context. **Never
113
+ show the critic the reviewer's findings.** When the critic is `codex`, run the
114
+ prerequisite checks and the `codex exec` invocation in `reference/engagement.md` ("Codex
115
+ critic") in a fresh `.claude/worktrees/review-<pr>`, treat its output file as the critic's findings, and
116
+ fall back to `em-critic` (saying so in the evidence bundle) if any prerequisite fails.
117
+ 4. Compare the two findings lists. A blocker or major finding raised by only one of the two is
118
+ itself a finding for the human (record it in the evidence bundle).
119
+ 5. **Findings go back to the SAME implementer.** On a validator FAIL, or any `blocker`/`major`
120
+ finding: `em engagement set <model>.em <slug> <key> --state building`, then continue the same
121
+ implementer agent (same session, same branch, same worktree) with the failing check lines or
122
+ the findings. Never start a fresh implementer for it, and never fix the code yourself. When
123
+ it reports back, go back to step 4.1: the validator always re-runs before review does. If the
124
+ same finding survives two rounds, stop the loop and put it in the evidence bundle for the
125
+ human.
126
+ 6. `minor` findings do not loop. They go in the evidence bundle.
127
+
128
+ ## 5. Hand the human the stack, bottom first
129
+
130
+ 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.
138
+
139
+ You never merge.
140
+
141
+ ## 6. After each human merge
142
+
143
+ 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:
149
+ `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
151
+ `main`: `git switch -c engagement/<slug>-level-<n> main`, run
152
+ `em slice mark-implemented <model>.em <key> <pr-url>` for each slice merged in the level,
153
+ then `em slice index <model>.em`, commit, and `gh pr create --base main`. The human merges it
154
+ like any other PR.
155
+ 5. Recompute: `em engagement plan <model>.em <slug>`. Merges release holds
156
+ (`multiple-unmerged-upstreams` drops to one upstream, a base moves to `main`). Continue with
157
+ step 3 for anything newly startable.
158
+
159
+ ## 7. Gaps
160
+
161
+ When the implementer stops on a gap (the doc is wrong, incomplete, or contradicts the
162
+ constitution), follow the gap protocol (`reference/engagement.md`):
163
+
164
+ 1. `em engagement set <model>.em <slug> <key> --state gap`.
165
+ 2. Add the question as a dated bullet under the model's `.event-modeling.md`
166
+ `## Open questions / parking lot`:
167
+ `- [ ] YYYY-MM-DD: <key> — <the question, citing the doc line> — source: engagement <slug>`.
168
+ 3. Continue with the other slices. Leave the gap slice's dependents unstarted, and tell the
169
+ human which they are. The doc is fixed in a design session, never in this one.
170
+
171
+ ## 8. End
172
+
173
+ 1. `em state log-usage <model>.em --phases engagement`.
174
+ 2. `em engagement status <model>.em <slug>`. When it reports `closable: true` (every slice
175
+ `merged` or `gap`), run `em engagement close <model>.em <slug>`. Otherwise leave it open: the
176
+ next lead session resumes from the Ledger.
177
+ 3. Report: what merged (PR links), what is awaiting merge, what is held and why, each gap with
178
+ its question, and every unresolved reviewer or critic disagreement.
179
+
180
+ ## Never do
181
+
182
+ | Rule | Because |
183
+ |---|---|
184
+ | 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) |
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 |
188
+ | 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 |
191
+ | Never show the critic the reviewer's findings | The critic's value is an independent view; disagreement is a finding |
192
+ | Never start a held slice, or ask "which slice first" | The plan decides order and holds; the human confirms only the ceiling |
@@ -0,0 +1,143 @@
1
+ # Engagement reference — the lead session's rules
2
+
3
+ The `event-modeling-engagement` skill's steps refer here by name. The commands are documented in
4
+ full in `docs/cli.md` (`em engagement`) and the file format in `docs/engagement-schema.md`;
5
+ neither is vendored, and this file repeats only what the lead needs mid-session.
6
+
7
+ ## The Ledger state machine
8
+
9
+ Every Ledger write is `em engagement set <model>.em <slug> <key> --state <state> [--branch <b>]
10
+ [--base <b>] [--pr <url>]`. The command accepts any state at any time, so the order below is the
11
+ skill's discipline, not something em enforces. The exceptions em does enforce: setting the same
12
+ state and values again is a no-op, `merged` is terminal (every later `set` is refused), and a
13
+ closed engagement refuses every `set`.
14
+
15
+ | State | Set at | Means | Next |
16
+ |---|---|---|---|
17
+ | `planned` | `em engagement new` | Selected; nothing cut yet | `building` (step 3) or `held` |
18
+ | `building` | step 3, after `git worktree add` (with `--branch impl/<key> --base <base>`); step 4.5 when findings go back | The implementer owns the worktree | `validating`, or `gap` |
19
+ | `validating` | step 4.1 (with `--pr <url>` the first time) | `em-validator` is running on the PR | `review` on PASS, `building` on FAIL |
20
+ | `review` | step 4.3 | `em-reviewer` and `em-critic` are reading the PR | `awaiting-merge`, or `building` on blocker/major findings |
21
+ | `awaiting-merge` | step 5 | Handed to the human with its evidence bundle | `merged` |
22
+ | `merged` | step 6.3, after the human merges (also inferred, never written, once the doc reads `status: implemented`) | Terminal | — |
23
+ | `held` | only when the human asks to park a slice (`heldBy: human`) | A human hold; the plan's own computed holds are separate (`planHeld`) and never written | `planned` when the human releases it |
24
+ | `gap` | step 7 | The implementer stopped on a question the doc must answer | Stays `gap`; the slice comes back in a later engagement once its doc is re-ratified |
25
+
26
+ `em engagement close <model>.em <slug>` succeeds only when every slice is `merged` (recorded or
27
+ inferred) or `gap`; `em engagement status` reports this as `closable`.
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.
31
+
32
+ ## The evidence bundle (step 5)
33
+
34
+ Hand the human one block per PR, bottom-first, in this shape:
35
+
36
+ ```markdown
37
+ ### <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>)
40
+
41
+ Validator (em-validator, <model>):
42
+ | Check | Result |
43
+ |---|---|
44
+ | `em validate <model>.em --slice-ready <key>` | PASS |
45
+ | `em coverage <model>.em --slice <key> --tests <dir> --strict` | PASS |
46
+ | test command `<cmd>` | PASS |
47
+ | diff footprint inside the slice package | PASS |
48
+ | no diff under `slices/**`, `*.em`, `constitution.md`, `engagements/` | PASS |
49
+ | PR body cites the slice doc | PASS |
50
+
51
+ Reviewer (em-reviewer, <model>): <findings list verbatim, or NO FINDINGS>
52
+ Critic (em-critic, <model>): <findings list verbatim, or NO FINDINGS>
53
+ Disagreements: <each blocker/major raised by one and not the other, or "none">
54
+ Rounds: <how many times findings went back to the implementer>; unresolved: <findings that
55
+ survived two rounds, or "none">
56
+
57
+ Per-invariant tests (from em-implementer):
58
+ - INV-<id> -> <test file>::<test name>
59
+ ```
60
+
61
+ Copy the agents' lines verbatim; never summarise a finding away.
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
+ ## The gap protocol (step 7)
78
+
79
+ A gap is a question only the model can answer: the doc is wrong, incomplete, or contradicts the
80
+ constitution. The implementer stops and reports it as the doc line plus the question.
81
+
82
+ 1. `em engagement set <model>.em <slug> <key> --state gap`. Leave the worktree and branch as they
83
+ are.
84
+ 2. Append one bullet to `.event-modeling.md` under `## Open questions / parking lot`:
85
+ `- [ ] YYYY-MM-DD: <key> — <question, citing the doc line> — source: engagement <slug>`
86
+ (today's local date).
87
+ 3. Every slice downstream of the gap stays unstarted. Name them to the human.
88
+ 4. Carry on with every other startable slice. Never answer the question yourself, never edit the
89
+ doc, and never let the implementer guess.
90
+
91
+ The question is answered in a design session (`event-modeling-design`), which re-ratifies the
92
+ doc. The slice is then built in a later engagement.
93
+
94
+ ## Model selection
95
+
96
+ Models come from the constitution's `- **Agent models:** implementer=<model>, validator=<model>,
97
+ reviewer=<model>, critic=<model|codex>` line, or from the defaults when the line is absent:
98
+ implementer=sonnet, validator=sonnet, reviewer=sonnet, critic=opus. Pass the model with each
99
+ dispatch; the agent definitions fix none.
100
+
101
+ **The critic never runs on the implementer's model.** If the line names the same model for both,
102
+ STOP before the first critic dispatch and tell the human. A critic on the implementer's model
103
+ shares its blind spots, which defeats its purpose. Proceed without a critic only if the human
104
+ says so, and record that choice in the final report.
105
+
106
+ ## Codex critic
107
+
108
+ When the constitution's agent-models line says `critic=codex`, the critic runs through Codex instead
109
+ of as the `em-critic` sub-agent. Its findings use the same list shape, and every rule above applies
110
+ to them unchanged: fresh context, no access to the reviewer's findings, and disagreement is a
111
+ finding. The Claude critic path is untouched.
112
+
113
+ **Prerequisites (check; never write).** Any miss is reported to the human, the Claude critic
114
+ (`em-critic`) runs for that PR instead, and the evidence bundle says "critic: codex unavailable
115
+ (<reason>), ran em-critic":
116
+
117
+ 1. `command -v codex` succeeds.
118
+ 2. The project is trusted in Codex: `~/.codex/config.toml` has a `[projects."<repo root>"]` table with
119
+ `trust_level = "trusted"`. Read it; never add it. Trust is the human's to grant.
120
+ 3. If the project keeps `.codex/rules`, it is present in the review checkout. A repo without
121
+ `.codex/` is fine: the invocation below needs no rules file, and the lead never creates one.
122
+
123
+ **Invocation** (flags verified against `codex exec --help`, codex-cli 0.159.1). Cut the review
124
+ worktree at the PR head, save the diff, then run Codex read-only:
125
+
126
+ ```
127
+ git worktree add --detach .claude/worktrees/review-<pr> <pr-head-sha>
128
+ gh pr diff <pr> > <scratch>/pr-<pr>.diff
129
+ codex exec --cd .claude/worktrees/review-<pr> --sandbox read-only --ephemeral \
130
+ --add-dir <scratch> -o <scratch>/critic-<pr>.txt "<prompt>" < /dev/null
131
+ ```
132
+
133
+ `< /dev/null` is required: without it `codex exec` waits on stdin ("Reading additional input from
134
+ stdin...") and hangs. `-o` (`--output-last-message`) writes only the final message to the file.
135
+ The prompt gives the slice doc path, the constitution path and the diff path, says it is read-only,
136
+ and asks for ONLY the `em-critic` list: `- [<severity>] <file:line or doc §> — <finding>`
137
+ (`blocker`|`major`|`minor`), every finding citing a slice doc line or constitution rule, or
138
+ `NO FINDINGS` naming what was checked. Do not pass the reviewer's findings.
139
+
140
+ **Parse.** The output file is the critic's findings: keep lines matching `^- \[(blocker|major|minor)\] `
141
+ or the `NO FINDINGS` line. If the file is missing, empty, or has neither, treat it as a failed run:
142
+ report it and fall back to `em-critic`. Then continue with step 4 onward exactly as for the Claude
143
+ critic. Remove the review worktree afterwards (`git worktree remove --force`).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: event-modeling-implement
3
- em-version: 1.13.1
3
+ em-version: 1.14.1
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
@@ -90,10 +90,10 @@ section — and the routing from it is mechanical, not a technical choice you ma
90
90
  catch. An endpoint on a view the model shows no `ui` reading is a gap to surface the same way
91
91
  (MIL-215) — conform will classify it as a **model gap**, never drift to delete, once you flag
92
92
  it (`../../event-modeling-conform/reference/conform.md`, Flow step 4).
93
- - **`public` events and views** are the model's published integration surface: their shape is a
94
- contract, not an implementation detail. `em validate --list-public` lists them; `em typespec`
95
- is the POC generator for a downstream schema. Changing a public element's shape is a ratified
96
- delta, never an implementation-time choice.
93
+ - **`public` commands, events and views** are the model's published integration surface: their
94
+ shape is a contract, not an implementation detail. `em validate --list-public` lists them;
95
+ `em api generate` writes the model-owned contract (`<model dir>/contracts/<model key>.tsp`).
96
+ Changing a public element's shape is a ratified delta, never an implementation-time choice.
97
97
 
98
98
  For timeline context, read the slice's surroundings in the `.em` (what triggers it, what
99
99
  consumes its output) — the slice's own diagram (`slices/<slice-key>.svg`) shows its canonical
@@ -161,7 +161,9 @@ undocumented ordering, a contradiction with adjacent code. The discipline:
161
161
  `ratifiedBy` set): once the human has answered, the doc changes by `em slice reratify
162
162
  <model>.em <slice-key>` (bumps `version:`, clears the old sign-off, leaves `status` alone),
163
163
  the answer is written into the doc, and the human re-signs with `em slice ratify <model>.em
164
- <slice-key> --by <name>`. That is the human's step, not yours — you never run `ratify`, and
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
166
+ yours — you never run `ratify`, and
165
167
  the doc is not ratified again until they do; resume the build after that.
166
168
  - **Never edit the ratified doc to record your own answer**, and never quietly pick a behavior
167
169
  a business person could have an opinion on. Silent divergence is the failure mode the whole
@@ -304,12 +306,26 @@ sibling slice's package to reuse it — the boundary the constitution drew is go
304
306
  handlers, no projections — contracts only.** Because: a handler or a projection belongs to
305
307
  the slice that owns the behavior behind it; folding one into the foundation PR turns a shared
306
308
  contract into a pre-empted slice.
307
- 2. **It merges before any slice PR opens.** Every slice branch is cut from `main` *after* the
308
- foundation PR has landed there — never from a commit that predates it, and never alongside an
309
- open, unmerged foundation PR. A slice PR never carries foundation files. Because: a slice PR
310
- opened while the foundation is still in review shows a diff dominated by files the slice
311
- didn't write and can't be held accountable for, and its merge depends on someone else's
312
- review timeline instead of its own.
309
+ 2. **It merges before any slice PR opens.** Every slice branch is cut *after* the foundation PR
310
+ 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.
328
+
313
329
  3. **A slice never creates, edits, or reaches into another slice's code.** It *imports* events —
314
330
  only events — from wherever the foundation placed them; a sibling slice's handlers, storage,
315
331
  and other internals stay off limits. Because: the boundary the constitution drew only holds if
@@ -400,6 +416,17 @@ everything a spec holds. Don't introduce an intermediate spec document of your o
400
416
  | Never commit an authored intermediate spec | The slice is the spec; anything between it and the code is a rendering |
401
417
  | Never open a slice PR before the foundation PR has merged | The foundation is what makes an event a stable shared contract — a slice built ahead of it is building on a moving target (§8) |
402
418
  | Never implement more than one slice doc in a PR | The PR is the durable record of one spec's implementation; `mark-implemented`, coverage, and conformance all key on one doc ↔ one `implementedIn` |
419
+ | Stay on your side of the seam: never edit another model's directory, slice docs or contract file | Another model's `public` element is its owners' decision; a needed change goes to them as a seam change request, not into your PR |
420
+ | Never hand-edit a generated contract (`contracts/*.tsp`) | It is derived from the model by `em api generate`; a hand edit is a contract change nobody ratified |
421
+
422
+ **Mirror image of the design write scope (MIL-236).** The design session never writes generated
423
+ contracts, SDD/spec artifacts (`specs/`, `.specify/`), implementation source, or a draft's
424
+ `version:`, and never reads code as evidence for a modeling decision (see
425
+ `../../event-modeling-shared/reference/operating-principles.md`, "Write scope and evidence").
426
+ Implementation is the other side: implement reads them; design never writes them. You read the
427
+ contract and the constitution as inputs, work in code and (on spec-kit projects) the `specs/`
428
+ container per §9, and never write the model or its slice docs (except the two §6 fields at
429
+ merge).
403
430
 
404
431
  ## 11. Afterward: the loop closes
405
432
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: event-modeling-review
3
- em-version: 1.13.1
3
+ em-version: 1.14.1
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
@@ -56,7 +56,7 @@ review:` marker (mirrors `Last conformance:`).
56
56
  **Per-slice outcome.** A slice whose open questions are all resolved in the room →
57
57
  `em slice review <model>.em <key> --by <name>` (flips its doc to `status: reviewed` and records
58
58
  `reviewedBy:`/`reviewedOn:`). Anything still open stays `draft` — the walkthrough doesn't decide
59
- it, the next session or the open-questions list does.
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.
60
60
 
61
61
  **The facilitator never ratifies, never offers to ratify, and never suggests ratification in a
62
62
  review session. Ratification is a separate human gate after review**