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