@milehimikey/em 1.6.1 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/.claude/skills/event-modeling/SKILL.md +94 -49
  2. package/.claude/skills/event-modeling/reference/conform.md +30 -8
  3. package/.claude/skills/event-modeling/reference/em-dsl.md +194 -73
  4. package/.claude/skills/event-modeling/reference/extract.md +14 -11
  5. package/.claude/skills/event-modeling/reference/implement.md +172 -0
  6. package/.claude/skills/event-modeling/reference/methodology.md +40 -33
  7. package/.claude/skills/event-modeling/templates/conformance-report.md +15 -9
  8. package/.claude/skills/event-modeling/templates/model-readme.md +7 -7
  9. package/.claude/skills/event-modeling/templates/slice.md +73 -7
  10. package/.claude/skills/event-modeling/templates/state.md +7 -6
  11. package/README.md +1 -0
  12. package/dist/catalog/build.d.ts +5 -0
  13. package/dist/catalog/build.js +1 -3
  14. package/dist/catalog/build.js.map +1 -1
  15. package/dist/catalog/classify.d.ts +7 -8
  16. package/dist/catalog/classify.js +7 -8
  17. package/dist/catalog/classify.js.map +1 -1
  18. package/dist/catalog/docJoin.d.ts +39 -0
  19. package/dist/catalog/docJoin.js +86 -0
  20. package/dist/catalog/docJoin.js.map +1 -0
  21. package/dist/catalog/driftSignal.d.ts +16 -0
  22. package/dist/catalog/driftSignal.js +24 -0
  23. package/dist/catalog/driftSignal.js.map +1 -0
  24. package/dist/catalog/frontmatterCoherenceValidate.d.ts +8 -0
  25. package/dist/catalog/frontmatterCoherenceValidate.js +52 -0
  26. package/dist/catalog/frontmatterCoherenceValidate.js.map +1 -0
  27. package/dist/catalog/lineageValidate.d.ts +9 -0
  28. package/dist/catalog/lineageValidate.js +161 -0
  29. package/dist/catalog/lineageValidate.js.map +1 -0
  30. package/dist/catalog/readSliceDoc.d.ts +2 -0
  31. package/dist/catalog/readSliceDoc.js +21 -0
  32. package/dist/catalog/readSliceDoc.js.map +1 -0
  33. package/dist/catalog/sliceDoc.d.ts +94 -3
  34. package/dist/catalog/sliceDoc.js +157 -7
  35. package/dist/catalog/sliceDoc.js.map +1 -1
  36. package/dist/catalog/sliceReadyValidate.d.ts +11 -0
  37. package/dist/catalog/sliceReadyValidate.js +85 -0
  38. package/dist/catalog/sliceReadyValidate.js.map +1 -0
  39. package/dist/cli/diff-inputs.d.ts +20 -0
  40. package/dist/cli/diff-inputs.js +75 -18
  41. package/dist/cli/diff-inputs.js.map +1 -1
  42. package/dist/cli/ledgerCheck.d.ts +38 -0
  43. package/dist/cli/ledgerCheck.js +116 -0
  44. package/dist/cli/ledgerCheck.js.map +1 -0
  45. package/dist/cli/skillCheck.d.ts +18 -0
  46. package/dist/cli/skillCheck.js +63 -0
  47. package/dist/cli/skillCheck.js.map +1 -0
  48. package/dist/cli/skillSync.d.ts +22 -0
  49. package/dist/cli/skillSync.js +69 -0
  50. package/dist/cli/skillSync.js.map +1 -0
  51. package/dist/cli/skillVersionCheck.d.ts +32 -0
  52. package/dist/cli/skillVersionCheck.js +145 -0
  53. package/dist/cli/skillVersionCheck.js.map +1 -0
  54. package/dist/cli.d.ts +3 -1
  55. package/dist/cli.js +203 -32
  56. package/dist/cli.js.map +1 -1
  57. package/dist/emit/diffJson.d.ts +1 -1
  58. package/dist/emit/diffJson.js +18 -14
  59. package/dist/emit/diffJson.js.map +1 -1
  60. package/dist/emit/dot.js +46 -5
  61. package/dist/emit/dot.js.map +1 -1
  62. package/dist/emit/json.d.ts +10 -25
  63. package/dist/emit/json.js +70 -103
  64. package/dist/emit/json.js.map +1 -1
  65. package/dist/emit/ledgerJson.d.ts +5 -0
  66. package/dist/emit/ledgerJson.js +25 -0
  67. package/dist/emit/ledgerJson.js.map +1 -0
  68. package/dist/emit/skillCheckJson.d.ts +5 -0
  69. package/dist/emit/skillCheckJson.js +32 -0
  70. package/dist/emit/skillCheckJson.js.map +1 -0
  71. package/dist/model/diff.d.ts +44 -1
  72. package/dist/model/diff.js +51 -9
  73. package/dist/model/diff.js.map +1 -1
  74. package/dist/model/edges.js +17 -17
  75. package/dist/model/edges.js.map +1 -1
  76. package/dist/model/model.d.ts +1 -1
  77. package/dist/model/refs.d.ts +23 -0
  78. package/dist/model/refs.js +75 -0
  79. package/dist/model/refs.js.map +1 -0
  80. package/dist/model/rules.d.ts +253 -0
  81. package/dist/model/rules.js +254 -0
  82. package/dist/model/rules.js.map +1 -0
  83. package/dist/model/validate.d.ts +23 -1
  84. package/dist/model/validate.js +207 -69
  85. package/dist/model/validate.js.map +1 -1
  86. package/dist/parser/ast.d.ts +3 -2
  87. package/dist/parser/lexer.d.ts +17 -2
  88. package/dist/parser/lexer.js +119 -13
  89. package/dist/parser/lexer.js.map +1 -1
  90. package/dist/parser/parser.js +75 -34
  91. package/dist/parser/parser.js.map +1 -1
  92. package/dist/pipeline.d.ts +9 -0
  93. package/dist/pipeline.js +4 -2
  94. package/dist/pipeline.js.map +1 -1
  95. package/dist/render/sliceDiagram.js +33 -35
  96. package/dist/render/sliceDiagram.js.map +1 -1
  97. package/dist/render/sliceStatus.js +1 -1
  98. package/dist/render/sliceStatus.js.map +1 -1
  99. package/dist/util/isMainModule.d.ts +14 -0
  100. package/dist/util/isMainModule.js +33 -0
  101. package/dist/util/isMainModule.js.map +1 -0
  102. package/dist/util/walkDir.d.ts +4 -0
  103. package/dist/util/walkDir.js +28 -0
  104. package/dist/util/walkDir.js.map +1 -0
  105. package/package.json +5 -2
