@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.
- package/.claude/agents/em-critic.md +26 -0
- package/.claude/agents/em-implementer.md +34 -0
- package/.claude/agents/em-reviewer.md +31 -0
- package/.claude/agents/em-validator.md +27 -0
- package/.claude/skills/event-modeling/SKILL.md +50 -11
- package/.claude/skills/event-modeling-conform/SKILL.md +1 -1
- package/.claude/skills/event-modeling-design/SKILL.md +127 -18
- package/.claude/skills/event-modeling-discover/SKILL.md +1 -1
- package/.claude/skills/event-modeling-engagement/SKILL.md +192 -0
- package/.claude/skills/event-modeling-engagement/reference/engagement.md +143 -0
- package/.claude/skills/event-modeling-implement/SKILL.md +1 -1
- package/.claude/skills/event-modeling-implement/reference/implement.md +38 -11
- package/.claude/skills/event-modeling-review/SKILL.md +2 -2
- package/.claude/skills/event-modeling-shared/reference/em-dsl.md +279 -189
- package/.claude/skills/event-modeling-shared/reference/operating-principles.md +61 -0
- package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +116 -5
- package/.claude/skills/event-modeling-shared/templates/constitution.md +18 -1
- package/.claude/skills/event-modeling-shared/templates/slice.md +64 -39
- package/.claude/skills/event-modeling-shared/templates/state.md +5 -1
- package/.claude-plugin/marketplace.json +14 -0
- package/README.md +25 -11
- package/dist/catalog/apiFirst.d.ts +28 -0
- package/dist/catalog/apiFirst.js +49 -0
- package/dist/catalog/apiFirst.js.map +1 -0
- package/dist/catalog/docJoin.d.ts +13 -0
- package/dist/catalog/docJoin.js +11 -0
- package/dist/catalog/docJoin.js.map +1 -1
- package/dist/catalog/docModelConsistencyValidate.js +44 -4
- package/dist/catalog/docModelConsistencyValidate.js.map +1 -1
- package/dist/catalog/invariantsValidate.d.ts +4 -0
- package/dist/catalog/invariantsValidate.js +102 -0
- package/dist/catalog/invariantsValidate.js.map +1 -0
- package/dist/catalog/scenarios.d.ts +15 -0
- package/dist/catalog/scenarios.js +97 -0
- package/dist/catalog/scenarios.js.map +1 -0
- package/dist/catalog/sliceDoc.d.ts +8 -0
- package/dist/catalog/sliceDoc.js +9 -0
- package/dist/catalog/sliceDoc.js.map +1 -1
- package/dist/catalog/sliceReadyValidate.d.ts +31 -4
- package/dist/catalog/sliceReadyValidate.js +66 -8
- package/dist/catalog/sliceReadyValidate.js.map +1 -1
- package/dist/catalog/sliceSections.d.ts +55 -0
- package/dist/catalog/sliceSections.js +317 -0
- package/dist/catalog/sliceSections.js.map +1 -0
- package/dist/cli/agentsMd.js +7 -1
- package/dist/cli/agentsMd.js.map +1 -1
- package/dist/cli/api.d.ts +90 -0
- package/dist/cli/api.js +318 -0
- package/dist/cli/api.js.map +1 -0
- package/dist/cli/ciInit.d.ts +82 -21
- package/dist/cli/ciInit.js +468 -64
- package/dist/cli/ciInit.js.map +1 -1
- package/dist/cli/conformScope.d.ts +28 -0
- package/dist/cli/conformScope.js +67 -0
- package/dist/cli/conformScope.js.map +1 -1
- package/dist/cli/coverage.d.ts +9 -0
- package/dist/cli/coverage.js +60 -8
- package/dist/cli/coverage.js.map +1 -1
- package/dist/cli/defer.d.ts +55 -0
- package/dist/cli/defer.js +244 -0
- package/dist/cli/defer.js.map +1 -0
- package/dist/cli/engagement.d.ts +210 -0
- package/dist/cli/engagement.js +444 -0
- package/dist/cli/engagement.js.map +1 -0
- package/dist/cli/engagementFile.d.ts +86 -0
- package/dist/cli/engagementFile.js +255 -0
- package/dist/cli/engagementFile.js.map +1 -0
- package/dist/cli/metrics.d.ts +10 -0
- package/dist/cli/metrics.js +49 -1
- package/dist/cli/metrics.js.map +1 -1
- package/dist/cli/pluginPin.d.ts +55 -0
- package/dist/cli/pluginPin.js +188 -0
- package/dist/cli/pluginPin.js.map +1 -0
- package/dist/cli/ratify.d.ts +27 -2
- package/dist/cli/ratify.js +112 -13
- package/dist/cli/ratify.js.map +1 -1
- package/dist/cli/reratify.d.ts +4 -2
- package/dist/cli/reratify.js +41 -16
- package/dist/cli/reratify.js.map +1 -1
- package/dist/cli/scopeInputs.d.ts +48 -0
- package/dist/cli/scopeInputs.js +176 -0
- package/dist/cli/scopeInputs.js.map +1 -0
- package/dist/cli/skillCheck.d.ts +15 -1
- package/dist/cli/skillCheck.js +22 -1
- package/dist/cli/skillCheck.js.map +1 -1
- package/dist/cli/skillDirs.d.ts +5 -0
- package/dist/cli/skillDirs.js +13 -1
- package/dist/cli/skillDirs.js.map +1 -1
- package/dist/cli/skillSync.d.ts +4 -0
- package/dist/cli/skillSync.js +23 -0
- package/dist/cli/skillSync.js.map +1 -1
- package/dist/cli/sliceNew.d.ts +11 -7
- package/dist/cli/sliceNew.js +91 -18
- package/dist/cli/sliceNew.js.map +1 -1
- package/dist/cli/sliceSync.d.ts +50 -0
- package/dist/cli/sliceSync.js +170 -0
- package/dist/cli/sliceSync.js.map +1 -0
- package/dist/cli/status.d.ts +24 -1
- package/dist/cli/status.js +20 -1
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/systemInputs.d.ts +53 -10
- package/dist/cli/systemInputs.js +186 -11
- package/dist/cli/systemInputs.js.map +1 -1
- package/dist/cli/upgrade.d.ts +16 -3
- package/dist/cli/upgrade.js +366 -30
- package/dist/cli/upgrade.js.map +1 -1
- package/dist/cli/usageLog.d.ts +4 -2
- package/dist/cli/usageLog.js +4 -2
- package/dist/cli/usageLog.js.map +1 -1
- package/dist/cli.js +599 -94
- package/dist/cli.js.map +1 -1
- package/dist/emit/api.d.ts +29 -0
- package/dist/emit/api.js +220 -0
- package/dist/emit/api.js.map +1 -0
- package/dist/emit/apiCheckJson.d.ts +3 -0
- package/dist/emit/apiCheckJson.js +21 -0
- package/dist/emit/apiCheckJson.js.map +1 -0
- package/dist/emit/codeownersJson.d.ts +3 -0
- package/dist/emit/codeownersJson.js +19 -0
- package/dist/emit/codeownersJson.js.map +1 -0
- package/dist/emit/diffJson.d.ts +1 -1
- package/dist/emit/diffJson.js +8 -1
- package/dist/emit/diffJson.js.map +1 -1
- package/dist/emit/engagementJson.d.ts +8 -0
- package/dist/emit/engagementJson.js +46 -0
- package/dist/emit/engagementJson.js.map +1 -0
- package/dist/emit/glossaryJson.d.ts +1 -1
- package/dist/emit/glossaryJson.js +4 -1
- package/dist/emit/glossaryJson.js.map +1 -1
- package/dist/emit/json.d.ts +17 -1
- package/dist/emit/json.js +30 -1
- package/dist/emit/json.js.map +1 -1
- package/dist/emit/metricsJson.d.ts +1 -1
- package/dist/emit/metricsJson.js +4 -1
- package/dist/emit/metricsJson.js.map +1 -1
- package/dist/emit/queryJson.d.ts +1 -1
- package/dist/emit/queryJson.js +7 -1
- package/dist/emit/queryJson.js.map +1 -1
- package/dist/emit/scopeJson.d.ts +12 -0
- package/dist/emit/scopeJson.js +26 -0
- package/dist/emit/scopeJson.js.map +1 -0
- package/dist/emit/skillCheckJson.d.ts +3 -2
- package/dist/emit/skillCheckJson.js +10 -2
- package/dist/emit/skillCheckJson.js.map +1 -1
- package/dist/emit/statusJson.d.ts +1 -1
- package/dist/emit/statusJson.js +15 -1
- package/dist/emit/statusJson.js.map +1 -1
- package/dist/emit/systemJson.d.ts +15 -8
- package/dist/emit/systemJson.js +28 -13
- package/dist/emit/systemJson.js.map +1 -1
- package/dist/emit/validateJson.d.ts +3 -3
- package/dist/emit/validateJson.js +10 -4
- package/dist/emit/validateJson.js.map +1 -1
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +163 -31
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/diff.d.ts +4 -1
- package/dist/model/diff.js +44 -8
- package/dist/model/diff.js.map +1 -1
- package/dist/model/glossary.d.ts +2 -0
- package/dist/model/glossary.js +1 -0
- package/dist/model/glossary.js.map +1 -1
- package/dist/model/model.d.ts +55 -2
- package/dist/model/model.js +57 -0
- package/dist/model/model.js.map +1 -1
- package/dist/model/qualifiedRef.d.ts +18 -0
- package/dist/model/qualifiedRef.js +26 -0
- package/dist/model/qualifiedRef.js.map +1 -1
- package/dist/model/queryIndex.d.ts +9 -1
- package/dist/model/queryIndex.js +18 -2
- package/dist/model/queryIndex.js.map +1 -1
- package/dist/model/rules.d.ts +143 -2
- package/dist/model/rules.js +162 -3
- package/dist/model/rules.js.map +1 -1
- package/dist/model/validate.d.ts +40 -0
- package/dist/model/validate.js +147 -1
- package/dist/model/validate.js.map +1 -1
- package/dist/parser/ast.d.ts +31 -3
- package/dist/parser/parser.js +148 -14
- package/dist/parser/parser.js.map +1 -1
- package/dist/query/format.js +1 -1
- package/dist/query/format.js.map +1 -1
- package/dist/query/verbs.d.ts +6 -0
- package/dist/query/verbs.js +6 -2
- package/dist/query/verbs.js.map +1 -1
- package/dist/system/adaptation.d.ts +14 -0
- package/dist/system/adaptation.js +49 -0
- package/dist/system/adaptation.js.map +1 -0
- package/dist/system/codeowners.d.ts +77 -0
- package/dist/system/codeowners.js +242 -0
- package/dist/system/codeowners.js.map +1 -0
- package/dist/system/manifest.d.ts +10 -5
- package/dist/system/manifest.js +54 -26
- package/dist/system/manifest.js.map +1 -1
- package/dist/system/migrateManifest.d.ts +28 -0
- package/dist/system/migrateManifest.js +155 -0
- package/dist/system/migrateManifest.js.map +1 -0
- package/dist/system/scope.d.ts +46 -0
- package/dist/system/scope.js +132 -0
- package/dist/system/scope.js.map +1 -0
- package/dist/system/verify.d.ts +50 -13
- package/dist/system/verify.js +179 -58
- package/dist/system/verify.js.map +1 -1
- package/dist/templates.d.ts +2 -2
- package/dist/templates.js +23 -2
- package/dist/templates.js.map +1 -1
- package/package.json +5 -2
- package/plugin/.claude-plugin/plugin.json +18 -0
- package/plugin/agents/em-critic.md +27 -0
- package/plugin/agents/em-implementer.md +35 -0
- package/plugin/agents/em-reviewer.md +32 -0
- package/plugin/agents/em-validator.md +28 -0
- package/plugin/shared/reference/em-dsl.md +871 -0
- package/plugin/shared/reference/methodology.md +329 -0
- package/plugin/shared/reference/operating-principles.md +222 -0
- package/plugin/shared/reference/slice-doc-schema.md +574 -0
- package/plugin/shared/templates/conformance-report.md +85 -0
- package/plugin/shared/templates/constitution.md +136 -0
- package/plugin/shared/templates/model-readme.md +46 -0
- package/plugin/shared/templates/slice.md +251 -0
- package/plugin/shared/templates/state.md +77 -0
- package/plugin/skills/conform/SKILL.md +93 -0
- package/plugin/skills/conform/reference/conform.md +428 -0
- package/plugin/skills/design/SKILL.md +298 -0
- package/plugin/skills/discover/SKILL.md +90 -0
- package/plugin/skills/discover/reference/extract.md +147 -0
- package/plugin/skills/engagement/SKILL.md +193 -0
- package/plugin/skills/engagement/reference/engagement.md +144 -0
- package/plugin/skills/event-modeling/SKILL.md +132 -0
- package/plugin/skills/implement/SKILL.md +61 -0
- package/plugin/skills/implement/reference/implement.md +439 -0
- package/plugin/skills/review/SKILL.md +74 -0
- package/dist/emit/typespec.d.ts +0 -26
- package/dist/emit/typespec.js +0 -356
- 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.
|
|
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
|
|
94
|
-
contract, not an implementation detail. `em validate --list-public` lists them;
|
|
95
|
-
|
|
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
|
|
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
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
review
|
|
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.
|
|
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**
|