@milehimikey/em 1.10.0 → 1.11.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 +5 -1
- package/.claude/skills/event-modeling-design/SKILL.md +31 -12
- package/.claude/skills/event-modeling-discover/SKILL.md +1 -1
- package/.claude/skills/event-modeling-implement/SKILL.md +14 -3
- package/.claude/skills/event-modeling-implement/reference/implement.md +73 -6
- package/.claude/skills/event-modeling-review/SKILL.md +14 -3
- package/.claude/skills/event-modeling-shared/reference/em-dsl.md +64 -10
- package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +4 -1
- package/.claude/skills/event-modeling-shared/templates/constitution.md +111 -0
- package/.claude/skills/event-modeling-shared/templates/model-readme.md +2 -2
- package/.claude/skills/event-modeling-shared/templates/slice.md +4 -0
- package/dist/catalog/docJoin.d.ts +8 -0
- package/dist/catalog/docJoin.js +4 -0
- package/dist/catalog/docJoin.js.map +1 -1
- package/dist/catalog/sliceDoc.d.ts +8 -0
- package/dist/catalog/sliceDoc.js +2 -0
- package/dist/catalog/sliceDoc.js.map +1 -1
- package/dist/cli/ledgerCheck.d.ts +72 -0
- package/dist/cli/ledgerCheck.js +122 -1
- package/dist/cli/ledgerCheck.js.map +1 -1
- package/dist/cli/ratify.d.ts +37 -5
- package/dist/cli/ratify.js +106 -9
- package/dist/cli/ratify.js.map +1 -1
- package/dist/cli/reratify.js +14 -5
- package/dist/cli/reratify.js.map +1 -1
- package/dist/cli/review.d.ts +38 -0
- package/dist/cli/review.js +160 -0
- package/dist/cli/review.js.map +1 -0
- package/dist/cli/sliceIndex.d.ts +3 -0
- package/dist/cli/sliceIndex.js +5 -4
- package/dist/cli/sliceIndex.js.map +1 -1
- package/dist/cli/stateFile.d.ts +10 -0
- package/dist/cli/stateFile.js +14 -0
- package/dist/cli/stateFile.js.map +1 -1
- package/dist/cli/status.d.ts +44 -3
- package/dist/cli/status.js +75 -18
- package/dist/cli/status.js.map +1 -1
- package/dist/cli.js +142 -18
- package/dist/cli.js.map +1 -1
- package/dist/emit/freshnessJson.d.ts +1 -1
- package/dist/emit/freshnessJson.js +5 -1
- package/dist/emit/freshnessJson.js.map +1 -1
- package/dist/emit/json.d.ts +22 -1
- package/dist/emit/json.js +33 -2
- package/dist/emit/json.js.map +1 -1
- package/dist/emit/ledgerJson.d.ts +1 -1
- package/dist/emit/ledgerJson.js +6 -1
- package/dist/emit/ledgerJson.js.map +1 -1
- package/dist/emit/queryJson.d.ts +1 -1
- package/dist/emit/queryJson.js +5 -1
- package/dist/emit/queryJson.js.map +1 -1
- package/dist/emit/statusJson.d.ts +1 -1
- package/dist/emit/statusJson.js +5 -1
- package/dist/emit/statusJson.js.map +1 -1
- package/dist/mcp/server.js +10 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/edges.d.ts +18 -3
- package/dist/model/edges.js +34 -0
- package/dist/model/edges.js.map +1 -1
- package/dist/model/model.d.ts +4 -0
- package/dist/model/model.js +1 -0
- package/dist/model/model.js.map +1 -1
- package/dist/model/queryIndex.d.ts +5 -2
- package/dist/model/queryIndex.js +4 -1
- package/dist/model/queryIndex.js.map +1 -1
- package/dist/model/rules.d.ts +19 -0
- package/dist/model/rules.js +19 -0
- package/dist/model/rules.js.map +1 -1
- package/dist/model/validate.js +82 -1
- package/dist/model/validate.js.map +1 -1
- package/dist/parser/ast.d.ts +21 -0
- package/dist/parser/parser.js +96 -32
- package/dist/parser/parser.js.map +1 -1
- package/dist/render/drawEdges.js +7 -0
- package/dist/render/drawEdges.js.map +1 -1
- package/dist/render/drawNotes.d.ts +13 -3
- package/dist/render/drawNotes.js +96 -20
- package/dist/render/drawNotes.js.map +1 -1
- package/dist/render/render.js +6 -5
- package/dist/render/render.js.map +1 -1
- package/dist/templates.d.ts +14 -1
- package/dist/templates.js +134 -5
- package/dist/templates.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
The implementation constitution: the house rules an implementing agent follows on EVERY slice —
|
|
3
|
+
stack, code style, testing norms, NFR baselines, review norms. It answers "how do we build things
|
|
4
|
+
here" once, so no slice doc has to repeat it and no agent has to invent it. Slice docs say WHAT to
|
|
5
|
+
build; this says HOW it gets built here.
|
|
6
|
+
|
|
7
|
+
Where this document lives:
|
|
8
|
+
- No SDD tool: `constitution.md` beside the model — `em scaffold` writes it there.
|
|
9
|
+
- spec-kit project (a `.specify/` directory exists anywhere above the model): the document IS
|
|
10
|
+
`.specify/memory/constitution.md`. em writes no second copy; the sections below merge into
|
|
11
|
+
that file under these same headings, never overwriting text already there, and ratification is
|
|
12
|
+
recorded in spec-kit's own `**Ratified**:` footer line instead of the frontmatter below.
|
|
13
|
+
|
|
14
|
+
How it gets filled: not by an agent guessing. Each section opens with the question a short
|
|
15
|
+
facilitated conversation asks before the first slice is implemented — the procedure is "Before the
|
|
16
|
+
first slice: the constitution" in the `event-modeling-implement` skill's `reference/implement.md`
|
|
17
|
+
(`em contract` prints it). Replace each `{{...}}` block with the real answers; delete the guidance
|
|
18
|
+
comments and any row that doesn't apply.
|
|
19
|
+
|
|
20
|
+
Ratification: `ratifiedBy:`/`ratifiedOn:` are the same identity discipline slice docs use — a
|
|
21
|
+
NAMED human and an ISO date, hand-filled at sign-off (no `em` command writes this file).
|
|
22
|
+
**A constitution with an empty `ratifiedBy:` is a draft**: an implementing agent treats it as
|
|
23
|
+
unratified, says so, and does not proceed on unilateral style or stack decisions for a first slice.
|
|
24
|
+
|
|
25
|
+
`em status` reports this document as present or absent per model — existence only. em never reads
|
|
26
|
+
or validates its content, and nothing here is machine-parsed.
|
|
27
|
+
-->
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
schemaVersion: 1
|
|
31
|
+
ratifiedBy:
|
|
32
|
+
ratifiedOn:
|
|
33
|
+
---
|
|
34
|
+
# {{Project Name}} — implementation constitution
|
|
35
|
+
|
|
36
|
+
The house rules for how implementation happens in this project. They bound every "purely
|
|
37
|
+
technical choice" an implementing agent would otherwise make alone.
|
|
38
|
+
|
|
39
|
+
## Stack and architectural shape
|
|
40
|
+
|
|
41
|
+
> **What do we build on, what shape does the code take, and which implementation skill or
|
|
42
|
+
> approach does each slice pattern route to?**
|
|
43
|
+
|
|
44
|
+
- **Languages / runtimes:** {{e.g. Kotlin 2.x on JVM 21; TypeScript 5 on Node 24}}
|
|
45
|
+
- **Frameworks / platform:** {{web framework, persistence, messaging, build tool}}
|
|
46
|
+
- **Architectural pattern:** {{e.g. event-sourced CQRS with vertical slices; layered service over
|
|
47
|
+
a relational store; functional core / imperative shell}}
|
|
48
|
+
- **Where a slice's code lives:** {{one package per slice, per context, ...}}
|
|
49
|
+
|
|
50
|
+
Routing — which implementation skill or approach each of the four slice patterns uses:
|
|
51
|
+
|
|
52
|
+
| Pattern | Skill / approach |
|
|
53
|
+
|---|---|
|
|
54
|
+
| State Change | {{e.g. the `axon-*` skill set — axon-entity-patterns, then axon-entity-testing}} |
|
|
55
|
+
| State View | {{e.g. the `axon-*` skill set — axon-projection-patterns, then axon-projection-testing}} |
|
|
56
|
+
| Automation | {{e.g. the `axon-*` skill set — axon-policy-patterns, then axon-policy-testing}} |
|
|
57
|
+
| Translation | {{e.g. the `axon-*` skill set — axon-translation-patterns}} |
|
|
58
|
+
|
|
59
|
+
An agent implementing a slice reads the doc's `pattern:` frontmatter and follows that row — this
|
|
60
|
+
table is the only routing rule.
|
|
61
|
+
|
|
62
|
+
## Code style
|
|
63
|
+
|
|
64
|
+
> **What does "idiomatic" mean in this codebase — formatting, naming, module layout?**
|
|
65
|
+
|
|
66
|
+
- **Formatter / linter:** {{the tool and the command that runs it — never hand-format against it}}
|
|
67
|
+
- **Naming:** {{commands, events, handlers, files, test names}}
|
|
68
|
+
- **Module layout:** {{what lives in which file/package, and what may not import what}}
|
|
69
|
+
- **Idiomatic here means:** {{the two or three habits a new contributor most often gets wrong}}
|
|
70
|
+
|
|
71
|
+
## Testing norms
|
|
72
|
+
|
|
73
|
+
> **What must be tested for each slice pattern, where do those tests live, and how are they named
|
|
74
|
+
> so `em coverage` can trace invariant IDs?**
|
|
75
|
+
|
|
76
|
+
- **Levels required per pattern:** {{e.g. State Change — decider unit tests plus a
|
|
77
|
+
given/when/then fixture test; State View — projection tests; Automation / Translation —
|
|
78
|
+
reaction tests, including a negative case}}
|
|
79
|
+
- **Invariant tests:** {{where they live}} — every `INV-<MNEMONIC>-n` in a slice doc needs at least
|
|
80
|
+
one test **citing that exact ID** in its name or a comment, so
|
|
81
|
+
`em coverage <model>.em --tests <dir>` can trace it.
|
|
82
|
+
- **Scenario tests:** {{where they live}} — one per `## Scenarios (Given / When / Then)` entry,
|
|
83
|
+
with rejection scenarios asserting the doc's named rejection reason.
|
|
84
|
+
- **Test naming convention:** {{the exact pattern, e.g. `INV-ORD-3: rejects a second submit`}}
|
|
85
|
+
- **What "green" means:** {{the command CI runs}}
|
|
86
|
+
|
|
87
|
+
## NFR baselines
|
|
88
|
+
|
|
89
|
+
> **What standing non-functional defaults does every slice inherit — authz, PII, performance,
|
|
90
|
+
> observability?**
|
|
91
|
+
|
|
92
|
+
- **Authorization model:** {{who may issue which commands, how it's enforced, and where}}
|
|
93
|
+
- **PII / data handling:** {{what is sensitive, what may be logged, retention}}
|
|
94
|
+
- **Performance defaults:** {{latency / throughput budgets that apply unless a slice says otherwise}}
|
|
95
|
+
- **Observability:** {{logging, metrics, tracing every slice is expected to emit}}
|
|
96
|
+
|
|
97
|
+
A slice doc's own `## Non-Functional Requirements` section overrides these for that slice; where
|
|
98
|
+
it is silent, these apply.
|
|
99
|
+
|
|
100
|
+
## Review and merge norms
|
|
101
|
+
|
|
102
|
+
> **Who reviews an implementation PR, what blocks a merge, and how does the slice doc's status
|
|
103
|
+
> flip fit in?**
|
|
104
|
+
|
|
105
|
+
- **Reviewers:** {{who — a team, a CODEOWNERS rule, the slice's ratifier}}
|
|
106
|
+
- **What blocks a merge:** {{e.g. a failing suite, an uncovered invariant, a gap that belongs back
|
|
107
|
+
at the model}}
|
|
108
|
+
- **Branch / commit conventions:** {{...}}
|
|
109
|
+
- **At merge:** run `em slice mark-implemented <model>.em <slice-key> <pr-url>` — the one edit an
|
|
110
|
+
implementing agent makes to a ratified slice doc, run by {{the PR author | CI}}. Never bump
|
|
111
|
+
`version:`; that moves only when a delta is ratified.
|
|
@@ -37,8 +37,8 @@ never connected to one another.
|
|
|
37
37
|
`em slice index {{model-name}}.em` to (re)write the table below from the model and its
|
|
38
38
|
slice docs; never hand-edit between the markers. -->
|
|
39
39
|
<!-- GENERATED:slices:start -->
|
|
40
|
-
| # | Slice | Pattern | Status | Ratified by | Owner | Tracking | Implemented in | Design doc |
|
|
41
|
-
|
|
40
|
+
| # | Slice | Pattern | Status | Reviewed by | Ratified by | Owner | Tracking | Implemented in | Design doc |
|
|
41
|
+
|---|-------|---------|--------|-------------|-------------|-------|----------|----------------|------------|
|
|
42
42
|
<!-- GENERATED:slices:end -->
|
|
43
43
|
|
|
44
44
|
## Status
|
|
@@ -157,6 +157,10 @@ an event directly.}}
|
|
|
157
157
|
instance of a repeated view needs its own consumer, not just the last one. -->
|
|
158
158
|
- **Freshness / consistency expectation:** {{real-time | eventual | on-demand}}
|
|
159
159
|
|
|
160
|
+
| Field | Type | Source / Notes |
|
|
161
|
+
|-------|------|-----------------|
|
|
162
|
+
| {{field}} | {{Type}} | {{which event field it's copied from, or `Derived: <plain-language rule>` for a value computed from which events have landed (a status stepping through states, a computed rank, a flag two events can flip) — a field written as `Derived:` here should ALSO carry the `derived` marker (bare `derived`, or `derived from "Event A", "Event B"` naming the events the rule depends on) on the view's field in the `.em`, so `em export`/the model know the field exists too, not just this doc (docs/dsl.md#derived-fields)}} |
|
|
163
|
+
|
|
160
164
|
## Invariants / Business Rules
|
|
161
165
|
<!-- What must ALWAYS hold. Give each a stable ID so tests and code can reference it:
|
|
162
166
|
`INV-<MNEMONIC>-<n>`, where `<MNEMONIC>` is a short (2-4 letter/digit), slice-unique
|
|
@@ -49,6 +49,14 @@ export interface SliceDocExport {
|
|
|
49
49
|
* `version` above from the same doc parse — a finding built from `driftSignal` should always
|
|
50
50
|
* cite `version` alongside it, never cache one without the other. */
|
|
51
51
|
driftSignal: DriftSignalKind | null;
|
|
52
|
+
/** MIL-201: who recorded the review session this doc passed through (frontmatter
|
|
53
|
+
* `reviewedBy:`), written only by `em slice review` — null when absent (a doc that hasn't
|
|
54
|
+
* reached the review gate, one predating this feature, or one reviewed by hand). The review
|
|
55
|
+
* gate is the FIRST of the two human gates; `ratifiedBy` below records the second. */
|
|
56
|
+
reviewedBy: string | null;
|
|
57
|
+
/** MIL-201: when this doc was reviewed (frontmatter `reviewedOn:`, `YYYY-MM-DD`), written only
|
|
58
|
+
* by `em slice review` — null when absent, same as `reviewedBy`. */
|
|
59
|
+
reviewedOn: string | null;
|
|
52
60
|
/** MIL-165: who ratified this doc's current `status`/`version` (frontmatter `ratifiedBy:`),
|
|
53
61
|
* written only by `em slice ratify` — null when absent (a doc predating this feature, or
|
|
54
62
|
* ratified by hand before it existed). */
|
package/dist/catalog/docJoin.js
CHANGED
|
@@ -66,6 +66,8 @@ const EMPTY_CONTENT = {
|
|
|
66
66
|
mergedFrom: [],
|
|
67
67
|
supersededBy: [],
|
|
68
68
|
driftSignal: null,
|
|
69
|
+
reviewedBy: null,
|
|
70
|
+
reviewedOn: null,
|
|
69
71
|
ratifiedBy: null,
|
|
70
72
|
ratifiedOn: null,
|
|
71
73
|
owner: null,
|
|
@@ -154,6 +156,8 @@ function foundDoc(path, parsed) {
|
|
|
154
156
|
mergedFrom: parsed.mergedFrom,
|
|
155
157
|
supersededBy: parsed.supersededBy,
|
|
156
158
|
driftSignal: classifyImplementationDrift(parsed),
|
|
159
|
+
reviewedBy: parsed.reviewedBy,
|
|
160
|
+
reviewedOn: parsed.reviewedOn,
|
|
157
161
|
ratifiedBy: parsed.ratifiedBy,
|
|
158
162
|
ratifiedOn: parsed.ratifiedOn,
|
|
159
163
|
owner: parsed.owner,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docJoin.js","sourceRoot":"","sources":["../../src/catalog/docJoin.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,4FAA4F;AAC5F,6FAA6F;AAC7F,2FAA2F;AAC3F,4FAA4F;AAC5F,uFAAuF;AACvF,6FAA6F;AAC7F,oFAAoF;AACpF,0FAA0F;AAC1F,4FAA4F;AAC5F,EAAE;AACF,oFAAoF;AACpF,6FAA6F;AAC7F,4FAA4F;AAC5F,8FAA8F;AAC9F,wCAAwC;AACxC,EAAE;AACF,gGAAgG;AAChG,gGAAgG;AAChG,gGAAgG;AAChG,8FAA8F;AAC9F,iGAAiG;AACjG,6FAA6F;AAC7F,+FAA+F;AAC/F,iGAAiG;AACjG,6FAA6F;AAC7F,gGAAgG;AAChG,oDAAoD;AACpD,EAAE;AACF,6FAA6F;AAC7F,qEAAqE;AACrE,2FAA2F;AAC3F,4FAA4F;AAC5F,iGAAiG;AACjG,0FAA0F;AAC1F,oFAAoF;AAIpF,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,2BAA2B,EAAmB,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAsB,MAAM,eAAe,CAAC;AAEzE,0FAA0F;AAC1F,oGAAoG;AACpG,0DAA0D;AAC1D,MAAM,CAAC,MAAM,eAAe,GAAG,2CAA2C,CAAC;AAY3E;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAe,EAAE,YAAoB,EAAE,QAAgB;IAC3F,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAChD,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IACvC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAC9D,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IACpE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;AACrC,CAAC;
|
|
1
|
+
{"version":3,"file":"docJoin.js","sourceRoot":"","sources":["../../src/catalog/docJoin.ts"],"names":[],"mappings":"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"}
|
|
@@ -59,6 +59,14 @@ export interface SliceDoc {
|
|
|
59
59
|
* the noting slice back. Empty array when absent — the common case; a doc always covers its
|
|
60
60
|
* own canonical slice key implicitly and never needs to list it here. */
|
|
61
61
|
covers: string[];
|
|
62
|
+
/** MIL-201: `reviewedBy:` — free text, typically the facilitator's or reviewer's name — or null
|
|
63
|
+
* when absent. Written only by `em slice review` (the FIRST human gate); no legacy bullet-line
|
|
64
|
+
* form. Optional in every status, exactly like `ratifiedBy` — never a required key. */
|
|
65
|
+
reviewedBy: string | null;
|
|
66
|
+
/** MIL-201: `reviewedOn:` — a `YYYY-MM-DD` date string, or null when absent. Written only by
|
|
67
|
+
* `em slice review`; validated by the CLI layer, not re-validated here (this parser stays as
|
|
68
|
+
* lenient about value shape as every other frontmatter field). */
|
|
69
|
+
reviewedOn: string | null;
|
|
62
70
|
/** MIL-165: `ratifiedBy:` — free text, typically a person's name — or null when absent.
|
|
63
71
|
* Written only by `em slice ratify`; no legacy bullet-line form. */
|
|
64
72
|
ratifiedBy: string | null;
|
package/dist/catalog/sliceDoc.js
CHANGED
|
@@ -196,6 +196,8 @@ export function parseSliceDoc(markdown) {
|
|
|
196
196
|
supersededBy: parseSliceRefList(fields.get("superseded-by")),
|
|
197
197
|
implementedIn: fields.get("implementedin") ?? null,
|
|
198
198
|
covers: parseKeyList(fields.get("covers")),
|
|
199
|
+
reviewedBy: fields.get("reviewedby") ?? null,
|
|
200
|
+
reviewedOn: fields.get("reviewedon") ?? null,
|
|
199
201
|
ratifiedBy: fields.get("ratifiedby") ?? null,
|
|
200
202
|
ratifiedOn: fields.get("ratifiedon") ?? null,
|
|
201
203
|
owner: fields.get("owner") ?? null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sliceDoc.js","sourceRoot":"","sources":["../../src/catalog/sliceDoc.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,yDAAyD;AACzD,2EAA2E;AAC3E,2EAA2E;AAC3E,8EAA8E;AAC9E,4EAA4E;AAC5E,8EAA8E;AAC9E,iEAAiE;AACjE,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,6EAA6E;AAC7E,8EAA8E;AAC9E,2EAA2E;AAC3E,yEAAyE;AACzE,EAAE;AACF,oEAAoE;AACpE,wEAAwE;AACxE,kFAAkF;AAClF,8EAA8E;AAC9E,8EAA8E;AAC9E,6EAA6E;AAC7E,EAAE;AACF,8EAA8E;AAC9E,4EAA4E;AAC5E,4EAA4E;AAC5E,8EAA8E;AAC9E,0EAA0E;AAC1E,EAAE;AACF,4EAA4E;AAC5E,4FAA4F;AAC5F,qFAAqF;AACrF,8EAA8E;AAC9E,sFAAsF;AACtF,6CAA6C;AAC7C,EAAE;AACF,6FAA6F;AAC7F,6FAA6F;AAC7F,8FAA8F;AAC9F,iGAAiG;AACjG,qFAAqF;AACrF,EAAE;AACF,6FAA6F;AAC7F,+FAA+F;AAC/F,kGAAkG;AAClG,wFAAwF;AACxF,6FAA6F;AAC7F,+EAA+E;AAC/E,uEAAuE;AAEvE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"sliceDoc.js","sourceRoot":"","sources":["../../src/catalog/sliceDoc.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,8 +14,41 @@ export interface LedgerSkip {
|
|
|
14
14
|
sliceKey: string;
|
|
15
15
|
reason: LedgerSkipReason;
|
|
16
16
|
}
|
|
17
|
+
/** Where a waiver of a `ledger-content-without-version-bump` finding came from (MIL-185): the
|
|
18
|
+
* repeatable `--waive <slice-key>` flag on a manual run, or an `Em-Ledger-Waive: <slice-key>`
|
|
19
|
+
* git trailer found on a commit in the checked range during a CI run. The trailer variant
|
|
20
|
+
* carries the exact commit that declared it — see `readLedgerWaiverTrailers` — so the waiver
|
|
21
|
+
* is auditable back to a specific, reviewed change, not just an unattributed flag.
|
|
22
|
+
*/
|
|
23
|
+
export type LedgerWaiveSource = {
|
|
24
|
+
source: "flag";
|
|
25
|
+
} | {
|
|
26
|
+
source: "trailer";
|
|
27
|
+
commit: string;
|
|
28
|
+
};
|
|
29
|
+
/** A `ledger-content-without-version-bump` finding that was excused rather than silenced —
|
|
30
|
+
* still fully reported (text output prints a `waived:` line, JSON lists it under `waived`),
|
|
31
|
+
* just not counted toward the exit code. Only this one finding code is ever waivable: a
|
|
32
|
+
* version regression or a bump-without-content-change is never a "formatting-only" false
|
|
33
|
+
* positive, so waiving either would hide a real defect (docs/cli.md, docs/ci.md). */
|
|
34
|
+
export interface WaivedLedgerFinding extends LedgerFinding {
|
|
35
|
+
waivedBy: LedgerWaiveSource;
|
|
36
|
+
}
|
|
37
|
+
/** A waiver (flag or trailer) that named a slice key with no matching waivable finding — either
|
|
38
|
+
* a typo, a key for a slice with a different (non-waivable) finding, or a slice that's already
|
|
39
|
+
* clean. Not an error: the waiver is simply inert, but silently swallowing it would hide a
|
|
40
|
+
* typo'd `--waive`/trailer from the operator, so it's surfaced as a note (stderr in the CLI,
|
|
41
|
+
* never folded into `findings`/`waived`). */
|
|
42
|
+
export interface UnknownLedgerWaiver {
|
|
43
|
+
sliceKey: string;
|
|
44
|
+
source: LedgerWaiveSource;
|
|
45
|
+
}
|
|
17
46
|
export interface LedgerCheckResult {
|
|
18
47
|
findings: LedgerFinding[];
|
|
48
|
+
/** Findings excused by a waiver (MIL-185) — see `WaivedLedgerFinding`. Always present (`[]`
|
|
49
|
+
* when no waiver applied), so a caller comparing runs before/after MIL-185 sees only this one
|
|
50
|
+
* additive field, never a shape change to `findings`/`skipped`/`checkedCount`. */
|
|
51
|
+
waived: WaivedLedgerFinding[];
|
|
19
52
|
skipped: LedgerSkip[];
|
|
20
53
|
/** Total slice keys considered (the union of both revisions' `slices/*.md` — every key that
|
|
21
54
|
* produced either a finding, a skip, or a clean pass). Lets a caller report "N checked"
|
|
@@ -36,3 +69,42 @@ export interface LedgerCheckResult {
|
|
|
36
69
|
* risking a false negative on a real prose edit.
|
|
37
70
|
*/
|
|
38
71
|
export declare function checkLedger(anchorFile: string, from: string, to: string | null, runGit?: GitRunner): LedgerCheckResult;
|
|
72
|
+
/** One `Em-Ledger-Waive: <slice-key>` trailer found on a commit in the checked range, paired
|
|
73
|
+
* with the commit that declared it. */
|
|
74
|
+
export interface LedgerTrailerWaiver {
|
|
75
|
+
sliceKey: string;
|
|
76
|
+
commit: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* `Em-Ledger-Waive: <slice-key>` trailers on every commit in `from..to` (`to` null means `HEAD`
|
|
80
|
+
* — an uncommitted working-tree change has no commit to carry a trailer, so it can only be
|
|
81
|
+
* waived via `--waive`; see docs/cli.md). Reads the range oldest-first (`--reverse`) so a slice
|
|
82
|
+
* key repeated across several commits attributes to the **first** (earliest) commit that
|
|
83
|
+
* actually declared the waiver, not the most recent — deterministic for a given repo state, and
|
|
84
|
+
* the answer an auditor wants ("who introduced this waiver").
|
|
85
|
+
*
|
|
86
|
+
* Uses `%(trailers:key=Em-Ledger-Waive,valueonly)` (git's own trailer parser — requires the
|
|
87
|
+
* standard blank-line-separated footer block, same convention `git interpret-trailers` expects)
|
|
88
|
+
* rather than regexing commit messages by hand. A range that fails to resolve (unknown
|
|
89
|
+
* revision, `anchorFile` not in a repo) returns `[]` — routine, matching every other
|
|
90
|
+
* `diff-inputs.ts` git call's "missing is not a crash" stance; `checkLedger`'s own calls against
|
|
91
|
+
* the same revisions already surface a real problem with `--from`/`--to` if there is one.
|
|
92
|
+
*/
|
|
93
|
+
export declare function readLedgerWaiverTrailers(anchorFile: string, from: string, to: string | null, runGit?: GitRunner): LedgerTrailerWaiver[];
|
|
94
|
+
/**
|
|
95
|
+
* Split a `checkLedger` result's findings into still-active and waived (MIL-185, R9), given the
|
|
96
|
+
* flag-provided slice keys (repeatable `--waive <slice-key>`) and the trailer waivers read from
|
|
97
|
+
* the commit range (`readLedgerWaiverTrailers`). Pure — no git access, so flag-only and
|
|
98
|
+
* trailer-only waiver logic is testable without faking a git runner.
|
|
99
|
+
*
|
|
100
|
+
* Only a `ledger-content-without-version-bump` finding is ever waivable (`WAIVABLE_LEDGER_CODE`)
|
|
101
|
+
* — a version regression or a bump-without-content-change stays a hard finding regardless of any
|
|
102
|
+
* waiver naming that slice key. A flag waiver takes precedence over a same-key trailer waiver
|
|
103
|
+
* (both excuse the same finding; the flag is the more explicit, in-hand instruction). A waiver
|
|
104
|
+
* that names a slice key with no matching waivable finding is reported via `unknownWaivers`
|
|
105
|
+
* rather than silently dropped — see `UnknownLedgerWaiver`.
|
|
106
|
+
*/
|
|
107
|
+
export declare function applyLedgerWaivers(result: LedgerCheckResult, flagWaivedKeys: string[], trailerWaivers: LedgerTrailerWaiver[]): {
|
|
108
|
+
result: LedgerCheckResult;
|
|
109
|
+
unknownWaivers: UnknownLedgerWaiver[];
|
|
110
|
+
};
|
package/dist/cli/ledgerCheck.js
CHANGED
|
@@ -111,6 +111,127 @@ export function checkLedger(anchorFile, from, to, runGit = realGit) {
|
|
|
111
111
|
: `slice "${sliceKey}": version: bumped (v${oldVersion} -> v${newVersion}) but doc content is unchanged`;
|
|
112
112
|
findings.push({ sliceKey, code, message, oldVersion, newVersion, bodyChanged, lineageChanged: docsLineageChanged });
|
|
113
113
|
}
|
|
114
|
-
return { findings, skipped, checkedCount: keys.length };
|
|
114
|
+
return { findings, waived: [], skipped, checkedCount: keys.length };
|
|
115
|
+
}
|
|
116
|
+
/** The only finding code a waiver may excuse (MIL-185, R9) — see `WaivedLedgerFinding`. */
|
|
117
|
+
const WAIVABLE_LEDGER_CODE = "ledger-content-without-version-bump";
|
|
118
|
+
// `%x00`/`%x01` are git's own pretty-format escapes for those literal bytes — git substitutes
|
|
119
|
+
// them into its OUTPUT, so the argv string handed to spawnSync stays plain ASCII text (an actual
|
|
120
|
+
// embedded NUL byte in an argv string throws in Node's child_process). The output bytes they
|
|
121
|
+
// produce are never valid in a commit hash or trailer value, so they're safe as delimiters when
|
|
122
|
+
// *parsing* `log.stdout` below — same technique as `changelog-git.ts`'s `FS` separator, one step
|
|
123
|
+
// removed because these two also need to round-trip through a `--format` argument first.
|
|
124
|
+
const FORMAT_HASH_SEP = "%x00";
|
|
125
|
+
const FORMAT_RECORD_END = "%x01";
|
|
126
|
+
const HASH_SEP = "\x00";
|
|
127
|
+
const RECORD_END = "\x01";
|
|
128
|
+
/**
|
|
129
|
+
* `Em-Ledger-Waive: <slice-key>` trailers on every commit in `from..to` (`to` null means `HEAD`
|
|
130
|
+
* — an uncommitted working-tree change has no commit to carry a trailer, so it can only be
|
|
131
|
+
* waived via `--waive`; see docs/cli.md). Reads the range oldest-first (`--reverse`) so a slice
|
|
132
|
+
* key repeated across several commits attributes to the **first** (earliest) commit that
|
|
133
|
+
* actually declared the waiver, not the most recent — deterministic for a given repo state, and
|
|
134
|
+
* the answer an auditor wants ("who introduced this waiver").
|
|
135
|
+
*
|
|
136
|
+
* Uses `%(trailers:key=Em-Ledger-Waive,valueonly)` (git's own trailer parser — requires the
|
|
137
|
+
* standard blank-line-separated footer block, same convention `git interpret-trailers` expects)
|
|
138
|
+
* rather than regexing commit messages by hand. A range that fails to resolve (unknown
|
|
139
|
+
* revision, `anchorFile` not in a repo) returns `[]` — routine, matching every other
|
|
140
|
+
* `diff-inputs.ts` git call's "missing is not a crash" stance; `checkLedger`'s own calls against
|
|
141
|
+
* the same revisions already surface a real problem with `--from`/`--to` if there is one.
|
|
142
|
+
*/
|
|
143
|
+
export function readLedgerWaiverTrailers(anchorFile, from, to, runGit = realGit) {
|
|
144
|
+
const toplevel = runGit(["-C", dirname(resolve(anchorFile)), "rev-parse", "--show-toplevel"]);
|
|
145
|
+
if (toplevel.status !== 0)
|
|
146
|
+
return [];
|
|
147
|
+
const repoRoot = toplevel.stdout.trim();
|
|
148
|
+
const range = `${from}..${to ?? "HEAD"}`;
|
|
149
|
+
const log = runGit([
|
|
150
|
+
"-C",
|
|
151
|
+
repoRoot,
|
|
152
|
+
"log",
|
|
153
|
+
"--reverse",
|
|
154
|
+
`--format=%H${FORMAT_HASH_SEP}%(trailers:key=Em-Ledger-Waive,valueonly)${FORMAT_RECORD_END}`,
|
|
155
|
+
range,
|
|
156
|
+
]);
|
|
157
|
+
if (log.status !== 0)
|
|
158
|
+
return [];
|
|
159
|
+
const seen = new Set();
|
|
160
|
+
const waivers = [];
|
|
161
|
+
for (const record of log.stdout.split(RECORD_END)) {
|
|
162
|
+
const body = record.startsWith("\n") ? record.slice(1) : record;
|
|
163
|
+
if (!body.trim())
|
|
164
|
+
continue;
|
|
165
|
+
const sepIndex = body.indexOf(HASH_SEP);
|
|
166
|
+
if (sepIndex === -1)
|
|
167
|
+
continue;
|
|
168
|
+
const commit = body.slice(0, sepIndex);
|
|
169
|
+
const values = body
|
|
170
|
+
.slice(sepIndex + 1)
|
|
171
|
+
.split("\n")
|
|
172
|
+
.map((v) => v.trim())
|
|
173
|
+
.filter((v) => v.length > 0);
|
|
174
|
+
for (const sliceKey of values) {
|
|
175
|
+
if (seen.has(sliceKey))
|
|
176
|
+
continue; // keep only the first (earliest, --reverse) commit
|
|
177
|
+
seen.add(sliceKey);
|
|
178
|
+
waivers.push({ sliceKey, commit });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return waivers;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Split a `checkLedger` result's findings into still-active and waived (MIL-185, R9), given the
|
|
185
|
+
* flag-provided slice keys (repeatable `--waive <slice-key>`) and the trailer waivers read from
|
|
186
|
+
* the commit range (`readLedgerWaiverTrailers`). Pure — no git access, so flag-only and
|
|
187
|
+
* trailer-only waiver logic is testable without faking a git runner.
|
|
188
|
+
*
|
|
189
|
+
* Only a `ledger-content-without-version-bump` finding is ever waivable (`WAIVABLE_LEDGER_CODE`)
|
|
190
|
+
* — a version regression or a bump-without-content-change stays a hard finding regardless of any
|
|
191
|
+
* waiver naming that slice key. A flag waiver takes precedence over a same-key trailer waiver
|
|
192
|
+
* (both excuse the same finding; the flag is the more explicit, in-hand instruction). A waiver
|
|
193
|
+
* that names a slice key with no matching waivable finding is reported via `unknownWaivers`
|
|
194
|
+
* rather than silently dropped — see `UnknownLedgerWaiver`.
|
|
195
|
+
*/
|
|
196
|
+
export function applyLedgerWaivers(result, flagWaivedKeys, trailerWaivers) {
|
|
197
|
+
const waivableBySliceKey = new Map();
|
|
198
|
+
for (const finding of result.findings) {
|
|
199
|
+
if (finding.code === WAIVABLE_LEDGER_CODE)
|
|
200
|
+
waivableBySliceKey.set(finding.sliceKey, finding);
|
|
201
|
+
}
|
|
202
|
+
const waivedSliceKeys = new Set();
|
|
203
|
+
const waived = [...result.waived];
|
|
204
|
+
const unknownWaivers = [];
|
|
205
|
+
const seenFlagKeys = new Set();
|
|
206
|
+
for (const sliceKey of flagWaivedKeys) {
|
|
207
|
+
if (seenFlagKeys.has(sliceKey))
|
|
208
|
+
continue;
|
|
209
|
+
seenFlagKeys.add(sliceKey);
|
|
210
|
+
const finding = waivableBySliceKey.get(sliceKey);
|
|
211
|
+
const source = { source: "flag" };
|
|
212
|
+
if (finding) {
|
|
213
|
+
waived.push({ ...finding, waivedBy: source });
|
|
214
|
+
waivedSliceKeys.add(sliceKey);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
unknownWaivers.push({ sliceKey, source });
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
for (const trailer of trailerWaivers) {
|
|
221
|
+
if (waivedSliceKeys.has(trailer.sliceKey))
|
|
222
|
+
continue; // already waived by a flag entry
|
|
223
|
+
const finding = waivableBySliceKey.get(trailer.sliceKey);
|
|
224
|
+
const source = { source: "trailer", commit: trailer.commit };
|
|
225
|
+
if (finding) {
|
|
226
|
+
waived.push({ ...finding, waivedBy: source });
|
|
227
|
+
waivedSliceKeys.add(trailer.sliceKey);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
unknownWaivers.push({ sliceKey: trailer.sliceKey, source });
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
waived.sort((a, b) => a.sliceKey.localeCompare(b.sliceKey));
|
|
234
|
+
const findings = result.findings.filter((f) => !waivedSliceKeys.has(f.sliceKey));
|
|
235
|
+
return { result: { ...result, findings, waived }, unknownWaivers };
|
|
115
236
|
}
|
|
116
237
|
//# sourceMappingURL=ledgerCheck.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ledgerCheck.js","sourceRoot":"","sources":["../../src/cli/ledgerCheck.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,+FAA+F;AAC/F,8FAA8F;AAC9F,6FAA6F;AAC7F,yFAAyF;AACzF,+FAA+F;AAC/F,8FAA8F;AAC9F,EAAE;AACF,+FAA+F;AAC/F,4EAA4E;AAC5E,4FAA4F;AAC5F,kCAAkC;AAElC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAsB,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAa,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ledgerCheck.js","sourceRoot":"","sources":["../../src/cli/ledgerCheck.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/ratify.d.ts
CHANGED
|
@@ -1,13 +1,36 @@
|
|
|
1
1
|
import { NormalizedModel } from "../model/model.js";
|
|
2
2
|
import { RefsResult } from "../model/refs.js";
|
|
3
3
|
/** The status this command flips a slice doc to — the handoff gate
|
|
4
|
-
* (docs/process.md#
|
|
5
|
-
* or deferred, ready for an implementing agent or engineer to pick up. */
|
|
4
|
+
* (docs/process.md#the-slice-lifecycle-gates): contracts/invariants agreed, open questions
|
|
5
|
+
* resolved or deferred, ready for an implementing agent or engineer to pick up. */
|
|
6
6
|
export declare const RATIFIED_STATUS = "ready-to-implement";
|
|
7
|
+
/** One upstream producing slice (in timeline order earlier than the slice being ratified) whose
|
|
8
|
+
* doc hasn't reached `ready-to-implement`/`implemented` yet. `status` is the doc's own status
|
|
9
|
+
* string, or the literal `"no doc"` when no doc is bound/found for that slice at all. */
|
|
10
|
+
export interface UpstreamUnratifiedSlice {
|
|
11
|
+
sliceKey: string;
|
|
12
|
+
status: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* MIL-198 (ruling R5): for every element in the `sliceKey` slice, walks the query index's `in`
|
|
16
|
+
* adjacency one hop to find producing elements that live in OTHER slices (a producer in the SAME
|
|
17
|
+
* slice isn't a cross-slice dependency), dedupes by upstream slice, and reports every upstream
|
|
18
|
+
* slice whose doc status isn't `ready-to-implement`/`implemented` — sorted by the upstream
|
|
19
|
+
* slice's position on the timeline (`Slice.index`), so the advisory itself reads in the order the
|
|
20
|
+
* team should catch up in. Advisory data only: never refuses, callers decide whether/how to print
|
|
21
|
+
* it. An unknown `sliceKey` (shouldn't happen — the caller already resolved it) yields `[]`
|
|
22
|
+
* rather than throwing.
|
|
23
|
+
*/
|
|
24
|
+
export declare function upstreamUnratifiedSlices(model: NormalizedModel, refs: RefsResult, baseDir: string, sliceKey: string): UpstreamUnratifiedSlice[];
|
|
7
25
|
export type ApplyRatifyResult = {
|
|
8
26
|
ok: true;
|
|
9
27
|
content: string;
|
|
10
28
|
changed: boolean;
|
|
29
|
+
/** The doc's status BEFORE the edit, when `--skip-review` is what let this ratification
|
|
30
|
+
* through (i.e. the review gate would otherwise have refused) — `null` whenever the gate
|
|
31
|
+
* passed on its own merits, so the caller prints the skip notice exactly when the flag
|
|
32
|
+
* actually did something. */
|
|
33
|
+
skippedReviewFrom: string | null;
|
|
11
34
|
} | {
|
|
12
35
|
ok: false;
|
|
13
36
|
message: string;
|
|
@@ -22,13 +45,22 @@ export type ApplyRatifyResult = {
|
|
|
22
45
|
* such refusal when `status` isn't already the target: re-ratifying a slice that has since moved
|
|
23
46
|
* on (e.g. back from `implemented` after a version bump — docs/slice-doc-schema.md#status-under-
|
|
24
47
|
* re-ratification) is the ordinary, expected use of this command, so it always applies cleanly.
|
|
25
|
-
*
|
|
48
|
+
*
|
|
49
|
+
* MIL-201: after that idempotency check, refuses any doc whose status isn't `reviewed` or
|
|
50
|
+
* `ready-to-implement` unless `skipReview` is set — the review gate. `sliceKey` appears only in
|
|
51
|
+
* that refusal message (and in the caller's skip notice); every other refusal here is about the
|
|
52
|
+
* doc's own text. No fs access — the caller reads/writes; see `runRatify` below.
|
|
26
53
|
*/
|
|
27
|
-
export declare function applyRatifyFrontmatter(raw: string, ratifiedBy: string, ratifiedOn: string): ApplyRatifyResult;
|
|
54
|
+
export declare function applyRatifyFrontmatter(raw: string, sliceKey: string, ratifiedBy: string, ratifiedOn: string, skipReview?: boolean): ApplyRatifyResult;
|
|
28
55
|
export type RunRatifyResult = {
|
|
29
56
|
ok: true;
|
|
30
57
|
path: string;
|
|
31
58
|
changed: boolean;
|
|
59
|
+
skippedReviewFrom: string | null;
|
|
60
|
+
/** MIL-198's upstream-timeline advisory — see `upstreamUnratifiedSlices` above. Always
|
|
61
|
+
* computed once the gate has passed (whether or not `--skip-review` is what let it
|
|
62
|
+
* through), never gates the ratification itself. */
|
|
63
|
+
upstreamWarnings: UpstreamUnratifiedSlice[];
|
|
32
64
|
} | {
|
|
33
65
|
ok: false;
|
|
34
66
|
message: string;
|
|
@@ -38,4 +70,4 @@ export type RunRatifyResult = {
|
|
|
38
70
|
* `--slice-ready`/`em export` use (MIL-121 cross-binding included), then reads/applies/writes
|
|
39
71
|
* it. `baseDir` is the `.em` file's directory, same convention every doc/note path in `em` uses.
|
|
40
72
|
*/
|
|
41
|
-
export declare function runRatify(model: NormalizedModel, refs: RefsResult, baseDir: string, sliceKey: string, ratifiedBy: string, ratifiedOn: string): RunRatifyResult;
|
|
73
|
+
export declare function runRatify(model: NormalizedModel, refs: RefsResult, baseDir: string, sliceKey: string, ratifiedBy: string, ratifiedOn: string, skipReview?: boolean): RunRatifyResult;
|