@milehimikey/em 1.17.0 → 1.18.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-implementer.md +7 -4
- package/.claude/agents/em-validator.md +2 -2
- package/.claude/skills/event-modeling/SKILL.md +1 -1
- package/.claude/skills/event-modeling-conform/SKILL.md +1 -1
- package/.claude/skills/event-modeling-design/SKILL.md +46 -5
- package/.claude/skills/event-modeling-discover/SKILL.md +43 -8
- package/.claude/skills/event-modeling-discover/reference/extract.md +6 -1
- package/.claude/skills/event-modeling-discover/reference/prd-rubric.md +102 -0
- package/.claude/skills/event-modeling-discover/reference/prd-spec-path.md +171 -0
- package/.claude/skills/event-modeling-engagement/SKILL.md +21 -9
- package/.claude/skills/event-modeling-implement/SKILL.md +1 -1
- package/.claude/skills/event-modeling-implement/reference/implement.md +18 -0
- package/.claude/skills/event-modeling-review/SKILL.md +4 -2
- package/.claude/skills/event-modeling-shared/reference/em-dsl.md +94 -6
- package/.claude/skills/event-modeling-shared/reference/methodology.md +268 -0
- package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +96 -2
- package/.claude/skills/event-modeling-shared/templates/slice.md +11 -3
- package/.claude-plugin/marketplace.json +2 -2
- package/dist/catalog/docModelConsistencyValidate.js +160 -0
- package/dist/catalog/docModelConsistencyValidate.js.map +1 -1
- package/dist/catalog/invariantsValidate.d.ts +2 -0
- package/dist/catalog/invariantsValidate.js +67 -1
- package/dist/catalog/invariantsValidate.js.map +1 -1
- package/dist/catalog/scenarioQualityValidate.d.ts +4 -0
- package/dist/catalog/scenarioQualityValidate.js +148 -0
- package/dist/catalog/scenarioQualityValidate.js.map +1 -0
- package/dist/catalog/scenarios.d.ts +5 -0
- package/dist/catalog/scenarios.js +80 -0
- package/dist/catalog/scenarios.js.map +1 -1
- package/dist/catalog/sliceDoc.d.ts +4 -0
- package/dist/catalog/sliceDoc.js +16 -7
- package/dist/catalog/sliceDoc.js.map +1 -1
- package/dist/catalog/sliceReadyValidate.d.ts +11 -2
- package/dist/catalog/sliceReadyValidate.js +62 -3
- package/dist/catalog/sliceReadyValidate.js.map +1 -1
- package/dist/catalog/sliceSections.d.ts +3 -2
- package/dist/catalog/sliceSections.js +99 -9
- package/dist/catalog/sliceSections.js.map +1 -1
- package/dist/cli/ciInit.d.ts +4 -11
- package/dist/cli/ciInit.js +24 -6
- package/dist/cli/ciInit.js.map +1 -1
- package/dist/cli/coverage.d.ts +9 -0
- package/dist/cli/coverage.js +18 -0
- package/dist/cli/coverage.js.map +1 -1
- package/dist/cli/defer.d.ts +28 -0
- package/dist/cli/defer.js +87 -4
- package/dist/cli/defer.js.map +1 -1
- package/dist/cli/engagement.d.ts +13 -2
- package/dist/cli/engagement.js +60 -5
- package/dist/cli/engagement.js.map +1 -1
- package/dist/cli/engagementFile.d.ts +2 -0
- package/dist/cli/engagementFile.js +3 -1
- package/dist/cli/engagementFile.js.map +1 -1
- package/dist/cli/markImplemented.d.ts +14 -10
- package/dist/cli/markImplemented.js +49 -1
- package/dist/cli/markImplemented.js.map +1 -1
- package/dist/cli/prdTriage.d.ts +109 -0
- package/dist/cli/prdTriage.js +393 -0
- package/dist/cli/prdTriage.js.map +1 -0
- package/dist/cli/render-inputs.d.ts +2 -0
- package/dist/cli/render-inputs.js +4 -0
- package/dist/cli/render-inputs.js.map +1 -1
- package/dist/cli/review.d.ts +17 -2
- package/dist/cli/review.js +39 -10
- package/dist/cli/review.js.map +1 -1
- package/dist/cli/revise.d.ts +2 -0
- package/dist/cli/revise.js +7 -2
- package/dist/cli/revise.js.map +1 -1
- package/dist/cli/shape.d.ts +27 -0
- package/dist/cli/shape.js +77 -0
- package/dist/cli/shape.js.map +1 -0
- package/dist/cli/sliceIndex.d.ts +6 -1
- package/dist/cli/sliceIndex.js +28 -13
- package/dist/cli/sliceIndex.js.map +1 -1
- package/dist/cli/sliceNew.d.ts +4 -1
- package/dist/cli/sliceNew.js +26 -9
- package/dist/cli/sliceNew.js.map +1 -1
- package/dist/cli/status.d.ts +21 -1
- package/dist/cli/status.js +25 -3
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/storylineSuggest.d.ts +26 -0
- package/dist/cli/storylineSuggest.js +252 -0
- package/dist/cli/storylineSuggest.js.map +1 -0
- package/dist/cli/upgrade.d.ts +15 -3
- package/dist/cli/upgrade.js +516 -7
- package/dist/cli/upgrade.js.map +1 -1
- package/dist/cli/upgradeReshape.d.ts +60 -0
- package/dist/cli/upgradeReshape.js +425 -0
- package/dist/cli/upgradeReshape.js.map +1 -0
- package/dist/cli.js +311 -35
- package/dist/cli.js.map +1 -1
- package/dist/emit/dot.d.ts +2 -0
- package/dist/emit/dot.js +44 -8
- package/dist/emit/dot.js.map +1 -1
- package/dist/emit/engagementJson.d.ts +4 -3
- package/dist/emit/engagementJson.js +11 -4
- package/dist/emit/engagementJson.js.map +1 -1
- package/dist/emit/json.d.ts +21 -1
- package/dist/emit/json.js +26 -2
- package/dist/emit/json.js.map +1 -1
- package/dist/emit/queryJson.d.ts +1 -1
- package/dist/emit/queryJson.js +3 -1
- package/dist/emit/queryJson.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/emit/theme.d.ts +1 -0
- package/dist/emit/theme.js +13 -0
- package/dist/emit/theme.js.map +1 -1
- package/dist/emit/validateJson.d.ts +9 -5
- package/dist/emit/validateJson.js +40 -5
- package/dist/emit/validateJson.js.map +1 -1
- package/dist/layout/grid.d.ts +5 -1
- package/dist/layout/grid.js +93 -2
- package/dist/layout/grid.js.map +1 -1
- package/dist/mcp/server.js +46 -11
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/edges.d.ts +7 -0
- package/dist/model/edges.js +33 -16
- package/dist/model/edges.js.map +1 -1
- package/dist/model/model.d.ts +33 -0
- package/dist/model/model.js +87 -3
- package/dist/model/model.js.map +1 -1
- package/dist/model/queryIndex.js +2 -2
- package/dist/model/queryIndex.js.map +1 -1
- package/dist/model/refs.js +8 -5
- package/dist/model/refs.js.map +1 -1
- package/dist/model/rules.d.ts +149 -0
- package/dist/model/rules.js +144 -0
- package/dist/model/rules.js.map +1 -1
- package/dist/model/shapeLint.d.ts +12 -0
- package/dist/model/shapeLint.js +170 -0
- package/dist/model/shapeLint.js.map +1 -0
- package/dist/model/storylines.d.ts +51 -0
- package/dist/model/storylines.js +188 -0
- package/dist/model/storylines.js.map +1 -0
- package/dist/model/validate.d.ts +6 -1
- package/dist/model/validate.js +317 -14
- package/dist/model/validate.js.map +1 -1
- package/dist/parser/againSugar.d.ts +30 -0
- package/dist/parser/againSugar.js +105 -0
- package/dist/parser/againSugar.js.map +1 -0
- package/dist/parser/ast.d.ts +33 -0
- package/dist/parser/lexer.d.ts +2 -0
- package/dist/parser/lexer.js +4 -0
- package/dist/parser/lexer.js.map +1 -1
- package/dist/parser/parser.js +284 -4
- package/dist/parser/parser.js.map +1 -1
- package/dist/query/format.js +1 -0
- package/dist/query/format.js.map +1 -1
- package/dist/query/verbs.d.ts +4 -0
- package/dist/query/verbs.js +30 -3
- package/dist/query/verbs.js.map +1 -1
- package/dist/render/drawEdges.js +100 -4
- package/dist/render/drawEdges.js.map +1 -1
- package/dist/render/render.js +20 -2
- package/dist/render/render.js.map +1 -1
- package/dist/render/sliceDiagram.js +5 -5
- package/dist/render/sliceDiagram.js.map +1 -1
- package/dist/render/storylineBands.d.ts +11 -0
- package/dist/render/storylineBands.js +80 -0
- package/dist/render/storylineBands.js.map +1 -0
- package/dist/render/storylineDiagram.d.ts +14 -0
- package/dist/render/storylineDiagram.js +142 -0
- package/dist/render/storylineDiagram.js.map +1 -0
- package/dist/roster/check.d.ts +32 -0
- package/dist/roster/check.js +92 -0
- package/dist/roster/check.js.map +1 -0
- package/dist/roster/context.d.ts +3 -0
- package/dist/roster/context.js +23 -0
- package/dist/roster/context.js.map +1 -0
- package/dist/roster/init.d.ts +15 -0
- package/dist/roster/init.js +52 -0
- package/dist/roster/init.js.map +1 -0
- package/dist/roster/roster.d.ts +79 -0
- package/dist/roster/roster.js +298 -0
- package/dist/roster/roster.js.map +1 -0
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +2 -2
- package/plugin/agents/em-implementer.md +7 -4
- package/plugin/agents/em-validator.md +2 -2
- package/plugin/shared/reference/em-dsl.md +94 -6
- package/plugin/shared/reference/methodology.md +268 -0
- package/plugin/shared/reference/slice-doc-schema.md +96 -2
- package/plugin/shared/templates/slice.md +11 -3
- package/plugin/skills/conform/SKILL.md +1 -1
- package/plugin/skills/design/SKILL.md +46 -5
- package/plugin/skills/discover/SKILL.md +43 -8
- package/plugin/skills/discover/reference/extract.md +6 -1
- package/plugin/skills/discover/reference/prd-rubric.md +103 -0
- package/plugin/skills/discover/reference/prd-spec-path.md +172 -0
- package/plugin/skills/engagement/SKILL.md +21 -9
- package/plugin/skills/event-modeling/SKILL.md +1 -1
- package/plugin/skills/implement/SKILL.md +1 -1
- package/plugin/skills/implement/reference/implement.md +18 -0
- package/plugin/skills/review/SKILL.md +4 -2
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
<!-- GENERATED FILE from .claude/skills/event-modeling-discover/reference/prd-spec-path.md by scripts/build-plugin.ts — do not hand-edit; run npm run docs:generate -->
|
|
2
|
+
# PRD/spec path — a document is the input
|
|
3
|
+
|
|
4
|
+
Read this **before doing any work on a PRD, requirements document or API spec**, together with
|
|
5
|
+
`prd-rubric.md` (the shipped classification rubric).
|
|
6
|
+
|
|
7
|
+
**Entry:** `/em:discover` (plugin) or `/em:event-modeling discover` (repo skills), with the opening
|
|
8
|
+
message **`Discover from this PRD/spec: <path>`**. This is the exact entry the eval protocol's
|
|
9
|
+
arm C cites. The path is a **triage**: a document
|
|
10
|
+
describes the system its authors imagined (resources, endpoints, stack, quality targets). Handed
|
|
11
|
+
one cold, the failure modes are over-decomposition along control flow, implementation flavour,
|
|
12
|
+
and CRUD-per-entity models shaped like the resource reference. The steps below prevent all three
|
|
13
|
+
by making every claim in the document earn its place in the model, visibly.
|
|
14
|
+
|
|
15
|
+
**Stance.** You are still extracting the domain from people, not inventing it. The document is
|
|
16
|
+
evidence. Anything it does not say, or says ambiguously, is a question (step 6), never a guess.
|
|
17
|
+
|
|
18
|
+
Setup: run the shared preconditions (`../../../shared/reference/operating-principles.md`),
|
|
19
|
+
agree the input path with the user, and create `discovery/` next to the model. Record the input
|
|
20
|
+
path in the state file's Session inputs.
|
|
21
|
+
|
|
22
|
+
## Step 0 — Walkthroughs become storylines
|
|
23
|
+
|
|
24
|
+
Before splitting anything, find the document's **walkthroughs**: a PRD's user stories and
|
|
25
|
+
journeys, an API spec's Walkthroughs / use-case / "getting started" section.
|
|
26
|
+
|
|
27
|
+
- The **end-to-end journey** is the **main storyline** — the happy path, on a timeline, with no
|
|
28
|
+
branching ("a story of what success looks like"). Every other walkthrough is a **secondary
|
|
29
|
+
storyline** (retire, extend, reorganize...). Exactly one is main.
|
|
30
|
+
- The timeline is built from these. The resource/endpoint reference is consulted **last**, only to
|
|
31
|
+
fill operations no walkthrough touches.
|
|
32
|
+
- No walkthrough at all? Ask: *"what does success look like, start to finish?"* and have the
|
|
33
|
+
human first add the answer to the source document (or to a `discovery/walkthroughs.md` companion
|
|
34
|
+
that then becomes the triage `source`); a quote that is not in the source is rejected by design.
|
|
35
|
+
Do not synthesize a journey from the endpoint list.
|
|
36
|
+
- Record each storyline in `storylines[]` with its `id`, `name`, `main`, and `quote` — the **full**
|
|
37
|
+
walkthrough span, start to finish success story, verbatim (not its first sentence: the checker
|
|
38
|
+
anchors every group to this span). These become the design phase's `storyline` blocks, so the provenance travels
|
|
39
|
+
(`../../em:design/SKILL.md`, step 5; syntax in `../../../shared/reference/em-dsl.md`).
|
|
40
|
+
|
|
41
|
+
## Step 1 — Split into single-claim statements
|
|
42
|
+
|
|
43
|
+
Split the input into **single-claim statements** — one fact, rule, need or description each. A
|
|
44
|
+
sentence with "and" usually holds two. Number them `S1`, `S2`, ... in source order. Each carries a
|
|
45
|
+
`quote` copied **verbatim** from the document (whitespace, Markdown emphasis marks and smart
|
|
46
|
+
quotes may differ; words may not; at least 12 characters). You may reword later (step 4) but never
|
|
47
|
+
in `quote`: the checker searches the document for it, and a quote it cannot find is an invented
|
|
48
|
+
claim. Every statement also records `provenance`: `walkthrough` for a claim made inside a
|
|
49
|
+
walkthrough span, `reference` for one from the resource/endpoint reference or operational notes.
|
|
50
|
+
**Every claim in a walkthrough gets a statement** — the carrier collecting, the delivery being
|
|
51
|
+
confirmed, the return before the due date — so nothing in the story is silently dropped; the
|
|
52
|
+
checker cannot see a missing one, so walk each walkthrough sentence by sentence.
|
|
53
|
+
|
|
54
|
+
## Step 2 — Classify
|
|
55
|
+
|
|
56
|
+
For each statement set:
|
|
57
|
+
|
|
58
|
+
- `category` — one id from `prd-rubric.md`.
|
|
59
|
+
- `aboutBusiness` — the independent check: *"is this about the business, independent of how it is
|
|
60
|
+
built?"* Answer it separately from the category, without looking at the category.
|
|
61
|
+
- `confidence` — `high` or `low`. Any doubt: `low` (a low-confidence statement is always a question).
|
|
62
|
+
|
|
63
|
+
When `aboutBusiness` contradicts what the category expects (the rubric's `aboutBusiness expected`
|
|
64
|
+
column), that disagreement is data, not judgement: the outcome MUST be `question` (step 4, step 6).
|
|
65
|
+
|
|
66
|
+
A `resource-or-endpoint` statement is **never promoted to a command as-is**: ask which intent(s)
|
|
67
|
+
the resource serves (one endpoint may carry several intents) and rewrite to those (step 4).
|
|
68
|
+
|
|
69
|
+
## Step 3 — Group by reaction
|
|
70
|
+
|
|
71
|
+
A **group** is one future slice. Statements sharing a **trigger** and an **acting system** are one
|
|
72
|
+
group (`groups[]`: `id`, `name`, `trigger`, `actor`, `storyline`). Follow the merged reaction
|
|
73
|
+
shape (`../../../shared/reference/methodology.md`): a reaction, its command and its
|
|
74
|
+
event share one slice.
|
|
75
|
+
|
|
76
|
+
- **Failure, retry and timeout statements are not new slices.** They become outcome events and
|
|
77
|
+
Given/When/Then scenarios of the slice whose trigger they belong to; set `scenarioOf` to that
|
|
78
|
+
group's id.
|
|
79
|
+
- **Storyline check.** A statement joins the storyline whose **journey it advances**, not the
|
|
80
|
+
entity it mentions. A "Product" sentence in the retire walkthrough belongs to "Retire a
|
|
81
|
+
product", not to a Product lifecycle.
|
|
82
|
+
- One group per trigger-and-actor; never one group per entity or per endpoint.
|
|
83
|
+
- **A group is anchored or reference-only, never both.** An anchored group names a storyline and
|
|
84
|
+
holds at least one `walkthrough` statement quoted from inside that storyline's span. A group
|
|
85
|
+
built only from `reference` statements (operations no walkthrough touches) is reference-only:
|
|
86
|
+
`storyline: null` on the group and on its statements. It never joins a walkthrough storyline,
|
|
87
|
+
and the report lists it outside every storyline for the human to inspect.
|
|
88
|
+
- A claim is quoted once: no statement's quote may equal, contain, be contained in, or partially overlap by character range in the normalised source another's. Only `modeled`/`rewritten` walkthrough statements anchor a group; a `question` never does.
|
|
89
|
+
|
|
90
|
+
## Step 4 — Rewrite, don't drop
|
|
91
|
+
|
|
92
|
+
Nothing is silently discarded.
|
|
93
|
+
|
|
94
|
+
- An **implementation detail that implies a business fact** (*"the service writes a row to
|
|
95
|
+
`stock_levels` when a pick is confirmed"*): classify it `implementation-detail` with
|
|
96
|
+
`aboutBusiness: false` — they agree, so it is `rewritten`, with the business-language form in
|
|
97
|
+
`rewrite` (*"Stock is decremented when a pick is confirmed"*); the original stays in `quote`,
|
|
98
|
+
which is the link to its source. If you classified the same sentence `business-fact` but the
|
|
99
|
+
independent check says `false`, they **disagree**: the outcome is `question`, with the proposed
|
|
100
|
+
rewrite in the question text (*"Is this a business fact? proposed: Stock is decremented when a
|
|
101
|
+
pick is confirmed."*). The human resolves it and a later pass records `rewritten`.
|
|
102
|
+
- A **real technology choice or NFR** (*"must run on Postgres"*, *"p95 under 300 ms"*) gets outcome
|
|
103
|
+
`constraint` and an entry in `constraints[]` listing its statement ids. That list feeds the
|
|
104
|
+
project's constitution: hand it to the constitution's owner (the skills read the constitution,
|
|
105
|
+
never write it); it never becomes a slice.
|
|
106
|
+
- Anything else you set aside is `parked` with a `reason`, **and** recorded in the state file's
|
|
107
|
+
Decisions log with why (the same rule as rejected events in `discover` step 1), so it is not
|
|
108
|
+
re-proposed later.
|
|
109
|
+
|
|
110
|
+
## Step 5 — Record
|
|
111
|
+
|
|
112
|
+
Write `discovery/prd-triage.json` (UTF-8, 2-space indent):
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"prdTriageSchemaVersion": "1.0",
|
|
117
|
+
"rubricVersion": "1.0",
|
|
118
|
+
"source": "prd.md",
|
|
119
|
+
"storylines": [{ "id": "L1", "name": "Order to delivery", "main": true, "quote": "A customer places an order. We pick and ship it, and they get a tracking link." }],
|
|
120
|
+
"groups": [{ "id": "G1", "name": "Place Order", "trigger": "customer submits checkout", "actor": "Storefront", "storyline": "L1" }],
|
|
121
|
+
"statements": [
|
|
122
|
+
{ "id": "S1", "quote": "A customer places an order.", "category": "user-intent", "aboutBusiness": true, "confidence": "high", "provenance": "walkthrough", "outcome": "modeled", "group": "G1", "storyline": "L1" },
|
|
123
|
+
{ "id": "S2", "quote": "must respond within 300 ms", "category": "nfr", "aboutBusiness": false, "confidence": "high", "provenance": "reference", "outcome": "constraint", "group": null, "storyline": null },
|
|
124
|
+
{ "id": "S3", "quote": "writes a row to stock_levels", "category": "business-fact", "aboutBusiness": false, "confidence": "high", "provenance": "reference", "outcome": "question", "group": null, "storyline": null, "question": "Is this a business fact? proposed: Stock is decremented when a pick is confirmed." }
|
|
125
|
+
],
|
|
126
|
+
"constraints": [{ "id": "C1", "text": "Checkout responds within 300 ms", "statements": ["S2"] }]
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Per statement: `id`, `quote`, `category`, `aboutBusiness`, `confidence`, `provenance`, `outcome`
|
|
131
|
+
(`modeled | rewritten | constraint | parked | question`), `group` and `storyline` (set for
|
|
132
|
+
`modeled`/`rewritten`, otherwise `null`), plus `rewrite` / `reason` / `question` /
|
|
133
|
+
`scenarioOf` where the outcome needs them. **Every statement has a category and an outcome;
|
|
134
|
+
every modeled or rewritten statement has a group.** The rules the checker enforces are listed in
|
|
135
|
+
`prd-rubric.md` ("Rules the checker enforces"): disagreement and low confidence are questions, an
|
|
136
|
+
endpoint is never modeled, group and storyline only for modeled/rewritten (otherwise `null`),
|
|
137
|
+
provenance verified against the storyline spans (a `walkthrough` quote lies inside one, a
|
|
138
|
+
`reference` quote outside all), no shared quotes, and every group either anchored by a walkthrough
|
|
139
|
+
statement inside its storyline's span or reference-only (`"storyline": null` on the group and its
|
|
140
|
+
statements, listed in the report outside every storyline).
|
|
141
|
+
|
|
142
|
+
Then run, and fix until it passes:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
em discover triage-check discovery/prd-triage.json # MCP: discover_triage_check
|
|
146
|
+
em discover triage-check discovery/prd-triage.json --markdown > discovery/prd-triage.md
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`--markdown` prints the human-readable view (storylines, slice groups with their statements,
|
|
150
|
+
constraints, parked, questions); save it next to the JSON. The checker verifies shape, the rubric
|
|
151
|
+
version, verbatim quotes, and the outcome rules; **it cannot judge whether your classification is
|
|
152
|
+
right**, whether every walkthrough claim has a statement, or whether the Decisions-log entry for
|
|
153
|
+
each parked or rejected statement was actually written (that entry is prose-only and unchecked) —
|
|
154
|
+
that is what the human review is for. Read the report's **reference-only groups** list: those
|
|
155
|
+
are operations no walkthrough touches; check they are not CRUD fill. Also confirm each
|
|
156
|
+
**storyline quote really is a walkthrough span**: storyline spans are self-declared and the
|
|
157
|
+
checker cannot know which sections of the document are walkthroughs. The `--markdown` view lists
|
|
158
|
+
the storylines with their quotes for exactly this review.
|
|
159
|
+
|
|
160
|
+
## Step 6 — Questions, never inventions
|
|
161
|
+
|
|
162
|
+
Every `low` confidence statement, every statement where `aboutBusiness` contradicts the
|
|
163
|
+
category's expectation, and every `question` category statement gets outcome `question` and a
|
|
164
|
+
Socratic `question` (a disagreement's question carries the proposed rewrite). Ask them one concern at a time, in the story's words. Record each answer in the state
|
|
165
|
+
file and update the record (the statement is re-classified; re-run the checker). If the document
|
|
166
|
+
and the human disagree, the human wins and the disagreement is a Decisions-log entry.
|
|
167
|
+
|
|
168
|
+
## Hand-off
|
|
169
|
+
|
|
170
|
+
Continue with `discover` steps 1-4 (`../SKILL.md`) on the surviving groups: the storylines are the
|
|
171
|
+
timeline's spine, each group seeds one slice, and the constraints list goes to the project
|
|
172
|
+
constitution. `discovery/prd-triage.json` stays in the repo as provenance for the model.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: engagement
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.18.1
|
|
4
4
|
description: >-
|
|
5
5
|
Use when leading an engagement: building a named set of ratified event-modeling slices
|
|
6
6
|
(`em engagement`) into one independent PR per slice, each against main, by dispatching the
|
|
@@ -72,7 +72,11 @@ Run the shared preconditions first (tool check, bundle currency, locate the mode
|
|
|
72
72
|
5. **The engagement exists.** `em engagement status <model>.em <slug>`. If there is no such
|
|
73
73
|
engagement, ask the human which slices it covers (a list, a context, or "everything
|
|
74
74
|
downstream of X") and run `em engagement new <model>.em <slug> --slices a,b,c` (or
|
|
75
|
-
`--context <C>`, or `--downstream-of <ref>`) `--by "<their name>"`.
|
|
75
|
+
`--context <C>`, or `--downstream-of <ref>`) `--by "<their name>"`. First check the host
|
|
76
|
+
repo's PR-title convention (a commitlint config, a PR-title workflow, or the last few merged
|
|
77
|
+
PR titles) and pass `--pr-title "<template>"` when it differs from the default
|
|
78
|
+
`<key>: <slice name>`; placeholders are `{key}`, `{slice}` (display name) and `{sliceKey}`
|
|
79
|
+
(kebab key, usually what a lint wants). When `new` warns that the
|
|
76
80
|
selection has several unconnected components, relay its suggestion (one engagement each)
|
|
77
81
|
and let the human decide before going on.
|
|
78
82
|
|
|
@@ -84,7 +88,9 @@ base is `main`), and every held slice with its reason (`not-ready`,
|
|
|
84
88
|
`upstream-outside-engagement-unmerged`, or `human`). Then the plan's **`pre-flight:` block** (GH
|
|
85
89
|
#239): the model-wide gaps the engagement's slices share — a `repeated-invariant` with no single
|
|
86
90
|
enforcing slice, an `event-without-tag` whose consistency boundary is undeclared, a
|
|
87
|
-
`shared-trigger` (one `ui`, two slices, no endpoint owner), a `doc-model-mismatch
|
|
91
|
+
`shared-trigger` (one `ui`, two slices, no endpoint owner), a `doc-model-mismatch`, a `shape` (a
|
|
92
|
+
`em validate --shape` lint fires on the slices; the answer is a `shape-accepted: <rule> <refs> —
|
|
93
|
+
<reason>` bullet in `.event-modeling.md` `## Decisions log`, or a model fix). These are
|
|
88
94
|
exactly what every implementer would otherwise stop on and report separately. Put them to the
|
|
89
95
|
human **in the same single question round** as the ceiling, one bullet each with the slices it
|
|
90
96
|
spans, and ask for a ruling on each (the answer goes where it belongs: the model, the foundation
|
|
@@ -116,10 +122,13 @@ For each slice the plan lists as not held:
|
|
|
116
122
|
4. Record it:
|
|
117
123
|
`em engagement set <model>.em <slug> <key> --state building --branch impl/<key> --base <base>`
|
|
118
124
|
5. Dispatch `em-implementer` (`em:em-implementer` under the plugin) on the implementer model.
|
|
119
|
-
Its prompt is ONLY the slice key, the absolute worktree path
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
125
|
+
Its prompt is ONLY the slice key, the absolute worktree path, the exact pull-request title
|
|
126
|
+
and, when there is one, the tracking key. The title is the slice's `prTitle` from
|
|
127
|
+
`em engagement plan --json` (GH #334), already resolved from the engagement's `--pr-title`
|
|
128
|
+
template or the default: pass it verbatim and never compose one. The tracking key is the
|
|
129
|
+
plan's `tracking` (GH #241), already resolved: the slice doc's own `tracking:` wins over the
|
|
130
|
+
engagement's `--tracking`, and it is `null` when neither is set (then say nothing about
|
|
131
|
+
tracking). Surface any `pr-title-fallback` pre-flight entry to the human. It reads
|
|
123
132
|
its own spec, the constitution and the implement contract. Give it no plan, no other slice,
|
|
124
133
|
and no merge instructions.
|
|
125
134
|
|
|
@@ -131,7 +140,7 @@ When the implementer returns a PR URL (and a per-invariant test map):
|
|
|
131
140
|
base: `gh pr view <url> --json baseRefName` must be `main`. If not, fix it with
|
|
132
141
|
`gh pr edit <url> --base main`. That is a lead step; the implementer never changes a base.
|
|
133
142
|
2. Dispatch `em-validator` (`em:em-validator`) with the slice key, the worktree path and the same
|
|
134
|
-
tracking key (when the slice has one)
|
|
143
|
+
tracking key (when the slice has one) and the same `prTitle`. It
|
|
135
144
|
returns one PASS/FAIL line per check and `OVERALL: PASS` or a failure.
|
|
136
145
|
3. On `OVERALL: PASS`: `em engagement set <model>.em <slug> <key> --state review`. Dispatch
|
|
137
146
|
`em-reviewer` (`em:em-reviewer`) with the slice key and the PR URL. Dispatch `em-critic`
|
|
@@ -172,7 +181,10 @@ You never merge.
|
|
|
172
181
|
`main`: `git switch -c engagement/<slug>-level-<n> main`, run
|
|
173
182
|
`em slice mark-implemented <model>.em <key> <pr-url>` for each slice merged in the level,
|
|
174
183
|
then `em slice index <model>.em`, commit, and `gh pr create --base main`. The human merges it
|
|
175
|
-
like any other PR.
|
|
184
|
+
like any other PR. If `mark-implemented` printed `opened draft v<n+1>` for a slice, its doc in
|
|
185
|
+
this PR reads `status: draft`: say so in the hand-back and paste the command's notice into the PR
|
|
186
|
+
body — `shippedVersion:`/`implementedIn:` are the record that v<n> was implemented, `status:` is
|
|
187
|
+
the next version's state, so the reviewer does not read it as a slice that was never marked.
|
|
176
188
|
4. Recompute: `em engagement plan <model>.em <slug>`. A merge can release an
|
|
177
189
|
`upstream-outside-engagement-unmerged` hold once that upstream's doc reads `implemented`.
|
|
178
190
|
Continue with step 3 for anything newly startable.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: event-modeling
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.18.1
|
|
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.18.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
|
|
@@ -35,6 +35,16 @@ every `## Open Questions` checkbox is checked, and no status/version/link incohe
|
|
|
35
35
|
— `gates` names each of those 4 conditions individually (`docBound`/`frontmatterUsable`/
|
|
36
36
|
`statusReady`/`noUncheckedOpenQuestions`) if you need to say which one is blocking.
|
|
37
37
|
|
|
38
|
+
`ready` is the named gates, plus error-severity diagnostics scoped to the slice, plus these warning-severity codes:
|
|
39
|
+
|
|
40
|
+
- `slice-ready-no-doc-bound`, `slice-ready-status-not-ready`, `slice-ready-open-questions-unchecked`: the gates themselves.
|
|
41
|
+
- `binding-missing-file`, `frontmatter-invalid`: the `frontmatterUsable` gate.
|
|
42
|
+
- `both-ends-of-a-flow/*`: a dangling slice is not a complete pattern.
|
|
43
|
+
- `fields-completeness/event-field-no-source`: the `assigned` marker contract (MIL-148).
|
|
44
|
+
- `invariants/public-command-without-invariants`: the API-first readiness requirement (`docs/process.md`).
|
|
45
|
+
|
|
46
|
+
A warning whose code is in this list blocks; any other warning never does (it stays in `diagnostics`; don't treat it as a blocker). `--strict` promotes advisory rules only.
|
|
47
|
+
|
|
38
48
|
**`ready: false` means stop** — with one named exception: a slice already `status: implemented`
|
|
39
49
|
with `driftSignal: in-sync` or `uncertified` (MIL-214) also reads `ready: false` (its
|
|
40
50
|
`statusReady` gate fails because nothing is newly ratified), and that specific case is
|
|
@@ -255,6 +265,14 @@ the question back to `- [ ]`; the version you built stays shipped) — a questio
|
|
|
255
265
|
slice defer` while the doc was ratified (GH #253) is one of those. If it prints `opened draft
|
|
256
266
|
v<N+1>`, say so in your report: the slice has known work, and a design session, not you, decides it.
|
|
257
267
|
|
|
268
|
+
**What the PR will show.** In that case the slice doc in your PR reads `status: draft` with
|
|
269
|
+
`version: <N+1>` — not `implemented`. That is correct, not a failed flip: `shippedVersion: <N>` and
|
|
270
|
+
`implementedIn:` are the record that v<N> was implemented, and `status:` is the next version's
|
|
271
|
+
state. The command prints a multi-line notice (what shipped, what opened, the reopened question
|
|
272
|
+
titles; `--json` gives `nextDraft: { version, reopened[] }`) — paste it into the PR description so a
|
|
273
|
+
reviewer who sees `status: draft` knows where to look. `em status` lists the slice as `implemented
|
|
274
|
+
(v<N>) · draft v<N+1> open`.
|
|
275
|
+
|
|
258
276
|
Then, if the project keeps a model README (from `../../../shared/templates/model-readme.md`), run
|
|
259
277
|
`em slice index <model-name>.em` so its generated Slices table reflects the new status and
|
|
260
278
|
link — never hand-edit that table. The `implementedIn` link is what the `conform` phase later
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: review
|
|
3
|
-
em-version: 1.
|
|
3
|
+
em-version: 1.18.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
|
|
@@ -66,7 +66,9 @@ review:` marker (mirrors `Last conformance:`).
|
|
|
66
66
|
|
|
67
67
|
Then, and only then: a slice with nothing left `- [ ]` and no open `issue` →
|
|
68
68
|
`em slice review <model>.em <key> --by <name>` (flips its doc to `status: reviewed` and records
|
|
69
|
-
`reviewedBy:`/`reviewedOn:`).
|
|
69
|
+
`reviewedBy:`/`reviewedOn:`). `em slice review` itself exits 1 on an unchecked Open Question
|
|
70
|
+
(`--allow-open` records a deliberately partial walk; `--again` re-records a review after a body edit).
|
|
71
|
+
Anything still open stays `draft` — the walkthrough doesn't decide
|
|
70
72
|
it, the next session or the open-questions list does.
|
|
71
73
|
|
|
72
74
|
**The facilitator never ratifies, never offers to ratify, and never suggests ratification in a
|