@milehimikey/em 1.19.6 → 1.20.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/skills/event-modeling/SKILL.md +1 -1
- package/.claude/skills/event-modeling-conform/SKILL.md +1 -1
- package/.claude/skills/event-modeling-conform/reference/conform.md +32 -4
- package/.claude/skills/event-modeling-design/SKILL.md +14 -3
- package/.claude/skills/event-modeling-discover/SKILL.md +1 -1
- package/.claude/skills/event-modeling-discover/reference/extract.md +8 -0
- package/.claude/skills/event-modeling-engagement/SKILL.md +1 -1
- package/.claude/skills/event-modeling-implement/SKILL.md +7 -2
- package/.claude/skills/event-modeling-implement/reference/implement.md +73 -6
- package/.claude/skills/event-modeling-review/SKILL.md +1 -1
- package/.claude/skills/event-modeling-shared/reference/em-dsl.md +24 -4
- package/.claude/skills/event-modeling-shared/reference/methodology.md +16 -0
- package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +1 -1
- package/.claude/skills/event-modeling-shared/templates/slice.md +6 -1
- package/.claude-plugin/marketplace.json +2 -2
- package/README.md +11 -1
- package/dist/catalog/docBadge.d.ts +16 -0
- package/dist/catalog/docBadge.js +50 -0
- package/dist/catalog/docBadge.js.map +1 -0
- package/dist/catalog/docModelConsistencyValidate.js +9 -2
- package/dist/catalog/docModelConsistencyValidate.js.map +1 -1
- package/dist/catalog/invTokens.d.ts +49 -0
- package/dist/catalog/invTokens.js +94 -0
- package/dist/catalog/invTokens.js.map +1 -0
- package/dist/catalog/pages.js +48 -1
- package/dist/catalog/pages.js.map +1 -1
- package/dist/catalog/scenarios.d.ts +4 -0
- package/dist/catalog/scenarios.js +4 -1
- package/dist/catalog/scenarios.js.map +1 -1
- package/dist/catalog/sliceDoc.d.ts +46 -1
- package/dist/catalog/sliceDoc.js +90 -2
- package/dist/catalog/sliceDoc.js.map +1 -1
- package/dist/catalog/sliceDocRender.d.ts +3 -0
- package/dist/catalog/sliceDocRender.js +295 -0
- package/dist/catalog/sliceDocRender.js.map +1 -0
- package/dist/cli/conformSupersede.js +13 -3
- package/dist/cli/conformSupersede.js.map +1 -1
- package/dist/cli/coverage.d.ts +13 -23
- package/dist/cli/coverage.js +51 -91
- package/dist/cli/coverage.js.map +1 -1
- package/dist/cli/markImplemented.js +21 -3
- package/dist/cli/markImplemented.js.map +1 -1
- package/dist/cli/refsCheck.d.ts +52 -0
- package/dist/cli/refsCheck.js +127 -1
- package/dist/cli/refsCheck.js.map +1 -1
- package/dist/cli/sliceConform.d.ts +100 -1
- package/dist/cli/sliceConform.js +182 -9
- package/dist/cli/sliceConform.js.map +1 -1
- package/dist/cli/status.js +4 -3
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/watchStoryline.d.ts +27 -0
- package/dist/cli/watchStoryline.js +55 -0
- package/dist/cli/watchStoryline.js.map +1 -0
- package/dist/cli.js +184 -24
- package/dist/cli.js.map +1 -1
- package/dist/emit/docJson.d.ts +99 -0
- package/dist/emit/docJson.js +197 -0
- package/dist/emit/docJson.js.map +1 -0
- package/dist/emit/refsJson.d.ts +5 -3
- package/dist/emit/refsJson.js +5 -2
- package/dist/emit/refsJson.js.map +1 -1
- package/dist/mcp/server.js +23 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/continuation.d.ts +9 -0
- package/dist/model/continuation.js +30 -0
- package/dist/model/continuation.js.map +1 -1
- 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/shapeLint.js +48 -0
- package/dist/model/shapeLint.js.map +1 -1
- package/dist/model/validate.js +119 -0
- package/dist/model/validate.js.map +1 -1
- package/dist/parser/ast.d.ts +8 -0
- package/dist/parser/parser.js +51 -1
- package/dist/parser/parser.js.map +1 -1
- package/dist/render/render.js +1 -1
- package/dist/render/render.js.map +1 -1
- package/dist/render/sliceOverlay.d.ts +7 -2
- package/dist/render/sliceOverlay.js +28 -3
- package/dist/render/sliceOverlay.js.map +1 -1
- package/dist/render/storylinePicker.d.ts +9 -0
- package/dist/render/storylinePicker.js +17 -0
- package/dist/render/storylinePicker.js.map +1 -0
- package/dist/render/viewerHtml.js +1 -1
- package/dist/render/viewerHtml.js.map +1 -1
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +2 -2
- package/plugin/shared/reference/em-dsl.md +24 -4
- package/plugin/shared/reference/methodology.md +16 -0
- package/plugin/shared/reference/slice-doc-schema.md +1 -1
- package/plugin/shared/templates/slice.md +6 -1
- package/plugin/skills/conform/SKILL.md +1 -1
- package/plugin/skills/conform/reference/conform.md +32 -4
- package/plugin/skills/design/SKILL.md +14 -3
- package/plugin/skills/discover/SKILL.md +1 -1
- package/plugin/skills/discover/reference/extract.md +8 -0
- package/plugin/skills/engagement/SKILL.md +1 -1
- package/plugin/skills/event-modeling/SKILL.md +1 -1
- package/plugin/skills/implement/SKILL.md +7 -2
- package/plugin/skills/implement/reference/implement.md +73 -6
- package/plugin/skills/review/SKILL.md +1 -1
|
@@ -40,7 +40,9 @@ difference is what you do with what you find: extract *builds* a model from the
|
|
|
40
40
|
(or the status the user says corresponds to shipped code) for whichever slices are in scope.
|
|
41
41
|
Checking a `draft` or `ready-to-implement` slice against code is a wasted walk — ratified or
|
|
42
42
|
not, nobody has built to it yet; tell the user and skip it rather than reporting "drift"
|
|
43
|
-
against it.
|
|
43
|
+
against it. (GH #400: the ONE exception is a deliberate pre-ship advisory run — see
|
|
44
|
+
`--preview` under step 5 below — not a reason to treat this precondition as optional for an
|
|
45
|
+
ordinary post-ship sweep.)
|
|
44
46
|
3. The codebase to check: the state file's **Existing system refs** (populated during
|
|
45
47
|
`extract`, if this model came from one) or ask the user for the repo path if not set. Record
|
|
46
48
|
it if missing. In a headless/scheduled run with no user to ask, default to the repository
|
|
@@ -336,6 +338,32 @@ been through this) instead of just trusting `implementedIn`. Legal only for `sta
|
|
|
336
338
|
with a link, and itself refuses if an unruled finding for that slice still exists at this
|
|
337
339
|
revision — the mechanical proof this step comes only after rulings, not before.
|
|
338
340
|
|
|
341
|
+
**Pre-ship advisory mode: `--preview` (GH #400).** The certify step above is legal only for a
|
|
342
|
+
**shipped** slice (`status: implemented`/`shippedVersion:` + `implementedIn:`) — precondition 2
|
|
343
|
+
reflects that this phase ordinarily walks shipped code. `--preview` is the deliberate exception:
|
|
344
|
+
the SAME doc-resolution and findings-check read, legal for a slice that hasn't shipped yet
|
|
345
|
+
(the shipped/`implementedIn:` preconditions are waived), and it **never writes anything** —
|
|
346
|
+
no `conformedVersion`/`conformedAt`/`conformedOn`, ever, regardless of outcome:
|
|
347
|
+
|
|
348
|
+
```
|
|
349
|
+
em slice conform <model-name>.em <slice-key> --at <target-repo revision> --preview
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
Use this to run a conform sweep against your OWN implementing branch before it merges — catching
|
|
353
|
+
spec/code drift while you can still fix it on the same branch, rather than after shipping. The
|
|
354
|
+
walk itself (steps 1-4 above) is unchanged; only the certify step's preconditions differ. Output
|
|
355
|
+
is ephemeral by default (nothing is written, not even to `conformance/`); pass
|
|
356
|
+
`--write-findings` to persist the run's own unruled findings as a normal
|
|
357
|
+
`conformance/<date>-<slice-key>-preview-findings.json` (this is deliberate — `docs/cli.md`'s
|
|
358
|
+
`em slice conform --preview` section documents the exact shape and naming). Know before opting
|
|
359
|
+
in: the written file has no sibling report (`report` is synthetic), so `em conform-supersede`
|
|
360
|
+
refuses to rule on it — unruled entries in it gate certify/`set-conformance` at that revision
|
|
361
|
+
until you rule them in the file by hand, delete the snapshot, or author the sibling report.
|
|
362
|
+
`em state set-conformance` and the unruled-findings gates are unaffected by
|
|
363
|
+
this mode either way: a default preview run writes nothing for them to read, so it can never
|
|
364
|
+
block a later certify or `set-conformance` call. There is no `--slice-ready` integration for this
|
|
365
|
+
mode yet.
|
|
366
|
+
|
|
339
367
|
End of run: update the state file's `Last conformance:` marker with
|
|
340
368
|
|
|
341
369
|
```
|
|
@@ -343,7 +371,7 @@ em state set-conformance <target-repo revision> --report conformance/YYYY-MM-DD-
|
|
|
343
371
|
```
|
|
344
372
|
|
|
345
373
|
— the revision is the one you just diffed against, so the next run's scope starts from here.
|
|
346
|
-
The command writes the exact format step 1 parses back out; never hand-edit the bullet.
|
|
374
|
+
The command writes the exact format step 1 parses back out; never hand-edit the bullet. Gates read every same-revision findings file (the report's own `-findings.json` first, else every file whose `revision` matches). The same-revision lookup uses the report's OWN revision (its `Target repo: … @ <rev>` header line; the caller's `<rev>` / `--as-of` only when the report has none).
|
|
347
375
|
**Refuses (MIL-214) while any `implemented` slice still has an unruled finding** in the findings
|
|
348
376
|
JSON beside the report — rule on every finding first (or certify what's already ruled via `em
|
|
349
377
|
slice conform` above), or pass `--partial` to record the marker with a loud notice instead
|
|
@@ -364,7 +392,7 @@ a ruling you're only banner-stamping after the fact), run the same command witho
|
|
|
364
392
|
em conform-supersede <model-name>.em conformance/YYYY-MM-DD-report.md --as-of <target-repo revision> --findings <spec>
|
|
365
393
|
```
|
|
366
394
|
|
|
367
|
-
— stamping the report with a "superseded as of `<rev>`" banner so a later reader who finds it
|
|
395
|
+
— a ruling is written to the file the report names (`<x>-report.md` <-> `<x>-findings.json`; with only per-slice files at that revision, pass the per-slice report or it refuses; `--as-of` is NOT the lookup key — the report's own `Target repo: … @ <rev>` header revision is, and `--as-of` only when the report has none) — stamping the report with a "superseded as of `<rev>`" banner so a later reader who finds it
|
|
368
396
|
(a search hit, a bookmark, a link from an old PR description) sees immediately that its
|
|
369
397
|
file:line citations describe an ancestor of the current model, not its current state. This is
|
|
370
398
|
what keeps a superseded report an honest piece of history rather than a silently-misleading
|
|
@@ -380,7 +408,7 @@ each call adds its own stamp rather than overwriting the last.
|
|
|
380
408
|
the gitignoring (`*-asis.em`, idempotent) mechanically, never built up from nothing and never
|
|
381
409
|
hand-maintained. It's regenerated every conform run.
|
|
382
410
|
- **Report location:** `conformance/<YYYY-MM-DD>-report.md` in the model directory. One file
|
|
383
|
-
per run; don't overwrite a prior date's report.
|
|
411
|
+
per run; don't overwrite a prior date's report. Its findings go in the same-stem `-findings.json`; gates read every same-revision findings file, so per-slice runs may write `<date>-<name>-findings.json`, and a ruling is written to the file the report names. The same-revision lookup uses the report's OWN revision (its `Target repo: … @ <rev>` header line; the caller's `<rev>` / `--as-of` only when the report has none).
|
|
384
412
|
- **Red note wording:** `issue "conformance: <what's wrong, plainly>"` — plain enough that
|
|
385
413
|
whoever ratifies it later understands the claim without re-reading the report.
|
|
386
414
|
- **Naming/matching rules:** same past-tense-event / imperative-command / thing-shown-view
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: design
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.20.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
|
|
@@ -89,10 +89,14 @@ Goal: a structurally complete, **validated** model with correct patterns and swi
|
|
|
89
89
|
shape — reshape it with the "Reshaping an existing model" checklist. Then the **intent test**
|
|
90
90
|
per command (would a business person say this name at this step in the story? an endpoint-shaped
|
|
91
91
|
name fails), the **question test** per view (write the question it answers; no question, no
|
|
92
|
-
read model; a child view only when its query needs what the parent view lacks),
|
|
92
|
+
read model; a child view only when its query needs what the parent view lacks), the
|
|
93
|
+
**views-as-lookups check** per `from "E"` on a view (does E add, change or remove a row here? if
|
|
94
|
+
it only fills a column, put the column on the event that creates the row and drop E — see
|
|
95
|
+
`${CLAUDE_PLUGIN_ROOT}/shared/reference/methodology.md`, "Views as lookups"), and the
|
|
93
96
|
**conditional-invariant signal** (invariants or fields that apply only "if `<field>` is set"
|
|
94
97
|
mean two intents in one command: split it). The `timeline-entity-clustered`,
|
|
95
|
-
`command-second-intent
|
|
98
|
+
`command-second-intent`, `automation-split-by-outcome` and `view-lookup-source` lints are the
|
|
99
|
+
mechanical half (the last one only catches the cross-context cases — do the check by eye too); the
|
|
96
100
|
1.18.0 design exit gate is `em validate --shape`. Shape the model first, scaffold docs after: a rename,
|
|
97
101
|
split or merge from the reshape would orphan docs already wired with `--wire`. The `slice` phase is unchanged (timeline order).
|
|
98
102
|
3. **Elaborate scenarios — first pass (step 6).** Scaffold every slice's doc now, one per
|
|
@@ -131,6 +135,13 @@ Goal: a structurally complete, **validated** model with correct patterns and swi
|
|
|
131
135
|
that reads it; another model/system reads it → mark it `public`; only an automation reads
|
|
132
136
|
it → nothing, it's internal by design. No new keyword — reachability is already what `ui` and
|
|
133
137
|
`public` mean.
|
|
138
|
+
**Per `view`, also ask whether each of its sources earns its place (GH #398):** for every
|
|
139
|
+
`from "E"` on the view, does E add, change or remove a row here — or only fill a column on a
|
|
140
|
+
row some other event already created? The latter is the views-as-lookups smell (methodology
|
|
141
|
+
reference, "Views as lookups"): drop E as a source and have the event that creates the row
|
|
142
|
+
carry the field instead. `view-lookup-source` flags the cross-context instances of this
|
|
143
|
+
mechanically; a lookup from the view's own context (no `@Context` mismatch to key on) only
|
|
144
|
+
this by-eye check catches.
|
|
134
145
|
**Per translation fed from another model, declare what it consumes (MIL-235):** write
|
|
135
146
|
`translation Order Intake consumes checkout:event.order-submitted`. The ref is
|
|
136
147
|
`<modelKey>:<kind>.<slug>`, where kind is `event` or `view` and the target is marked `public`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: discover
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.20.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
|
|
@@ -97,6 +97,14 @@ it is fine to finish a round with `# TBD`s still parked.
|
|
|
97
97
|
read model* warnings: real systems do record fire-and-forget events. In an as-is model that is
|
|
98
98
|
a **finding about the system**, not a modelling mistake — never invent a reader to silence it
|
|
99
99
|
(that would be desired state). Park it in the Decisions log and carry the warning.
|
|
100
|
+
**Expect lookup-style sources too.** A lifted model will faithfully reproduce the projection's
|
|
101
|
+
lookup joins — a view wired to `from "Order Created"` only because the current query joins the
|
|
102
|
+
orders table to get `customerName`, not because this view owns any row that event changes. Wire
|
|
103
|
+
it as-is (current-state-only stance: that join is how the system behaves today); don't fix it
|
|
104
|
+
here, that would be inventing desired state. Note it as a finding in the Decisions log the same
|
|
105
|
+
way as an unread event, and leave it for `model`/`slice` to apply the views-as-lookups rule
|
|
106
|
+
(`../../../shared/reference/methodology.md`, "Views as lookups") once the as-is
|
|
107
|
+
model is agreed.
|
|
100
108
|
- **R5 — Boundaries & reactions.** Current automations and integrations as-is: schedulers,
|
|
101
109
|
listeners, outbound syncs, inbound webhooks. Model each as a reaction sharing its slice with
|
|
102
110
|
the `command` + `event` it triggers (`reaction → command → event`, per `em-dsl.md`) — the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: event-modeling
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.20.0
|
|
4
4
|
description: >-
|
|
5
5
|
Use when the user runs `/em:event-modeling` (with or without a phase name), or wants to resume an
|
|
6
6
|
event-modeling session without specifying which part of the process applies. Reads the model's
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: implement
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.20.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
|
|
@@ -53,7 +53,12 @@ routing table (§7) is what names the skill set for each pattern.
|
|
|
53
53
|
Preconditions (tool check, model location) are the same as every other phase — see
|
|
54
54
|
`${CLAUDE_PLUGIN_ROOT}/shared/reference/operating-principles.md` — but this phase additionally
|
|
55
55
|
requires the target slice to already be ratified; if it isn't, stop and say so rather than
|
|
56
|
-
starting on unratified work.
|
|
56
|
+
starting on unratified work. The one documented exception is **inline ratification** (GH #399,
|
|
57
|
+
`reference/implement.md` §1a): for an internal (non-public-touching, non-engagement) slice whose
|
|
58
|
+
doc is already `reviewed`, drafting code on the same branch ahead of the human's `em slice
|
|
59
|
+
ratify` is sanctioned — provided you never flip the gate yourself and re-confirm
|
|
60
|
+
`--slice-ready` reads `true` before treating the slice as done. `em:engagement` is
|
|
61
|
+
unchanged by this: it still requires every dispatched slice ratified before its branch is cut.
|
|
57
62
|
|
|
58
63
|
End of phase: PR merged, slice doc flipped to `status: implemented` with `implementedIn`
|
|
59
64
|
filled, `em slice index <model-name>.em` run to refresh `README.md`'s Slices table. Implement
|
|
@@ -47,15 +47,82 @@ A warning whose code is in this list blocks; any other warning never does — `c
|
|
|
47
47
|
|
|
48
48
|
Because of that list, `ready` can be `false` with every `gates` entry `true` (a `both-ends-of-a-flow/*` warning on one of the slice's own elements, say). Don't work it out from `gates`: read **`blockedBy`** (schema `1.5`, GH #377), the codes that flipped `ready`, `[]` exactly when it is `true`, and report those codes with the `false` gates when you hand the slice back.
|
|
49
49
|
|
|
50
|
-
**`ready: false` means stop** — with
|
|
51
|
-
with `driftSignal: in-sync` or `uncertified` (MIL-214) also reads `ready: false`
|
|
52
|
-
`statusReady` gate fails because nothing is newly ratified), and that specific case is
|
|
53
|
-
re-implementation/repair, not a blocker — see §3's third mode before treating it as one.
|
|
50
|
+
**`ready: false` means stop** — with two named exceptions. First: a slice already `status:
|
|
51
|
+
implemented` with `driftSignal: in-sync` or `uncertified` (MIL-214) also reads `ready: false`
|
|
52
|
+
(its `statusReady` gate fails because nothing is newly ratified), and that specific case is
|
|
53
|
+
re-implementation/repair, not a blocker — see §3's third mode before treating it as one. Second:
|
|
54
|
+
under **inline ratification** (§1a) a slice doc that's only `status: reviewed` — not yet
|
|
55
|
+
`ready-to-implement` — is a sanctioned starting point for drafting code on the SAME branch, with
|
|
56
|
+
the explicit, non-negotiable condition that you treat nothing as actually ratified, and open
|
|
57
|
+
nothing for merge, until a human has run `em slice ratify` and `--slice-ready` reads `true` for
|
|
58
|
+
real; §1a names exactly which slices qualify and what that condition requires in practice. For
|
|
54
59
|
every other `false`, report which `gates`
|
|
55
60
|
entries are `false` and what `blockedBy` names (and any `diagnostics` entries concerning this
|
|
56
61
|
slice) and hand the slice back to the humans. Never make the gate pass yourself — checking an open-question box, flipping
|
|
57
|
-
`status`, or editing frontmatter are ratification decisions,
|
|
58
|
-
|
|
62
|
+
`status`, or editing frontmatter are ratification decisions, made by a human in a ratification
|
|
63
|
+
session, never by you running `em slice ratify` on their behalf. That session is usually a
|
|
64
|
+
separate doc-only PR, merged before an implementation branch is even cut — but it doesn't have
|
|
65
|
+
to be: **inline ratification** (GH #399, §1a below) lets the session be the PR review of the
|
|
66
|
+
very branch you're implementing on, for internal slices. Either shape, the rule here is the
|
|
67
|
+
same: you never flip the gate yourself, whatever branch you're on.
|
|
68
|
+
|
|
69
|
+
### 1a. The inline variant: ratifying on the implementation branch
|
|
70
|
+
|
|
71
|
+
Most of this document assumes the ordinary shape — a slice is already `ready-to-implement` when
|
|
72
|
+
you start, ratified in its own prior PR, and §1's gate reads `true` before you write a line of
|
|
73
|
+
code. **Inline ratification** is the documented alternative
|
|
74
|
+
(`docs/process.md`'s
|
|
75
|
+
["Inline ratification" section](https://github.com/milehimikey/em/blob/main/docs/process.md#inline-ratification-approval-as-the-ratification-session)):
|
|
76
|
+
draft the slice doc *and* build it on the same branch, spec commits first, and let the human's
|
|
77
|
+
review of that one PR be the ratification session — which means you are, deliberately and
|
|
78
|
+
sanctioned, building for most of that branch's life against a doc that reads `ready: false`.
|
|
79
|
+
What doesn't change: you still never flip `status` yourself, never run `em slice ratify` on the
|
|
80
|
+
human's behalf, and never write a word of the ratification record — see §1's second named
|
|
81
|
+
exception for the precise condition this depends on. What's different is sequencing and tiering:
|
|
82
|
+
|
|
83
|
+
- **Draft the doc first, then build on the same branch.** Commit the slice doc (through the
|
|
84
|
+
normal `slice` phase), get it reviewed (`em slice review --by`, flipping it to `status:
|
|
85
|
+
reviewed` — a human has to do this part too, same as always) before any implementation code,
|
|
86
|
+
even though doc and code will both live on one branch and merge in one PR. Writing code before
|
|
87
|
+
the doc exists, or before a human has looked at it, is retrofit — the exact failure mode inline
|
|
88
|
+
mode is named after avoiding — whether or not anyone ever checks for it.
|
|
89
|
+
- **You may keep building past a `reviewed`-but-not-yet-`ready-to-implement` doc, but nothing is
|
|
90
|
+
ratified until `em slice ratify` actually runs.** `--slice-ready` keeps reading `false` the
|
|
91
|
+
whole time you're building — that's expected, not a signal to stop, as long as the doc's
|
|
92
|
+
`status` is `reviewed` (not `draft`: an un-reviewed doc is never a valid base, inline or not).
|
|
93
|
+
On an inline branch the human typically runs `em slice ratify --no-ref` as part of approving
|
|
94
|
+
the PR (`--no-ref` because the branch is headed for a squash/rebase merge) — not something you
|
|
95
|
+
do for them, and not something you should expect to have happened before the PR is up for
|
|
96
|
+
review. Before you report the slice done, or treat §6's merge-time flip as legitimate,
|
|
97
|
+
re-check `--slice-ready` yourself and confirm it now reads `true` with `ratifiedBy:` set — if
|
|
98
|
+
it still doesn't, the slice isn't ratified yet and you say so instead of proceeding.
|
|
99
|
+
- **A post-signature doc edit still trips the hash check.** `ratifiedHash` doesn't know or care
|
|
100
|
+
which branch it was computed on — if something changes the doc's body after the human has
|
|
101
|
+
signed it (a gap surfaces, §4), `--slice-ready` and `em slice ratify` both refuse the stale
|
|
102
|
+
signature exactly as they would across two PRs. Route it through `em slice revise --withdraw`,
|
|
103
|
+
review, re-ratify (§4) — inline doesn't shortcut that loop, it just means the re-sign happens
|
|
104
|
+
on the branch you're already on instead of a fresh one.
|
|
105
|
+
- **Not every slice is a candidate.** A slice owning a `public` command, event or view
|
|
106
|
+
(`isPublicTouchingSlice`) keeps the separate doc PR — the contract is a promise to consumers
|
|
107
|
+
who never see your implementation diff, and `em slice ratify` already refuses a public-touching
|
|
108
|
+
slice without `--meaning-unchanged`/`--contract-change` regardless of which branch it runs on.
|
|
109
|
+
An engagement-dispatched slice is never inline either — engagements structurally need every
|
|
110
|
+
contract frozen before any implementer branch is cut, so the engagement skill never offers you
|
|
111
|
+
this shape (it is explicitly unchanged by GH #399 — this is a note for your own judgment
|
|
112
|
+
outside an engagement, not something to apply inside one).
|
|
113
|
+
- **Pre-ship advisory conform is the loop's natural checkpoint.** Before the PR merges, a human
|
|
114
|
+
(or you, if asked) can run `em slice conform <model>.em <key> --at <rev> --preview` — the
|
|
115
|
+
pre-ship, non-certifying mode (GH #400): same doc-resolution and findings-check read as a real
|
|
116
|
+
certification, legal before the slice has shipped, never writes `conformedVersion:`/
|
|
117
|
+
`conformedAt:`/`conformedOn:`. It's advisory and ephemeral by default (nothing written unless
|
|
118
|
+
`--write-findings` is passed) — a cheap "did I just drift from the doc I signed" look before
|
|
119
|
+
asking for the PR review that will also be the ratification.
|
|
120
|
+
- **The ordering advisory is informational, not yours to act on.** `em refs --check-order`
|
|
121
|
+
(GH #399) can report whether a commit on this branch touched code before the doc's
|
|
122
|
+
`ratifiedRef` — a retrofit smoke signal for the human reviewing the PR. It's advisory, never a
|
|
123
|
+
gate, and nothing in this skill asks you to run it or react to its output; if a human shows you
|
|
124
|
+
a `code-before-ratification` result, treat it the same as any other gap raised against your
|
|
125
|
+
work (§4), not as something to silence.
|
|
59
126
|
|
|
60
127
|
## 2. Read the spec
|
|
61
128
|
|