@@ -0,0 +1,172 @@
1
+ # Implementing a ratified slice
2
+
3
+ The contract for the implementation half of the workflow: an agent (or engineer) turning **one
4
+ ratified slice** into merged, verified code. The facilitation phases (`discover`/`extract` →
5
+ `model` → `slice`) produce the inputs; this document governs consuming them. It applies to any
6
+ implementing agent, whether or not the session started from `/event-modeling`.
7
+
8
+ **The contract in one paragraph:** the slice doc is the spec — nothing between it and the code
9
+ is a source of truth. Verify readiness mechanically before writing any code; implement exactly
10
+ what the doc says; put every gap in front of a human instead of deciding it silently; never
11
+ edit the ratified doc except the two lifecycle fields at merge; prove the work with tests
12
+ traceable to the doc's invariants and scenarios.
13
+
14
+ Why the rules are shaped this way: **agents propose, humans ratify.** Everything in the model
15
+ and its slice docs is there because a human decided it on purpose — that is what makes the
16
+ model authoritative. An implementing agent that silently patches a gap, or edits a ratified
17
+ doc outside a session, converts the model into just another generated artifact and voids the
18
+ whole methodology. (The full human/agent partition is `docs/process.md` in the
19
+ [em repository](https://github.com/milehimikey/em/blob/main/docs/process.md) — not vendored
20
+ with this skill.)
21
+
22
+ ## 1. Gate: verify readiness before starting
23
+
24
+ ```bash
25
+ em validate <model>.em --slice-ready <slice-key>
26
+ ```
27
+
28
+ `<slice-key>` is the slice's export key — the kebab-case slug of its name (`"Place Order"` →
29
+ `place-order`). Exit 0 means: the slice has a doc bound via `note "slices/<key>.md"`, its
30
+ frontmatter is usable, `status: ready-to-implement`, every `## Open Questions` checkbox is
31
+ checked, and no status/version/link incoherence is flagged.
32
+
33
+ **Non-zero exit means stop.** Report which checks failed and hand the slice back to the humans.
34
+ Never make the gate pass yourself — checking an open-question box, flipping `status`, or
35
+ editing frontmatter are ratification decisions, and ratification happens in a facilitated
36
+ session, not in an implementation branch.
37
+
38
+ ## 2. Read the spec
39
+
40
+ Read `slices/<slice-key>.md` end to end — every section is load-bearing:
41
+
42
+ | Section | What it is to the implementer |
43
+ |---|---|
44
+ | frontmatter `pattern:` | Which of the four patterns' implementation shapes to build (State Change / State View / Automation / Translation) |
45
+ | Command / Event field tables | The contracts — names, types, validation rules, immutable-fact markers |
46
+ | `## Invariants / Business Rules` (INV-n IDs) | The non-negotiable rules; every one needs a test citing its ID |
47
+ | `## Scenarios (Given / When / Then)` | The acceptance tests, already written — compile them, don't reinvent them |
48
+ | `## Alternate & Error Flows` | Retries, idempotency, compensations — real requirements, not appendix |
49
+ | `## Non-Functional Requirements` | Authz, PII, performance — implement or consciously surface, never skip |
50
+ | `## Dependencies & Read Models Affected` | The blast radius — what else to check before and after |
51
+
52
+ For timeline context, read the slice's surroundings in the `.em` (what triggers it, what
53
+ consumes its output) — the slice's own diagram (`slices/<slice-key>.svg`) shows its canonical
54
+ pattern shape. For machine-readable facts, use `em export <model>.em` rather than parsing the
55
+ DSL or the doc's frontmatter yourself: it carries the slice's `pattern`, element refs, fields,
56
+ and the joined doc metadata (`slice.doc.status`, `version`, `driftSignal`).
57
+
58
+ If the project ships pattern-specific implementation skills (for example an Axon/DCB skill
59
+ set keyed on a slice doc's `pattern:` frontmatter), route by the slice's pattern and follow
60
+ those.
61
+
62
+ ## 3. Two modes: first version vs. ratified delta
63
+
64
+ Check the doc's `version:` and `## Delta` section (or `em export`'s `slice.doc.driftSignal`):
65
+
66
+ - **First implementation** (`version: 1`, no `## Delta`, `driftSignal: never-implemented`):
67
+ green-field slice implementation. Build the whole pattern shape the doc specifies.
68
+ - **Ratified delta** (`version` > 1, `## Delta` present, `status: ready-to-implement` while
69
+ `implementedIn` still names the prior version's PR — `driftSignal: unpropagated-delta`):
70
+ this is a **change to existing, owned code**. The `## Delta` section's typed operations
71
+ (Added/Modified/Removed/Renamed, each with scenarios) scope the work precisely — which
72
+ invariants, which scenarios, which tests change. Touch what the delta names; leave the rest.
73
+ **Never regenerate merged code wholesale from the model** — after merge, code is owned by
74
+ the people who've edited it (generated-then-owned); regeneration is legal only for slices
75
+ whose code never merged.
76
+
77
+ ## 4. Gaps: propose, never decide
78
+
79
+ Mid-implementation you will hit things the doc doesn't answer — a field's edge case, an
80
+ undocumented ordering, a contradiction with adjacent code. The discipline:
81
+
82
+ - **Stop that thread and surface it.** State precisely what's unspecified, the options, and
83
+ your recommendation. The human resolves it — at the model, where the resolution lands as an
84
+ answered open question or a small ratified delta alongside your fix, so the decision is
85
+ recorded instead of buried in an implementation diff.
86
+ - **Never edit the ratified doc to record your own answer**, and never quietly pick a behavior
87
+ a business person could have an opinion on. Silent divergence is the failure mode the whole
88
+ conformance loop exists to catch — don't manufacture it.
89
+ - Purely technical choices with no behavioral surface (private naming, idiomatic structure,
90
+ which assertion library) are yours; anything observable in behavior, data, or contract is not.
91
+
92
+ ## 5. Definition of done
93
+
94
+ - Every `INV-n` invariant has at least one test that cites its ID.
95
+ - Every scenario in `## Scenarios (Given / When / Then)` exists as a passing test; rejection
96
+ scenarios assert the doc's named rejection reason.
97
+ - Alternate/error flows (idempotency included) are covered by tests.
98
+ - The build and full test suite are green; the model still validates (`em validate` in CI —
99
+ you didn't touch the `.em`, so this only fails if something else broke).
100
+ - Nothing between the slice doc and the code was committed as a source of truth (see §7 —
101
+ work containers are ephemeral; generated or symlinked specs are renderings).
102
+
103
+ ## 6. At merge: the lifecycle flip
104
+
105
+ When the PR merges, exactly **two** frontmatter fields change on the slice doc:
106
+
107
+ ```yaml
108
+ status: implemented
109
+ implementedIn: <PR or commit URL>
110
+ ```
111
+
112
+ This is supply-loop mechanics, not ratification — it's the one edit an implementing agent makes
113
+ to a slice doc, and it's why `em ledger` deliberately excludes these two fields from what
114
+ counts as content. **Do not bump `version:`** — versions bump only when a delta is ratified;
115
+ a bump here is a ledger defect. In bridge-equipped projects,
116
+ `npx -p em-sdd-bridge em-sdd-mark-implemented <slice-key> <pr-url>` does the flip for you.
117
+
118
+ Then update the model's `README.md` slice index if the project keeps one, so the one canonical
119
+ slice table reflects the new status and link. The `implementedIn` link is what the `conform`
120
+ phase later uses to anchor drift-checking — leaving it empty blinds the loop.
121
+
122
+ ## 7. Spec-kit projects: the SDD adapter
123
+
124
+ If the repository uses spec-kit (a `.specify/` directory exists), do not hand-author spec-kit
125
+ artifacts — allocate through **em-sdd-bridge**, redirect mode preferred:
126
+
127
+ ```bash
128
+ npx em-sdd-bridge@<pinned-version> <slice-key> --symlink
129
+ ```
130
+
131
+ That allocates the feature branch and `specs/NNN-slug/` dir, runs the same readiness gates,
132
+ and drops `spec.md` as a **symlink to the slice doc** — the slice doc itself travels through
133
+ plan/tasks as FEATURE_SPEC. The rules that keep redirect mode safe:
134
+
135
+ - **Never run `/speckit.specify`.** The ratified slice *is* the spec; an interactive specify
136
+ session against a defined slice creates a second, unratified source of truth.
137
+ - **`/speckit.clarify` must never write into a slice doc.** Open questions resolve at the
138
+ model (that's what the readiness gate enforced); a ratified slice has nothing to clarify.
139
+ Projects using em-sdd-preset's overlays carry a mechanical guard for this — respect the
140
+ rule even where the guard isn't installed.
141
+ - `/speckit.plan` and `/speckit.tasks` may run against the slice doc directly; the preset's
142
+ redirect preambles map spec-kit's section vocabulary onto the slice doc's sections.
143
+ - **Emission fallback**: where redirect can't work (Windows checkouts without symlink
144
+ privileges, two-doc pattern-pair bundles, a toolchain that mutates its spec files), run the
145
+ bridge without `--symlink` to render `spec.md` from the slice doc. The generated file is a
146
+ rendering — never hand-edit it; regenerate it from the slice doc instead.
147
+ - Everything under `specs/NNN-*/` is an **ephemeral work container** — one per change effort,
148
+ discardable; the PR is the durable record of the effort, the slice doc the durable
149
+ definition of the behavior.
150
+
151
+ No spec-kit (or any SDD tool)? Implement straight from the slice doc — it already contains
152
+ everything a spec holds. Don't introduce an intermediate spec document of your own.
153
+
154
+ ## 8. Never do
155
+
156
+ | Rule | Because |
157
+ |---|---|
158
+ | Never implement from a slice that fails `--slice-ready` | The gate is the handoff contract; bypassing it hands you unratified decisions |
159
+ | Never edit a ratified slice doc, except the two §6 fields at merge | Doc content is ratified; edits outside a session are unratified decisions |
160
+ | Never edit the `.em` model | Model edits are ratified decisions — propose, don't write |
161
+ | Never bump `version:` | Versions move only with ratified deltas; see `em ledger` |
162
+ | Never silently decide unspecified behavior | Silent divergence is the disease the conformance loop exists to catch |
163
+ | Never regenerate merged code from the model | Generated-then-owned: post-merge code belongs to its owners |
164
+ | Never commit an authored intermediate spec | The slice is the spec; anything between it and the code is a rendering |
165
+
166
+ ## 9. Afterward: the loop closes
167
+
168
+ Implementation isn't the end of the slice's story. On a cadence — or whenever someone asks —
169
+ the `conform` phase checks implemented slices against the code, using the `implementedIn` link
170
+ you recorded, and reports drift for humans to rule on (see `reference/conform.md`). Your two
171
+ duties to that future loop are already behind you if you followed this doc: an accurate
172
+ lifecycle flip, and zero silent decisions.
@@ -25,16 +25,16 @@ tempting shortcuts:
25
25
  - **`command → read model`** — the CQRS violation. A write is only ever visible to a reader
26
26
  through the event it recorded. Put the event between them.
27
27
  - **`read model → command`** — reads never drive a write directly. A processor or translation
28
- watches the read model and issues the command, across two slices.
28
+ watches the read model and issues the command that sits in the same slice.
29
29
 
30
30
  If you find yourself wanting an arrow the patterns don't allow, the model is missing an
31
31
  **element**, not an arrow.
32
32
 
33
33
  **Automations and translations are not exceptions to rule 1.** They are *reactions* — a processor
34
34
  or an adapter that wakes up, decides something must change, and **issues a command** to do it. They
35
- never record an event themselves. A reaction box always points at a **command** (in the next
36
- slice), and that command produces the event. If you ever see a translation or automation wired
37
- straight to an event, the model is wrong.
35
+ never record an event themselves. A reaction box always points at a **command in its own slice** —
36
+ the same shape a `ui` already uses in State Change — and that command produces the event. If you
37
+ ever see a translation or automation wired straight to an event, the model is wrong.
38
38
 
39
39
  Events are **immutable past-tense facts** ("Order Placed", "Payment Captured"). They are the
40
40
  spine of the model. Everything else hangs off the events.
@@ -52,8 +52,8 @@ Every slice is exactly one of these. In `em`, each maps to a specific shape (see
52
52
  **UI → Command → Event.** A user (or automation) submits a command; the system validates it
53
53
  against invariants and records one or more events.
54
54
  - **A State Change never travels alone, and it's joined at both ends.** Something must *trigger*
55
- the command — the `ui` it's issued from, or (patterns 3 and 4) the reaction in the slice before
56
- it — and its event needs a read model that projects it. So the unit of work is a State Change
55
+ the command — the `ui` it's issued from, or (patterns 3 and 4) the reaction that triggers it,
56
+ also in this slice — and its event needs a read model that projects it. So the unit of work is a State Change
57
57
  slice *plus* the State View slice that reads its event. Write them together; a command nothing
58
58
  points at is a write nobody can start, an unread event is a write nobody can see, and
59
59
  `em validate` warns on each.
@@ -114,16 +114,17 @@ displays. Read-only; changes no state.
114
114
  expectation?"*
115
115
 
116
116
  ### 3. Automation (Processor pattern)
117
- **Read Model → Processor → (next slice) Command → Event.** The system reacts on its own: a
118
- processor watches a read model (a "to-do list" of work) and **issues a command** — it never
119
- records an event directly.
120
- - `em` shape: **two slices**, then the read slice that consumes the event — three in all:
117
+ **Read Model → Processor → Command → Event, the last three together in one slice.** The system
118
+ reacts on its own: a processor watches a read model (a "to-do list" of work) and **issues a
119
+ command** — it never records an event directly.
120
+ - `em` shape: the read model in the slice before, then the reaction with its command and event —
121
+ plus the read slice that consumes the event — three slices in all:
121
122
  ```em
122
123
  slice "Todo" {
123
124
  view Todo from "..."
124
- processor P
125
125
  }
126
- slice "Do It" { # the triggered command goes in the NEXT slice
126
+ slice "Do It" { # processor, command, and event all share this slice
127
+ processor P from "Todo"
127
128
  command C
128
129
  event E @Context
129
130
  }
@@ -132,9 +133,10 @@ records an event directly.
132
133
  ui Work Board @Persona # ...and every read model needs a consumer
133
134
  }
134
135
  ```
135
- The processor band holds no event; the command in the next slice produces it. Keeping the
136
- triggered command in the same slice as the processor is a validation warning — always split it.
137
- Forgetting the third slice leaves `E` unread, which is also a warning.
136
+ The processor never records the event directly — the command it triggers does, and that event
137
+ happens to live in the processor's own slice now because the command does. A processor with no
138
+ command in its slice (and no explicit arrow to one) is a validation warning: a decision the
139
+ system never acts on. Forgetting the third slice leaves `E` unread, which is also a warning.
138
140
  - **Naming:** name the read model after the pending work — `Payments To Process`,
139
141
  `Orders To Fulfill`, `Pending Approvals` — never after the triggering event. The event is what
140
142
  happened; the view is what's left to do. Reusing the event's name also collides in the shared
@@ -144,10 +146,11 @@ records an event directly.
144
146
  list does the processor watch? What command does it fire? What if it fails or retries?"*
145
147
 
146
148
  ### 4. Translation
147
- **Boundary crossing → command → event.** An adapter translates data across a boundary (an external
148
- system, or another bounded context) into the model's own language. Like an automation, a
149
- translation is a *reaction*: it **triggers a command**, never records an event directly. Two
150
- independent questions shape which form it takes — don't conflate them:
149
+ **Boundary crossing → command → event, the reaction and what it triggers together in one slice.**
150
+ An adapter translates data across a boundary (an external system, or another bounded context) into
151
+ the model's own language. Like an automation, a translation is a *reaction*: it **triggers a
152
+ command**, never records an event directly. Two independent questions shape which form it takes —
153
+ don't conflate them:
151
154
  - **Trigger source:** does the input come from outside the model, or from the model's own state
152
155
  pushed back out?
153
156
  - **Durable artifact:** is there a queryable, persisted thing behind the trigger (a queue, topic,
@@ -167,13 +170,14 @@ The `em` shape only tracks the second question — trigger source doesn't change
167
170
  it's scoped to the context/lane whose fact it represents, not by who committed it — the same
168
171
  move as an Anti-Corruption-Layer boundary event in DDD — and stays legitimate as long as it
169
172
  doesn't leak into the model's own domain vocabulary.
170
- - `em` shape: **two slices**, exactly like an automation, plus the read slice for the event:
173
+ - `em` shape: exactly like an automation — the read model (durable-artifact form only) in the
174
+ slice before, then the reaction with its command and event, plus the read slice for the event:
171
175
  ```em
172
176
  slice "Boundary" {
173
177
  view Source from "..." # durable-artifact form only; omit if there's nothing persisted
174
- translation T from "Source"
175
178
  }
176
- slice "Record It" {
179
+ slice "Record It" { # translation, command, and event all share this slice
180
+ translation T from "Source" # omit `from` entirely for the no-durable-artifact form
177
181
  command C
178
182
  event E @Context
179
183
  }
@@ -182,7 +186,7 @@ The `em` shape only tracks the second question — trigger source doesn't change
182
186
  ui Status Screen @Persona # ...and every read model needs a consumer
183
187
  }
184
188
  ```
185
- The translation band never carries an event.
189
+ The translation never records the event directly — the command it triggers does.
186
190
  - Socratic prompts: *"What boundary are we crossing, and which way? What outside system or context
187
191
  feeds us (or do we feed)? In what format? How do we know its data is trustworthy/complete? What
188
192
  internal **command** does it trigger, and what event does that command record?"*
@@ -237,9 +241,9 @@ each view to the events that feed it.
237
241
  ### Step 5 — Swimlanes & Apply the Patterns *(model)*
238
242
  Organize elements into swimlanes: one **persona** row per actor, one **context** (bounded
239
243
  context / aggregate) row per event family. Classify every slice as one of the **4 patterns** and
240
- wire them correctly — especially **split both automations and translations across two slices**
241
- (the reaction in one, the command + event in the next). A translation or automation never records
242
- an event directly; it triggers a command.
244
+ wire them correctly — especially **share the slice between every automation or translation and the
245
+ command it triggers** (the read model it watches, if any, stays in the slice before). A translation
246
+ or automation never records an event directly; it triggers a command.
243
247
  - Prompts: *"Which events belong together as one consistency boundary (aggregate)? Who owns this
244
248
  data? Is this slice a state change, a view, an automation, or a translation?"*
245
249
  - Output: a structurally complete model with swimlanes and pattern-correct slices.
@@ -258,8 +262,9 @@ dedicated `slice` phase writes the full rich spec (see `templates/slice.md`).
258
262
 
259
263
  ### Step 7 — Evaluate Completeness *(model)*
260
264
  Walk the whole model with stakeholders and check for loose ends:
261
- - Every **command** has something that **triggers** it — a `ui` in its slice, or a reaction in the
262
- slice before it. A command nothing points at is a write nobody can start. `em validate` warns.
265
+ - Every **command** has something that **triggers** it — a `ui` in its slice, or the reaction that
266
+ triggers it, also in its slice. A command nothing points at is a write nobody can start.
267
+ `em validate` warns.
263
268
  - Every **command** produces at least one **event**.
264
269
  - Every **view** has at least one source event, **and a consumer** — a `ui` (headless: the `ui`
265
270
  tagged to the API-caller persona), or a reaction watching it. Every *instance* of a repeated
@@ -273,11 +278,13 @@ Walk the whole model with stakeholders and check for loose ends:
273
278
  - Every connection is one of the six legal pairs (`ui → command`, `command → event`,
274
279
  `event → read model`, `read model → ui`, `read model → reaction`, `reaction → command`). No
275
280
  arrow between two instances of one read model.
276
- - Automations **and** translations are split correctly (reaction → command → event, never a
277
- reaction wired straight to an event); translations cover every external input.
278
- - Run `em validate` and resolve all errors and warnings. It now catches illegal `arrow` kind pairs
279
- (error) and unread events (warning), but it still does **not** catch a translation/automation that
280
- emits an event directly — verify the two-slice split by hand.
281
+ - Automations **and** translations are wired correctly (reaction → command → event, all in one
282
+ slice — never a reaction wired straight to an event, and never a reaction with no command at
283
+ all); translations cover every external input.
284
+ - Run `em validate` and resolve all errors and warnings. It catches illegal `arrow` kind pairs
285
+ (error), unread events (warning), and a reaction with no command in its slice (warning) — a
286
+ reaction wired straight to an event with no command anywhere is exactly what that last check
287
+ catches, so a clean `em validate` run does cover this case.
281
288
  - Prompts: *"Is there any event nobody reads — and if the business genuinely never looks at it, why
282
289
  are we recording it? Any command that just happens, with nobody and nothing asking for it? Any
283
290
  screen with no way in or out? Any command that records nothing? Any
@@ -16,11 +16,15 @@ Replace bracketed placeholders; delete guidance comments before finishing.
16
16
 
17
17
  ## Summary
18
18
 
19
- | Surface | Real drift | Model gap | Internal inconsistency | Accepted divergence | Uncertainty |
20
- |---|---|---|---|---|---|
21
- | Structural | {{n}} | {{n}} | — | {{n}} | {{n}} |
22
- | Spec | {{n}} | {{n}} | — | {{n}} | {{n}} |
23
- | Internal | — | — | {{n}} | {{n}} | {{n}} |
19
+ | Surface | Real drift | Model gap | Internal inconsistency | Accepted divergence | Unpropagated delta | Uncertainty |
20
+ |---|---|---|---|---|---|---|
21
+ | Structural | {{n}} | {{n}} | — | {{n}} | {{n}} | {{n}} |
22
+ | Spec | {{n}} | {{n}} | — | {{n}} | {{n}} | {{n}} |
23
+ | Internal | — | — | {{n}} | {{n}} | — | {{n}} |
24
+
25
+ **Unpropagated delta** — a slice re-ratified past its shipped version (`slice.doc.driftSignal:
26
+ "unpropagated-delta"` in `em export --json`): a known state, not a code defect. See
27
+ `reference/conform.md` step 4.
24
28
 
25
29
  {{One or two sentences: overall read — clean, mostly clean with N items, or notably drifted.}}
26
30
 
@@ -32,15 +36,17 @@ Replace bracketed placeholders; delete guidance comments before finishing.
32
36
  ### {{n}}. {{Short finding title}}
33
37
 
34
38
  - **Surface:** {{structural | spec | internal}}
35
- - **Classification:** {{real drift | model gap | internal inconsistency | accepted divergence}}
39
+ - **Classification:** {{real drift | model gap | internal inconsistency | accepted divergence | unpropagated delta}}
36
40
  - **Slice:** {{slice name}}
37
41
  - **Evidence:** {{file path(s) and line/symbol, or the `em diff --json` entry (type + name) —
38
- for accepted divergence, the `divergence "..."` annotation text itself}}
42
+ for accepted divergence, the `divergence "..."` annotation text itself; for unpropagated
43
+ delta, `slice.doc.driftSignal` and `slice.doc.version` from `em export --json`}}
39
44
  - **Claim:** {{what the model/doc says vs. what the code/doc shows — the actual disagreement}}
40
45
  - **Proposed red note:** `issue "conformance: {{text}}"` on {{element}} (slice "{{slice}}")
41
46
  <!-- Omit this line entirely for internal-inconsistency findings with no clear side to flag,
42
- for any accepted-divergence finding (already ratified — don't propose re-ratifying it),
43
- or when the finding doesn't warrant a red note (say why instead). -->
47
+ for any accepted-divergence or unpropagated-delta finding (already ratified, or already
48
+ a known pending-ship state — don't propose re-ratifying either), or when the finding
49
+ doesn't warrant a red note (say why instead). -->
44
50
 
45
51
  ## Scenario / invariant coverage
46
52
 
@@ -18,14 +18,14 @@ Static render: `em render {{model-name}}.em -o {{model-name}}.svg`
18
18
  ## Patterns legend
19
19
  - **State Change** — UI → Command → Event
20
20
  - **State View** — Event(s) → Read Model → UI
21
- - **Automation** — Read Model → Processor → (next slice) Command → Event
22
- - **Translation** — External input (or Read Model) → Translation → (next slice) Command → Event
21
+ - **Automation** — Read Model (slice before) → Processor + Command → Event, together
22
+ - **Translation** — External input (or Read Model, slice before) → Translation + Command → Event, together
23
23
 
24
24
  Between them these are the only legal connections: `ui → command`, `command → event`,
25
25
  `event → read model`, `read model → ui`, `read model → reaction`, `reaction → command`. A command
26
26
  never reaches a read model directly — the event goes between them. Every slice is joined up at
27
- both ends: something triggers each command (the screen it's issued from, or the reaction in the
28
- slice before it), and every event a command records is read by some read model — so each State
27
+ both ends: something triggers each command (the screen it's issued from, or the reaction that
28
+ triggers it, also in this slice), and every event a command records is read by some read model — so each State
29
29
  Change slice is paired with the State View slice that projects its event. A read model repeated
30
30
  along the timeline (`view X again`) shows the same projection at a later point; the instances are
31
31
  never connected to one another.
@@ -34,9 +34,9 @@ never connected to one another.
34
34
  <!-- The canonical slice index — the ONE place slices are enumerated (the state file
35
35
  points here rather than keeping its own copy). Keep it in sync as slice docs are
36
36
  written and as statuses move. -->
37
- | # | Slice | Pattern | Status | Design doc |
38
- |---|-------|---------|--------|------------|
39
- | 1 | {{Slice Name}} | {{Pattern}} | {{none / draft / reviewed / ready-to-implement / implemented}} | [slices/{{slice-name}}.md](slices/{{slice-name}}.md) |
37
+ | # | Slice | Pattern | Status | Implemented in | Design doc |
38
+ |---|-------|---------|--------|----------------|------------|
39
+ | 1 | {{Slice Name}} | {{Pattern}} | {{no doc yet / draft / reviewed / ready-to-implement / implemented}} | {{PR/commit link once implemented, else —}} | [slices/{{slice-name}}.md](slices/{{slice-name}}.md) |
40
40
 
41
41
  ## Status
42
42
  See [`.event-modeling.md`](.event-modeling.md) for current phase, decisions, and open questions.
@@ -4,18 +4,84 @@ linked from the .em model with: note "slices/<slice-name>.md" on the slice's d
4
4
  Fill every section through Socratic questioning. Leave "Open Questions" rather than guessing.
5
5
  Replace the bracketed placeholders; delete guidance comments before finishing.
6
6
 
7
+ The frontmatter below is the canonical, machine-read metadata dialect — `em`'s own parser
8
+ (src/catalog/sliceDoc.ts) reads `status:`, `version:`, `pattern:`, and the lineage keys
9
+ (`split-from:`/`merged-from:`/`superseded-by:`) from it. `pattern` is kebab-case
10
+ (state-change/state-view/automation/translation) even though the skill's prose always says
11
+ "State Change"/"State View"/etc. — the frontmatter value is a machine key, not a display label.
12
+ Older docs using a `- **Status:** ...` bullet line instead of frontmatter still parse (legacy/
13
+ accepted input), but new docs should always use this frontmatter form; `version` and lineage
14
+ have no legacy form — frontmatter-only from day one.
15
+
16
+ `version` is this slice's own ratified-content version — starts at `1`, bumps when a delta is
17
+ ratified — distinct from `schemaVersion`, which versions the frontmatter dialect itself, not
18
+ this slice. When a ratified change lands on an already-`implemented` slice: bump `version`,
19
+ flip `status` back to `ready-to-implement` (it tracks the CURRENT version's implementation
20
+ state — `implementedIn` legitimately keeps naming the PRIOR version's PR until the new version
21
+ ships; that mismatch is an intended drift signal, not a bug), and fill in the `## Delta` section
22
+ below with this hop's change, replacing whatever it held before (it always shows only the latest
23
+ hop — full history lives in git, same-commit-ratification convention). Full grammar — the fixed
24
+ heading, the four operation subsections, why the heading never varies, the replace-not-accumulate
25
+ lifecycle — is documented in docs/slice-doc-schema.md#delta-section-grammar-and-lifecycle; treat
26
+ it the same Socratic way as every other section here, don't generate it mechanically.
27
+
28
+ The three lineage keys only apply when this doc was produced by a split, merge, or rename —
29
+ delete them otherwise; most slices never carry them. Grammar: `<slice-key>@v<N>`, where
30
+ `<slice-key>` is the referenced slice's kebab-case filename stem.
31
+
32
+ Full machine schema — required-vs-optional keys per `status`, value types/enums, the
33
+ unknown-key policy — is documented in docs/slice-doc-schema.md.
34
+
7
35
  The diagram below is generated, not hand-drawn: `em render <model>.em --slice "{{Slice Name}}"
8
36
  -o slices/{{slice-name}}.svg` (kebab-case the slice name to match this doc's own filename).
9
37
  -->
10
38
 
39
+ ---
40
+ schemaVersion: 1
41
+ pattern: {{state-change | state-view | automation | translation}}
42
+ swimlane: {{Persona/Actor}} → {{Context/Aggregate}}
43
+ status: {{draft | reviewed | ready-to-implement | implemented}}
44
+ version: 1
45
+ implementedIn: {{PR/commit link — fill in once status is `implemented`}}
46
+ # Lineage — only when this doc exists because of a split, merge, or rename (delete these three
47
+ # lines otherwise). Grammar: <slice-key>@v<N>. See
48
+ # docs/slice-doc-schema.md#lineage-grammar-and-cardinality.
49
+ # split-from: <slice-key>@v<N>
50
+ # merged-from: <slice-key>@v<N>, <slice-key>@v<N>
51
+ # superseded-by: <slice-key>@v<N>, <slice-key>@v<N>
52
+ ---
11
53
  # Slice: {{Slice Name}}
12
54
 
13
55
  ![Diagram](./{{slice-name}}.svg)
14
56
 
15
- - **Pattern:** {{State Change | State View | Automation | Translation}}
16
- - **Swimlane:** {{Persona/Actor}} → {{Context/Aggregate}}
17
- - **Status:** {{draft | reviewed | ready-to-implement | implemented}}
18
- - **Implemented in:** {{PR/commit link — fill in once status is `implemented`}}
57
+ <!-- Only on re-ratification of an already-`implemented` slice — omit this whole section on a
58
+ slice's first version (v1 has no delta yet). The heading is always the literal `## Delta`,
59
+ never `## Delta: vX → vY` — hop metadata is a display line inside the section instead (see
60
+ docs/slice-doc-schema.md#delta-section-grammar-and-lifecycle for why). Replace this
61
+ section's content wholesale on the next re-ratification — it shows only the latest hop, not
62
+ an accumulating log. Omit any of the four subsections below with no entries this hop; keep
63
+ the remaining ones in this order (Added/Modified/Removed/Renamed). `Renamed` is for a
64
+ requirement/invariant renamed within this slice, not a substitute for the frontmatter
65
+ `split-from`/`merged-from`/`superseded-by` lineage keys above, which record the slice-doc
66
+ itself splitting, merging, or being renamed. -->
67
+ ## Delta
68
+ **v{{X}} → v{{Y}}, ratified {{date}}** — {{one-line summary of the ratified change}}
69
+
70
+ ### Added
71
+ #### Requirement: {{title}} ({{stable ID, e.g. an INV-n from Invariants below}})
72
+ {{requirement text — same voice as an Invariants entry}}
73
+ ##### Scenario: {{name}}
74
+ - **GIVEN** {{...}} **WHEN** {{...}} **THEN** {{...}}
75
+
76
+ ### Modified
77
+ <!-- Same shape as Added — the stable ID names the requirement that changed. -->
78
+
79
+ ### Removed
80
+ #### Requirement: {{title}} ({{stable ID}})
81
+ {{why it was removed}}
82
+
83
+ ### Renamed
84
+ - {{old title}} ({{old ID}}) → {{new title}} ({{new ID}})
19
85
 
20
86
  ## Intent
21
87
  {{Why this slice exists — the user or business goal it serves, in one or two sentences. Note the
@@ -30,7 +96,7 @@ an event directly.}}
30
96
 
31
97
  ## Command / Input
32
98
  <!-- For State Change, and the command half of an Automation or Translation (reactions trigger a
33
- command in the next slice). Omit for pure State View slices. -->
99
+ command in this same slice). Omit for pure State View slices. -->
34
100
  **Command:** `{{Command Name}}`
35
101
 
36
102
  | Field | Type | Required | Rules / Validation |
@@ -40,8 +106,8 @@ an event directly.}}
40
106
  ## Trigger
41
107
  <!-- What issues this slice's command. Required: a command nothing points at is a write nobody
42
108
  can start. Either the screen the user acts on (a `ui` in this slice), or the reaction that
43
- issues it (an automation/processor/translation in the PREVIOUS slice). -->
44
- **Triggered by:** {{screen `X` @Persona | processor `Y` in slice "Z"}}
109
+ issues it (an automation/processor/translation, also in this slice). -->
110
+ **Triggered by:** {{screen `X` @Persona | processor `Y`, also in this slice}}
45
111
 
46
112
  ## Event(s) Emitted
47
113
  <!-- The immutable facts recorded. List each event and its payload. -->
@@ -7,7 +7,7 @@ Keep it current at the end of every working session.
7
7
  # Event Modeling Progress — {{Model Name}}
8
8
 
9
9
  - **Model file:** `{{model-name}}.em`
10
- - **Current phase:** {{extract | discover | model | slice}}
10
+ - **Current phase:** {{discover | extract | model | slice | implement | conform | review | validate}}
11
11
  - **Current step:** {{1–7, see methodology; or extraction round R1–R7}}
12
12
  - **Last updated:** {{YYYY-MM-DD}}
13
13
  - **Last conformance:** {{YYYY-MM-DD @ <target-repo revision> — report: conformance/<date>-report.md | never}}
@@ -30,7 +30,7 @@ Keep it current at the end of every working session.
30
30
  - [ ] R2. Timeline order (as-is narrative, actors/callers, first render)
31
31
  - [ ] R3. Commands / inputs
32
32
  - [ ] R4. Read models / outputs (validate from here)
33
- - [ ] R5. Boundaries & reactions (two-slice splits)
33
+ - [ ] R5. Boundaries & reactions (reaction shares its slice with the command it triggers)
34
34
  - [ ] R6. Gap & TBD reconciliation
35
35
  - [ ] R7. Convergence (render + validate clean, user confirmed as-is)
36
36
 
@@ -50,10 +50,11 @@ Keep it current at the end of every working session.
50
50
 
51
51
  ## Usage log
52
52
  <!-- The team's only usage signal today (see docs/usage-data.md) — cheap and coarse on purpose.
53
- One line per session: phase(s) touched, and validate diagnostic *categories* hit (the rule
54
- name from docs/validation.md's tables, e.g. "read model nothing consumes" — never the full
55
- instance message or any domain content). Append, never edit past entries. -->
56
- - {{YYYY-MM-DD}}: phases: {{discover | extract | model | slice | conform | review | validate | watch, ...}} — validate: {{diagnostic category (docs/usage-data.md#categories), ... | none}}
53
+ One line per session: phase(s) touched, and validate diagnostic *categories* hit (one of
54
+ the exact fixed strings in docs/usage-data.md#categories, e.g. "read model has no
55
+ consumer" — never the full instance message or any domain content). Append, never edit
56
+ past entries. -->
57
+ - {{YYYY-MM-DD}}: phases: {{discover | extract | model | slice | implement | conform | review | validate | watch, ...}} — validate: {{diagnostic category (docs/usage-data.md#categories), ... | none}}
57
58
 
58
59
  ## Open questions / parking lot
59
60
  <!-- Unresolved items to bring back to the user. Never guess these. Metadata is optional and
package/README.md CHANGED
@@ -84,6 +84,7 @@ built this way.
84
84
  |---|---|
85
85
  | [docs/tutorial.md](docs/tutorial.md) | Learn the tool by building a model from scratch |
86
86
  | [docs/workflow.md](docs/workflow.md) | The model lifecycle: specify, gate, hand off, track change, detect drift |
87
+ | [docs/process.md](docs/process.md) | Who does what: where humans are required, where agents work with review |
87
88
  | [docs/patterns.md](docs/patterns.md) | The four Event Modeling patterns and their DSL shapes |
88
89
  | [docs/dsl.md](docs/dsl.md) | Full DSL reference: keywords, `from`, `again`, fields, notes |
89
90
  | [docs/cli.md](docs/cli.md) | Every command and flag |
@@ -1,5 +1,6 @@
1
1
  import { NormalizedModel } from "../model/model.js";
2
2
  import { Grid } from "../layout/grid.js";
3
+ import { RefsResult } from "../model/refs.js";
3
4
  import { Diagnostic } from "../model/validate.js";
4
5
  export interface CatalogModelInput {
5
6
  /** The .em file as given on the command line — used for the doc-discovery path and display. */
@@ -7,6 +8,10 @@ export interface CatalogModelInput {
7
8
  model: NormalizedModel;
8
9
  grid: Grid;
9
10
  dot: string;
11
+ /** Already-computed by the same `compile()` call that produced `model`/`grid` (MIL-91) —
12
+ * never recomputed here, so its ref-collision diagnostics (already in `compile()`'s own
13
+ * `diagnostics`) aren't emitted a second time. */
14
+ refs: RefsResult;
10
15
  }
11
16
  export interface CatalogOptions {
12
17
  outDir: string;
@@ -15,7 +15,6 @@ import { copyFile, mkdir, writeFile } from "node:fs/promises";
15
15
  import { basename, dirname, extname, join } from "node:path";
16
16
  import { layoutDot, composeSvg, writeRendered } from "../render/render.js";
17
17
  import { buildSliceDiagram } from "../render/sliceDiagram.js";
18
- import { computeRefs } from "../emit/json.js";
19
18
  import { dedupe, kebabSlug } from "../util/slug.js";
20
19
  import { classifySlicePattern } from "./classify.js";
21
20
  import { parseSliceDoc } from "./sliceDoc.js";
@@ -29,7 +28,7 @@ export async function buildCatalog(inputs, opts) {
29
28
  const modelSummaries = [];
30
29
  const diagnostics = [];
31
30
  let sliceCount = 0;
32
- for (const { file, model, grid, dot } of inputs) {
31
+ for (const { file, model, grid, dot, refs } of inputs) {
33
32
  const modelKey = dedupe(kebabSlug(basename(file, extname(file))), usedModelKeys, "~");
34
33
  const modelDir = join(outDir, modelKey);
35
34
  const slicesDir = join(modelDir, "slices");
@@ -40,7 +39,6 @@ export async function buildCatalog(inputs, opts) {
40
39
  const raw = await layoutDot(dot);
41
40
  const mainSvg = composeSvg(raw, model, grid, dirname(file), modelDir);
42
41
  await writeRendered(mainSvg, join(modelDir, diagramFile), format);
43
- const refs = computeRefs(model);
44
42
  if (refs.diagnostics.length > 0)
45
43
  diagnostics.push({ file, diagnostics: refs.diagnostics });
46
44
  const sliceSummaries = [];
@@ -1 +1 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/catalog/build.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/catalog/build.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,0EAA0E;AAC1E,4EAA4E;AAC5E,EAAE;AACF,cAAc;AACd,iBAAiB;AACjB,mBAAmB;AACnB,8BAA8B;AAC9B,gBAAgB;AAChB,2BAA2B;AAC3B,2FAA2F;AAE3F,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG7D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,eAAe,EAA4C,MAAM,YAAY,CAAC;AAmCxG,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAA2B,EAC3B,IAAoB;IAEpB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC;IACpC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,qBAAqB,CAAC;IAClD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAE3B,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IACxC,MAAM,cAAc,GAA0B,EAAE,CAAC;IACjD,MAAM,WAAW,GAAkD,EAAE,CAAC;IACtE,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,CAAC;QACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,GAAG,CAAC,CAAC;QACtF,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC3C,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5C,MAAM,WAAW,GAAG,WAAW,MAAM,EAAE,CAAC;QACxC,mFAAmF;QACnF,sFAAsF;QACtF,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;QACtE,MAAM,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC;QAElE,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;YAAE,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3F,MAAM,cAAc,GAA0B,EAAE,CAAC;QAEjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;YAE5C,mFAAmF;YACnF,oFAAoF;YACpF,mFAAmF;YACnF,sFAAsF;YACtF,qFAAqF;YACrF,6EAA6E;YAC7E,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,QAAQ,KAAK,CAAC,CAAC;YACpD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC;YAChD,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAEtF,8EAA8E;YAC9E,+EAA+E;YAC/E,0EAA0E;YAC1E,0EAA0E;YAC1E,8DAA8D;YAC9D,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,QAAQ,MAAM,CAAC,CAAC;YACzE,MAAM,gBAAgB,GAAG,GAAG,QAAQ,MAAM,CAAC;YAC3C,IAAI,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;gBAChC,MAAM,QAAQ,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAC;YACrE,CAAC;iBAAM,CAAC;gBACN,+EAA+E;gBAC/E,8EAA8E;gBAC9E,6EAA6E;gBAC7E,8EAA8E;gBAC9E,4EAA4E;gBAC5E,sEAAsE;gBACtE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,iBAAiB,CAAC,KAAK,EAAE,CAAC,EAAE;oBACxF,cAAc,EAAE,IAAI,CAAC,cAAc;iBACpC,CAAC,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;gBAC3C,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;gBACvF,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;YACvE,CAAC;YAED,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;YAC9C,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAChC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBACpC,IAAI,GAAG;oBAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YACvC,CAAC;YAED,MAAM,IAAI,GAAG,eAAe,CAAC;gBAC3B,SAAS,EAAE,KAAK,CAAC,IAAI;gBACrB,WAAW,EAAE,MAAM,WAAW,EAAE;gBAChC,gBAAgB;gBAChB,KAAK;gBACL,QAAQ;gBACR,OAAO;gBACP,WAAW;gBACX,GAAG;gBACH,eAAe,EAAE,UAAU;aAC5B,CAAC,CAAC;YACH,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,QAAQ,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAEnE,cAAc,CAAC,IAAI,CAAC;gBAClB,GAAG,EAAE,QAAQ;gBACb,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO;gBACP,MAAM,EAAE,GAAG,KAAK,IAAI;gBACpB,MAAM,EAAE,GAAG,EAAE,MAAM,IAAI,IAAI;aAC5B,CAAC,CAAC;YACH,UAAU,EAAE,CAAC;QACf,CAAC;QAED,cAAc,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;IACtG,CAAC;IAED,MAAM,SAAS,GAAG,eAAe,CAAC,cAAc,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjE,MAAM,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IAE/D,OAAO,EAAE,MAAM,EAAE,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;AAC5E,CAAC"}