@milehimikey/em 1.9.1 → 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 +110 -11
- 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/README.md +8 -1
- 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/ciInit.d.ts +10 -3
- package/dist/cli/ciInit.js +22 -14
- package/dist/cli/ciInit.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/systemInputs.d.ts +34 -0
- package/dist/cli/systemInputs.js +129 -0
- package/dist/cli/systemInputs.js.map +1 -0
- package/dist/cli.js +362 -23
- 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 +37 -1
- package/dist/emit/json.js +67 -1
- 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 +6 -0
- package/dist/emit/queryJson.js +33 -0
- package/dist/emit/queryJson.js.map +1 -0
- 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/emit/systemJson.d.ts +8 -0
- package/dist/emit/systemJson.js +38 -0
- package/dist/emit/systemJson.js.map +1 -0
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +195 -9
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/edges.d.ts +28 -1
- package/dist/model/edges.js +77 -15
- package/dist/model/edges.js.map +1 -1
- package/dist/model/model.d.ts +6 -0
- package/dist/model/model.js +2 -0
- package/dist/model/model.js.map +1 -1
- package/dist/model/qualifiedRef.d.ts +47 -0
- package/dist/model/qualifiedRef.js +100 -0
- package/dist/model/qualifiedRef.js.map +1 -0
- package/dist/model/queryIndex.d.ts +53 -0
- package/dist/model/queryIndex.js +114 -0
- package/dist/model/queryIndex.js.map +1 -0
- package/dist/model/rules.d.ts +88 -0
- package/dist/model/rules.js +101 -0
- package/dist/model/rules.js.map +1 -1
- package/dist/model/sliceDocIndex.d.ts +30 -0
- package/dist/model/sliceDocIndex.js +110 -0
- package/dist/model/sliceDocIndex.js.map +1 -0
- package/dist/model/validate.js +85 -11
- package/dist/model/validate.js.map +1 -1
- package/dist/parser/ast.d.ts +25 -0
- package/dist/parser/parser.d.ts +2 -0
- package/dist/parser/parser.js +104 -34
- package/dist/parser/parser.js.map +1 -1
- package/dist/query/format.d.ts +8 -0
- package/dist/query/format.js +80 -0
- package/dist/query/format.js.map +1 -0
- package/dist/query/pipeline.d.ts +17 -0
- package/dist/query/pipeline.js +38 -0
- package/dist/query/pipeline.js.map +1 -0
- package/dist/query/system.d.ts +60 -0
- package/dist/query/system.js +87 -0
- package/dist/query/system.js.map +1 -0
- package/dist/query/verbs.d.ts +100 -0
- package/dist/query/verbs.js +306 -0
- package/dist/query/verbs.js.map +1 -0
- package/dist/render/drawEdges.js +15 -4
- 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/render/sliceDiagram.js +1 -0
- package/dist/render/sliceDiagram.js.map +1 -1
- package/dist/system/manifest.d.ts +45 -0
- package/dist/system/manifest.js +178 -0
- package/dist/system/manifest.js.map +1 -0
- package/dist/system/verify.d.ts +88 -0
- package/dist/system/verify.js +263 -0
- package/dist/system/verify.js.map +1 -0
- package/dist/templates.d.ts +14 -1
- package/dist/templates.js +134 -5
- package/dist/templates.js.map +1 -1
- package/dist/util/slug.js +16 -10
- package/dist/util/slug.js.map +1 -1
- package/package.json +10 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// `em slice review` (MIL-201): gives `status: reviewed` a mechanical path into the slice doc.
|
|
3
|
+
// `reviewed` has been a first-class value in the status enum since the schema was written
|
|
4
|
+
// (docs/slice-doc-schema.md), but nothing ever wrote it — a facilitator who finished walking a
|
|
5
|
+
// slice in a stakeholder review either hand-edited the frontmatter or (the failure this command
|
|
6
|
+
// exists to prevent) reached straight for `em slice ratify` and collapsed two distinct human
|
|
7
|
+
// gates into one. Review is the FIRST gate: the room agreed the slice reads correctly.
|
|
8
|
+
// Ratification is a separate, later, usually multi-person gate — see
|
|
9
|
+
// docs/process.md#the-slice-lifecycle-gates.
|
|
10
|
+
//
|
|
11
|
+
// Deliberately a clone of ratify.ts's mechanics, not a generalization of them: same note-binding
|
|
12
|
+
// resolution (catalog/docJoin.ts's resolveSliceDocJoin), same `--by`/`--on` validation, same
|
|
13
|
+
// surgical index-splice write via ./frontmatterSurgery.js, same idempotent/refuse-to-overwrite
|
|
14
|
+
// discipline. The two commands read as one family precisely because they are the two ends of the
|
|
15
|
+
// same handoff.
|
|
16
|
+
//
|
|
17
|
+
// Status preconditions (R4, docs/cli.md): legal from `draft` (the ordinary case — a slice doc
|
|
18
|
+
// walked in a review session) and from `reviewed` itself (idempotent re-run, or a refusal when a
|
|
19
|
+
// DIFFERENT reviewer/date is already recorded). Refuses from `ready-to-implement`/`implemented`:
|
|
20
|
+
// review applies BEFORE ratification, and a slice that has already shipped is reopened with
|
|
21
|
+
// `em slice reratify`, not reviewed in place.
|
|
22
|
+
//
|
|
23
|
+
// `reviewedBy`/`reviewedOn` are additive, optional frontmatter keys in every status
|
|
24
|
+
// (docs/slice-doc-schema.md) — exactly like `ratifiedBy`/`ratifiedOn`. `em slice ratify` never
|
|
25
|
+
// clears them (the review record stays as provenance for the version it described);
|
|
26
|
+
// `em slice reratify` does clear them alongside `ratifiedBy`/`ratifiedOn`, since neither the old
|
|
27
|
+
// sign-off nor the old review describes the brand-new version.
|
|
28
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
29
|
+
import { join } from "node:path";
|
|
30
|
+
import { resolveSliceDocJoin } from "../catalog/docJoin.js";
|
|
31
|
+
import { fieldLineRegex, locateFrontmatterInner, normalizeFieldValue } from "./frontmatterSurgery.js";
|
|
32
|
+
import { isValidDateString } from "./stateFile.js";
|
|
33
|
+
/** The status this command flips a slice doc to — the review gate
|
|
34
|
+
* (docs/process.md#the-slice-lifecycle-gates): the room walked the slice and every open question
|
|
35
|
+
* it raised was resolved. NOT a handoff to an implementer; that's `em slice ratify`. */
|
|
36
|
+
export const REVIEWED_STATUS = "reviewed";
|
|
37
|
+
/** Statuses `em slice review` refuses to act on: review applies before ratification, so a doc
|
|
38
|
+
* that has already passed the ratification gate (or shipped) is past the point where "the room
|
|
39
|
+
* reviewed it" is a meaningful new fact about THIS version. */
|
|
40
|
+
const POST_REVIEW_STATUSES = ["ready-to-implement", "implemented"];
|
|
41
|
+
/**
|
|
42
|
+
* Pure text transform: flips `status:` to `reviewed` and sets `reviewedBy:`/`reviewedOn:` in
|
|
43
|
+
* `raw`'s frontmatter block. Idempotent (re-applying the same by/on pair once already reviewed is
|
|
44
|
+
* a no-op, `changed: false`, `content` returned byte-identical to `raw`); refuses (`ok: false`)
|
|
45
|
+
* rather than silently overwrite provenance when the doc is already `status: reviewed` with a
|
|
46
|
+
* *different* recorded reviewer/date — mirroring `applyRatifyFrontmatter`'s refusal exactly.
|
|
47
|
+
* Refuses from `ready-to-implement`/`implemented` (see module header). No fs access — the caller
|
|
48
|
+
* reads/writes; see `runReview` below.
|
|
49
|
+
*/
|
|
50
|
+
export function applyReviewFrontmatter(raw, reviewedBy, reviewedOn) {
|
|
51
|
+
const trimmedBy = reviewedBy.trim();
|
|
52
|
+
if (!trimmedBy)
|
|
53
|
+
return { ok: false, message: "a reviewer name is required (--by)" };
|
|
54
|
+
// Same guard, same rationale as ratify's: an embedded \r/\n could splice a multi-line value
|
|
55
|
+
// into the frontmatter and corrupt the fence, while internal spaces are legitimate in a name.
|
|
56
|
+
if (/[\x00-\x1f\x7f]/.test(trimmedBy)) {
|
|
57
|
+
return { ok: false, message: "reviewer name must not contain control characters" };
|
|
58
|
+
}
|
|
59
|
+
if (!isValidDateString(reviewedOn)) {
|
|
60
|
+
return { ok: false, message: `invalid date "${reviewedOn}" — expected YYYY-MM-DD` };
|
|
61
|
+
}
|
|
62
|
+
const range = locateFrontmatterInner(raw);
|
|
63
|
+
if (!range)
|
|
64
|
+
return { ok: false, message: "no frontmatter block found" };
|
|
65
|
+
const inner = raw.slice(range.innerStart, range.innerEnd);
|
|
66
|
+
const statusMatch = fieldLineRegex("status").exec(inner);
|
|
67
|
+
if (!statusMatch)
|
|
68
|
+
return { ok: false, message: "no `status:` field found in frontmatter" };
|
|
69
|
+
const byMatch = fieldLineRegex("reviewedBy").exec(inner);
|
|
70
|
+
const onMatch = fieldLineRegex("reviewedOn").exec(inner);
|
|
71
|
+
const currentStatus = normalizeFieldValue(statusMatch[2])?.toLowerCase() ?? null;
|
|
72
|
+
const currentBy = byMatch ? normalizeFieldValue(byMatch[2]) : null;
|
|
73
|
+
const currentOn = onMatch ? normalizeFieldValue(onMatch[2]) : null;
|
|
74
|
+
if (currentStatus === REVIEWED_STATUS && currentBy !== null && currentOn !== null) {
|
|
75
|
+
if (currentBy === trimmedBy && currentOn === reviewedOn) {
|
|
76
|
+
return { ok: true, content: raw, changed: false }; // idempotent no-op
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
ok: false,
|
|
80
|
+
message: `already reviewed by ${currentBy} on ${currentOn} — refusing to overwrite with ` +
|
|
81
|
+
`${trimmedBy} on ${reviewedOn}`,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
if (currentStatus !== null && POST_REVIEW_STATUSES.includes(currentStatus)) {
|
|
85
|
+
return {
|
|
86
|
+
ok: false,
|
|
87
|
+
message: `doc is \`status: ${currentStatus}\` — review applies before ratification; a shipped ` +
|
|
88
|
+
"slice is reopened with `em slice reratify`",
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
// Match the file's own line-ending style for any freshly-inserted line — same trick
|
|
92
|
+
// markImplemented.ts/ratify.ts use (see ratify.ts for the full rationale).
|
|
93
|
+
const afterStatus = inner.slice(statusMatch.index + statusMatch[0].length);
|
|
94
|
+
const eol = afterStatus.startsWith("\r\n") ? "\r\n" : "\n";
|
|
95
|
+
// Whichever of reviewedBy/reviewedOn have no existing line get folded directly into the status
|
|
96
|
+
// edit's replacement text (inserted right after the new status value) rather than added as
|
|
97
|
+
// separate zero-length "insert" edits — same convention as ratify.ts.
|
|
98
|
+
const missingLines = [];
|
|
99
|
+
if (!byMatch)
|
|
100
|
+
missingLines.push(`reviewedBy: ${trimmedBy}`);
|
|
101
|
+
if (!onMatch)
|
|
102
|
+
missingLines.push(`reviewedOn: ${reviewedOn}`);
|
|
103
|
+
const newStatusText = `${statusMatch[1]}${REVIEWED_STATUS}`;
|
|
104
|
+
const statusNext = missingLines.length > 0 ? `${newStatusText}${eol}${missingLines.join(eol)}` : newStatusText;
|
|
105
|
+
// Apply from the highest index first so an earlier edit's index stays valid — same convention
|
|
106
|
+
// markImplemented.ts/ratify.ts use.
|
|
107
|
+
const edits = [
|
|
108
|
+
{ index: statusMatch.index, oldLen: statusMatch[0].length, next: statusNext },
|
|
109
|
+
];
|
|
110
|
+
if (byMatch)
|
|
111
|
+
edits.push({ index: byMatch.index, oldLen: byMatch[0].length, next: `${byMatch[1]}${trimmedBy}` });
|
|
112
|
+
if (onMatch)
|
|
113
|
+
edits.push({ index: onMatch.index, oldLen: onMatch[0].length, next: `${onMatch[1]}${reviewedOn}` });
|
|
114
|
+
edits.sort((a, b) => b.index - a.index);
|
|
115
|
+
let updatedInner = inner;
|
|
116
|
+
for (const edit of edits) {
|
|
117
|
+
updatedInner = updatedInner.slice(0, edit.index) + edit.next + updatedInner.slice(edit.index + edit.oldLen);
|
|
118
|
+
}
|
|
119
|
+
const content = raw.slice(0, range.innerStart) + updatedInner + raw.slice(range.innerEnd);
|
|
120
|
+
return { ok: true, content, changed: true };
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Resolves `sliceKey` to its bound doc via the same note-binding join `ratify`/`mark-implemented`/
|
|
124
|
+
* `--slice-ready`/`em export` use (MIL-121 cross-binding included), then reads/applies/writes it.
|
|
125
|
+
* `baseDir` is the `.em` file's directory, same convention every doc/note path in `em` uses.
|
|
126
|
+
*/
|
|
127
|
+
export function runReview(model, refs, baseDir, sliceKey, reviewedBy, reviewedOn) {
|
|
128
|
+
const sliceIndex = refs.sliceKeys.indexOf(sliceKey);
|
|
129
|
+
if (sliceIndex === -1) {
|
|
130
|
+
return { ok: false, message: `no slice with export key "${sliceKey}" in this model` };
|
|
131
|
+
}
|
|
132
|
+
const slice = model.slices[sliceIndex];
|
|
133
|
+
const { doc } = resolveSliceDocJoin(slice, sliceKey, baseDir, (id) => refs.refById.get(id));
|
|
134
|
+
if (doc.reason === "no-doc-bound") {
|
|
135
|
+
return {
|
|
136
|
+
ok: false,
|
|
137
|
+
message: `slice "${sliceKey}" has no doc bound via \`note "slices/${sliceKey}.md"\` — bind a slice doc before reviewing it`,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
if (doc.reason === "binding-missing-file") {
|
|
141
|
+
return { ok: false, message: `slice "${sliceKey}" notes "${doc.path}" but no such file exists` };
|
|
142
|
+
}
|
|
143
|
+
if (doc.reason === "frontmatter-invalid") {
|
|
144
|
+
return {
|
|
145
|
+
ok: false,
|
|
146
|
+
message: `slice doc "${doc.path}" has missing or invalid frontmatter — run \`em validate\` for details`,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const absPath = join(baseDir, doc.path);
|
|
150
|
+
const raw = readFileSync(absPath, "utf8");
|
|
151
|
+
const result = applyReviewFrontmatter(raw, reviewedBy, reviewedOn);
|
|
152
|
+
if (!result.ok) {
|
|
153
|
+
return { ok: false, message: `${doc.path}: ${result.message}` };
|
|
154
|
+
}
|
|
155
|
+
if (result.changed) {
|
|
156
|
+
writeFileSync(absPath, result.content, "utf8");
|
|
157
|
+
}
|
|
158
|
+
return { ok: true, path: doc.path, changed: result.changed };
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/cli/review.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/sliceIndex.d.ts
CHANGED
|
@@ -9,6 +9,9 @@ export interface SliceIndexRow {
|
|
|
9
9
|
name: string;
|
|
10
10
|
pattern: string;
|
|
11
11
|
status: string;
|
|
12
|
+
/** MIL-201: the doc's `reviewedBy`, or `—`. Sits between Status and Ratified by so the two
|
|
13
|
+
* human gates read left-to-right in the order they happen. */
|
|
14
|
+
reviewedBy: string;
|
|
12
15
|
ratifiedBy: string;
|
|
13
16
|
owner: string;
|
|
14
17
|
tracking: string;
|
package/dist/cli/sliceIndex.js
CHANGED
|
@@ -16,8 +16,8 @@ import { applyMarker } from "../util/markers.js";
|
|
|
16
16
|
/** The marker name wrapping the Slices table: `<!-- GENERATED:slices:start -->` /
|
|
17
17
|
* `<!-- GENERATED:slices:end -->`, matching templates/model-readme.md. */
|
|
18
18
|
export const SLICE_INDEX_MARKER = "slices";
|
|
19
|
-
const TABLE_HEADER = "| # | Slice | Pattern | Status | Ratified by | Owner | Tracking | Implemented in | Design doc |\n" +
|
|
20
|
-
"
|
|
19
|
+
const TABLE_HEADER = "| # | Slice | Pattern | Status | Reviewed by | Ratified by | Owner | Tracking | Implemented in | Design doc |\n" +
|
|
20
|
+
"|---|-------|---------|--------|-------------|-------------|-------|----------|----------------|------------|";
|
|
21
21
|
/** Escape characters that would break a markdown table cell: `|` (the column separator) and
|
|
22
22
|
* newlines (a slice name is always one line, but a doc's freeform `implementedIn` text isn't
|
|
23
23
|
* guaranteed to be). */
|
|
@@ -53,6 +53,7 @@ export function buildSliceIndexTable(model, refs, baseDir) {
|
|
|
53
53
|
name: slice.name,
|
|
54
54
|
pattern: slicePatternLabel(pattern),
|
|
55
55
|
status: statusCell(doc),
|
|
56
|
+
reviewedBy: doc.reviewedBy ?? "—",
|
|
56
57
|
ratifiedBy: doc.ratifiedBy ?? "—",
|
|
57
58
|
owner: doc.owner ?? "—",
|
|
58
59
|
tracking: doc.tracking ?? "—",
|
|
@@ -61,8 +62,8 @@ export function buildSliceIndexTable(model, refs, baseDir) {
|
|
|
61
62
|
};
|
|
62
63
|
});
|
|
63
64
|
const lines = rows.map((r) => `| ${r.index} | ${escapeCell(r.name)} | ${escapeCell(r.pattern)} | ${escapeCell(r.status)} | ` +
|
|
64
|
-
`${escapeCell(r.
|
|
65
|
-
`${escapeCell(r.implementedIn)} | [${r.docPath}](${r.docPath}) |`);
|
|
65
|
+
`${escapeCell(r.reviewedBy)} | ${escapeCell(r.ratifiedBy)} | ${escapeCell(r.owner)} | ` +
|
|
66
|
+
`${escapeCell(r.tracking)} | ${escapeCell(r.implementedIn)} | [${r.docPath}](${r.docPath}) |`);
|
|
66
67
|
return { markdown: [TABLE_HEADER, ...lines].join("\n"), rows, diagnostics };
|
|
67
68
|
}
|
|
68
69
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sliceIndex.js","sourceRoot":"","sources":["../../src/cli/sliceIndex.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,6FAA6F;AAC7F,6FAA6F;AAC7F,sFAAsF;AACtF,iGAAiG;AACjG,EAAE;AACF,0FAA0F;AAC1F,uFAAuF;AACvF,+FAA+F;AAC/F,sDAAsD;AAEtD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAI1C,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAkB,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;2EAC2E;AAC3E,MAAM,CAAC,MAAM,kBAAkB,GAAG,QAAQ,CAAC;AAE3C,MAAM,YAAY,GAChB,
|
|
1
|
+
{"version":3,"file":"sliceIndex.js","sourceRoot":"","sources":["../../src/cli/sliceIndex.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/stateFile.d.ts
CHANGED
|
@@ -55,6 +55,16 @@ export declare function loadStateFile(dirOrFile: string): LoadResult;
|
|
|
55
55
|
* review:` holds neither `never` nor its documented format — both are the file failing to be
|
|
56
56
|
* the thing resume/conform scoping needs, so both are reported the same way. */
|
|
57
57
|
export declare function parseState(text: string): ParseStateResult;
|
|
58
|
+
/** A state file is shared by every `.em` file in its directory (`.event-modeling.md` has no
|
|
59
|
+
* per-model namespacing), but its `Model file:` bullet names exactly ONE of them — so a
|
|
60
|
+
* sibling file it does NOT describe (the common case: a `conform-scope --seed-asis` scratch
|
|
61
|
+
* copy like `checkout-asis.em` sitting next to `checkout.em`) must not inherit `checkout.em`'s
|
|
62
|
+
* conformance record just because it lives in the same directory. Returns the exact non-fatal
|
|
63
|
+
* message to report when `modelPath` (a parsed state's `modelPath`, already stripped of
|
|
64
|
+
* backticks) names a different file than `file`'s basename; `null` when they agree. THE one
|
|
65
|
+
* check both `em status` (`resolveConformanceEntry`, PR #116/MIL-163) and `em conform-scope`
|
|
66
|
+
* (MIL-179) run before attributing a state file's `Last conformance:` to a given model file. */
|
|
67
|
+
export declare function modelPathMismatch(modelPath: string, file: string): string | null;
|
|
58
68
|
/** `em state set-phase`: rewrite `Current phase:` (and `Current step:` when `step` is given)
|
|
59
69
|
* plus `Last updated:`. `phase` is trusted to already be a validated `Phase` — the CLI layer
|
|
60
70
|
* checks against `PHASES` before calling this so the enum has exactly one home. */
|
package/dist/cli/stateFile.js
CHANGED
|
@@ -122,6 +122,20 @@ export function parseState(text) {
|
|
|
122
122
|
},
|
|
123
123
|
};
|
|
124
124
|
}
|
|
125
|
+
/** A state file is shared by every `.em` file in its directory (`.event-modeling.md` has no
|
|
126
|
+
* per-model namespacing), but its `Model file:` bullet names exactly ONE of them — so a
|
|
127
|
+
* sibling file it does NOT describe (the common case: a `conform-scope --seed-asis` scratch
|
|
128
|
+
* copy like `checkout-asis.em` sitting next to `checkout.em`) must not inherit `checkout.em`'s
|
|
129
|
+
* conformance record just because it lives in the same directory. Returns the exact non-fatal
|
|
130
|
+
* message to report when `modelPath` (a parsed state's `modelPath`, already stripped of
|
|
131
|
+
* backticks) names a different file than `file`'s basename; `null` when they agree. THE one
|
|
132
|
+
* check both `em status` (`resolveConformanceEntry`, PR #116/MIL-163) and `em conform-scope`
|
|
133
|
+
* (MIL-179) run before attributing a state file's `Last conformance:` to a given model file. */
|
|
134
|
+
export function modelPathMismatch(modelPath, file) {
|
|
135
|
+
if (!modelPath || modelPath === basename(file))
|
|
136
|
+
return null;
|
|
137
|
+
return `state file describes "${modelPath}", not "${basename(file)}" — not attributing its conformance record`;
|
|
138
|
+
}
|
|
125
139
|
/** Replace one or more bullet lines in place, in the order given, failing (without writing
|
|
126
140
|
* anything) if any targeted bullet is missing. Every other byte of `text` — including every
|
|
127
141
|
* other bullet, and whatever line ending style the file already used — passes through the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stateFile.js","sourceRoot":"","sources":["../../src/cli/stateFile.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stateFile.js","sourceRoot":"","sources":["../../src/cli/stateFile.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,2EAA2E;AAC3E,+FAA+F;AAC/F,6FAA6F;AAC7F,8FAA8F;AAC9F,6FAA6F;AAC7F,gGAAgG;AAChG,+CAA+C;AAC/C,EAAE;AACF,4FAA4F;AAC5F,6FAA6F;AAC7F,+FAA+F;AAC/F,cAAc;AACd,EAAE;AACF,iGAAiG;AACjG,4FAA4F;AAC5F,qEAAqE;AAErE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE3C,8EAA8E;AAC9E,MAAM,CAAC,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAEpD;;;2FAG2F;AAC3F,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAU,CAAC;AAGvH,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAQ,MAA4B,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,MAAM,GAAG;IACb,SAAS,EAAE,YAAY;IACvB,YAAY,EAAE,eAAe;IAC7B,WAAW,EAAE,cAAc;IAC3B,WAAW,EAAE,cAAc;IAC3B,eAAe,EAAE,kBAAkB;IACnC,qBAAqB,EAAE,yBAAyB;CACxC,CAAC;AAiBX,SAAS,cAAc,CAAC,CAAS;IAC/B,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,4FAA4F;IAC5F,oDAAoD;IACpD,OAAO,IAAI,MAAM,CAAC,eAAe,cAAc,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AAC3E,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,KAAa;IAC9C,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,eAAe,cAAc,CAAC,KAAK,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;IACnF,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAChC,CAAC;AAED;;;oFAGoF;AACpF,MAAM,UAAU,oBAAoB,CAAC,SAAiB;IACpD,OAAO,QAAQ,CAAC,SAAS,CAAC,KAAK,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;AAChG,CAAC;AAID,gEAAgE;AAChE,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC7C,MAAM,IAAI,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAC7C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,8BAA8B,IAAI,EAAE,EAAE,CAAC;IACtE,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,mBAAmB,GAAG,8CAA8C,CAAC;AAC3E,MAAM,eAAe,GAAG,wBAAwB,CAAC;AAEjD;;;iFAGiF;AACjF,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1C,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;;YAC/B,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,2BAA2B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SACrF,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAE9D,MAAM,kBAAkB,GAAG,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACvD,IAAI,eAAe,GAAmC,IAAI,CAAC;IAC3D,IAAI,kBAAkB,KAAK,OAAO,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,mBAAmB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACvD,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,OAAO,EAAE,kGAAkG,kBAAkB,EAAE;aAChI,CAAC;QACJ,CAAC;QACD,eAAe,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,CAAC;IAED,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACxD,IAAI,UAAU,GAAkB,IAAI,CAAC;IACrC,IAAI,aAAa,KAAK,OAAO,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC9C,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,OAAO,EAAE,gFAAgF,aAAa,EAAE;aACzG,CAAC;QACJ,CAAC;QACD,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,OAAO;QACL,EAAE,EAAE,IAAI;QACR,KAAK,EAAE;YACL,SAAS;YACT,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC;YAC/B,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC;YAC7B,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC;YACpC,eAAe;YACf,UAAU;SACX;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;iGAQiG;AACjG,MAAM,UAAU,iBAAiB,CAAC,SAAiB,EAAE,IAAY;IAC/D,IAAI,CAAC,SAAS,IAAI,SAAS,KAAK,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5D,OAAO,yBAAyB,SAAS,WAAW,QAAQ,CAAC,IAAI,CAAC,4CAA4C,CAAC;AACjH,CAAC;AAED;;;uBAGuB;AACvB,SAAS,kBAAkB,CAAC,IAAY,EAAE,OAAgD;IACxF,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,CAAC;QACvC,MAAM,EAAE,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpB,SAAS;QACX,CAAC;QACD,0FAA0F;QAC1F,yFAAyF;QACzF,8EAA8E;QAC9E,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,OAAO,KAAK,OAAO,KAAK,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,2BAA2B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;IAC7G,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC;AAED;;oFAEoF;AACpF,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,KAAY,EAAE,KAAa,EAAE,IAAa;IAC/E,MAAM,OAAO,GAA4C,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACxG,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACjF,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1D,OAAO,kBAAkB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED;;;iBAGiB;AACjB,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,QAAgB,EAAE,MAAc,EAAE,KAAa;IAC1F,MAAM,KAAK,GAAG,GAAG,KAAK,MAAM,QAAQ,cAAc,MAAM,EAAE,CAAC;IAC3D,OAAO,kBAAkB,CAAC,IAAI,EAAE;QAC9B,EAAE,KAAK,EAAE,MAAM,CAAC,eAAe,EAAE,KAAK,EAAE;QACxC,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE;KAC5C,CAAC,CAAC;AACL,CAAC;AAED;;qCAEqC;AACrC,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,IAAY,EAAE,KAAa;IACjE,MAAM,KAAK,GAAG,GAAG,IAAI,gCAAgC,CAAC;IACtD,OAAO,kBAAkB,CAAC,IAAI,EAAE;QAC9B,EAAE,KAAK,EAAE,MAAM,CAAC,qBAAqB,EAAE,KAAK,EAAE;QAC9C,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE;KAC5C,CAAC,CAAC;AACL,CAAC;AAED,MAAM,OAAO,GAAG,2BAA2B,CAAC;AAE5C;;+BAE+B;AAC/B,MAAM,UAAU,iBAAiB,CAAC,CAAS;IACzC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzB,OAAO,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC;AAC5D,CAAC"}
|
package/dist/cli/status.d.ts
CHANGED
|
@@ -91,6 +91,11 @@ export interface ConformanceEntry {
|
|
|
91
91
|
* `resolveConformanceEntry` below): a bare "opted out of computing this" state doesn't occur
|
|
92
92
|
* on the real CLI/MCP call paths, which always supply `sliceDocFacts`. */
|
|
93
93
|
slicePRsBehindHead: number | null;
|
|
94
|
+
/** MIL-202: whether this model's implementation constitution exists, and where it's expected
|
|
95
|
+
* — existence only. `em` never reads or validates the document's content (no LLM, nothing
|
|
96
|
+
* parsed): the whole fact is "is the house-rules document there or not". See
|
|
97
|
+
* `resolveConstitution` for the two-shape resolution rule. */
|
|
98
|
+
constitution: ConstitutionEntry;
|
|
94
99
|
/** Set when the state file exists and parses, but git couldn't answer commits-behind-HEAD or
|
|
95
100
|
* slice-PRs-behind-HEAD (not a git repo, unknown revision, ...) — reported per-model rather
|
|
96
101
|
* than aborting the whole rollup, since `em status` is a soft report, not a gate. Also carries
|
|
@@ -98,6 +103,37 @@ export interface ConformanceEntry {
|
|
|
98
103
|
* treatment. */
|
|
99
104
|
error: string | null;
|
|
100
105
|
}
|
|
106
|
+
/** Where the project's implementation constitution is, and whether it's there. `path` is always
|
|
107
|
+
* the EXPECTED location — set whether or not the file exists — expressed **relative to the
|
|
108
|
+
* entry's own `modelDir`**, always with `/` separators, so the JSON document stays
|
|
109
|
+
* machine-independent (never an absolute path, never a Windows separator). `join(modelDir,
|
|
110
|
+
* path)` reconstructs the real location. Typed `string | null` for the ruling's shape; on every
|
|
111
|
+
* real call path (`resolveConstitution` below) it is non-null, since the expected location is
|
|
112
|
+
* always computable from `modelDir` alone. */
|
|
113
|
+
export interface ConstitutionEntry {
|
|
114
|
+
present: boolean;
|
|
115
|
+
path: string | null;
|
|
116
|
+
}
|
|
117
|
+
/** Walk up from `startDir` looking for a `.specify/` directory — the same "is this a spec-kit
|
|
118
|
+
* project, and where is its root" walk `em-sdd-bridge`'s `findRepoRoot` does (and spec-kit's own
|
|
119
|
+
* `find_specify_root`). Returns the directory CONTAINING `.specify/`, or null at the filesystem
|
|
120
|
+
* root. Directory existence only; nothing inside `.specify/` is read. */
|
|
121
|
+
export declare function findSpecifyRoot(startDir: string): string | null;
|
|
122
|
+
/**
|
|
123
|
+
* Resolve one model's implementation constitution (MIL-202). Two project shapes, one document —
|
|
124
|
+
* em never writes or expects a second copy:
|
|
125
|
+
*
|
|
126
|
+
* - **spec-kit project** (a `.specify/` directory exists at or above `modelDir`): the document
|
|
127
|
+
* IS `<root>/.specify/memory/constitution.md`, spec-kit's own slot. em defers to it.
|
|
128
|
+
* - **anything else**: `<modelDir>/constitution.md`, beside the model — what `em scaffold`
|
|
129
|
+
* writes.
|
|
130
|
+
*
|
|
131
|
+
* Existence only: this never opens the file, so a blank stock template and a fully answered,
|
|
132
|
+
* ratified constitution are indistinguishable here by design (content judgment is a human's, and
|
|
133
|
+
* `em`'s core stays deterministic and LLM-free). The advisory "is it still an unfilled template"
|
|
134
|
+
* check belongs to the SDD bridge, not here.
|
|
135
|
+
*/
|
|
136
|
+
export declare function resolveConstitution(modelDir: string): ConstitutionEntry;
|
|
101
137
|
/**
|
|
102
138
|
* `git rev-list --count <revision>..HEAD` in `repo` (any directory inside it, not necessarily
|
|
103
139
|
* its root — same "anchor dir, resolve toplevel" convention `conformScope.ts`'s
|
|
@@ -142,9 +178,10 @@ export declare function resolveSlicePRsBehindHead(repo: string, revision: string
|
|
|
142
178
|
* per-model namespacing), but its `Model file:` bullet names exactly ONE of them — so a sibling
|
|
143
179
|
* file it does NOT describe (the common case: a `conform-scope --seed-asis` scratch copy like
|
|
144
180
|
* `checkout-asis.em` sitting next to `checkout.em`) must not inherit `checkout.em`'s conformance
|
|
145
|
-
* record just because it lives in the same directory.
|
|
146
|
-
*
|
|
147
|
-
* channel a git failure uses)
|
|
181
|
+
* record just because it lives in the same directory. `stateFile.ts`'s `modelPathMismatch` (the
|
|
182
|
+
* one check both this function and `em conform-scope`, MIL-179, run) reports that case: the
|
|
183
|
+
* record comes back unattributed (via `error`, the same non-fatal channel a git failure uses)
|
|
184
|
+
* rather than silently misattributed.
|
|
148
185
|
*/
|
|
149
186
|
export declare function resolveConformanceEntry(file: string, repoOverride: string | undefined, sliceDocFacts: SliceDocFacts[], runGit?: GitRunner): ConformanceEntry;
|
|
150
187
|
export interface StatusSliceCounts {
|
|
@@ -238,6 +275,10 @@ export declare function aggregateInvariantTotals(testsDir: string, reports: Cove
|
|
|
238
275
|
/** Exported for `em freshness` (freshness.ts, MIL-164) — the standalone surface for exactly
|
|
239
276
|
* this one clause, without pulling in the rest of `em status`'s rollup. */
|
|
240
277
|
export declare function formatConformancePart(entry: ConformanceEntry): string;
|
|
278
|
+
/** MIL-202: the per-model constitution clause — `present`, or `absent (<expected path>)` with
|
|
279
|
+
* the path the entry already resolved (relative to that model's own directory). Shared by the
|
|
280
|
+
* text and markdown reports so the two can't drift. Existence only; never a content judgment. */
|
|
281
|
+
export declare function formatConstitutionPart(entry: ConformanceEntry): string;
|
|
241
282
|
/** The one-line rollup: `"8/8 implemented · 20/20 invariants covered · 0 open issues · last
|
|
242
283
|
* conformed <rev>, N commits behind HEAD"` (MIL-163's acceptance line). For multiple input
|
|
243
284
|
* models, the conformance clause reports the FIRST file's entry — a single-file invocation is
|
package/dist/cli/status.js
CHANGED
|
@@ -21,11 +21,12 @@
|
|
|
21
21
|
// Deterministic core: no LLM calls, no wall-clock timestamps in the output, byte-stable for the
|
|
22
22
|
// same inputs. Text/markdown/badge are formatting layers over one aggregated StatusReport; the
|
|
23
23
|
// JSON document (emit/statusJson.ts) is a versioned envelope around the exact same object.
|
|
24
|
-
import {
|
|
24
|
+
import { existsSync } from "node:fs";
|
|
25
|
+
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
25
26
|
import { resolveSliceDocJoin } from "../catalog/docJoin.js";
|
|
26
27
|
import { readSliceDoc } from "../catalog/readSliceDoc.js";
|
|
27
28
|
import { realGit } from "./diff-inputs.js";
|
|
28
|
-
import { loadStateFile, parseState } from "./stateFile.js";
|
|
29
|
+
import { loadStateFile, parseState, modelPathMismatch } from "./stateFile.js";
|
|
29
30
|
import { changedPathsSince, buildConformScope } from "./conformScope.js";
|
|
30
31
|
/** The 4 canonical slice-doc lifecycle statuses (docs/slice-doc-schema.md) — the same enum
|
|
31
32
|
* `em catalog`'s header coloring and `em render`'s status legend already recognize. */
|
|
@@ -87,6 +88,41 @@ export function resolveSliceStatusFacts(file, model, refs, baseDir) {
|
|
|
87
88
|
export function countOpenIssues(model) {
|
|
88
89
|
return model.elements.filter((el) => el.issue).length;
|
|
89
90
|
}
|
|
91
|
+
/** Walk up from `startDir` looking for a `.specify/` directory — the same "is this a spec-kit
|
|
92
|
+
* project, and where is its root" walk `em-sdd-bridge`'s `findRepoRoot` does (and spec-kit's own
|
|
93
|
+
* `find_specify_root`). Returns the directory CONTAINING `.specify/`, or null at the filesystem
|
|
94
|
+
* root. Directory existence only; nothing inside `.specify/` is read. */
|
|
95
|
+
export function findSpecifyRoot(startDir) {
|
|
96
|
+
let dir = resolve(startDir);
|
|
97
|
+
for (;;) {
|
|
98
|
+
if (existsSync(join(dir, ".specify")))
|
|
99
|
+
return dir;
|
|
100
|
+
const parent = dirname(dir);
|
|
101
|
+
if (parent === dir)
|
|
102
|
+
return null;
|
|
103
|
+
dir = parent;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Resolve one model's implementation constitution (MIL-202). Two project shapes, one document —
|
|
108
|
+
* em never writes or expects a second copy:
|
|
109
|
+
*
|
|
110
|
+
* - **spec-kit project** (a `.specify/` directory exists at or above `modelDir`): the document
|
|
111
|
+
* IS `<root>/.specify/memory/constitution.md`, spec-kit's own slot. em defers to it.
|
|
112
|
+
* - **anything else**: `<modelDir>/constitution.md`, beside the model — what `em scaffold`
|
|
113
|
+
* writes.
|
|
114
|
+
*
|
|
115
|
+
* Existence only: this never opens the file, so a blank stock template and a fully answered,
|
|
116
|
+
* ratified constitution are indistinguishable here by design (content judgment is a human's, and
|
|
117
|
+
* `em`'s core stays deterministic and LLM-free). The advisory "is it still an unfilled template"
|
|
118
|
+
* check belongs to the SDD bridge, not here.
|
|
119
|
+
*/
|
|
120
|
+
export function resolveConstitution(modelDir) {
|
|
121
|
+
const base = resolve(modelDir);
|
|
122
|
+
const specifyRoot = findSpecifyRoot(base);
|
|
123
|
+
const absolute = specifyRoot ? join(specifyRoot, ".specify", "memory", "constitution.md") : join(base, "constitution.md");
|
|
124
|
+
return { present: existsSync(absolute), path: relative(base, absolute).split(sep).join("/") };
|
|
125
|
+
}
|
|
90
126
|
/**
|
|
91
127
|
* `git rev-list --count <revision>..HEAD` in `repo` (any directory inside it, not necessarily
|
|
92
128
|
* its root — same "anchor dir, resolve toplevel" convention `conformScope.ts`'s
|
|
@@ -146,16 +182,20 @@ export function resolveSlicePRsBehindHead(repo, revision, slices, runGit = realG
|
|
|
146
182
|
* per-model namespacing), but its `Model file:` bullet names exactly ONE of them — so a sibling
|
|
147
183
|
* file it does NOT describe (the common case: a `conform-scope --seed-asis` scratch copy like
|
|
148
184
|
* `checkout-asis.em` sitting next to `checkout.em`) must not inherit `checkout.em`'s conformance
|
|
149
|
-
* record just because it lives in the same directory.
|
|
150
|
-
*
|
|
151
|
-
* channel a git failure uses)
|
|
185
|
+
* record just because it lives in the same directory. `stateFile.ts`'s `modelPathMismatch` (the
|
|
186
|
+
* one check both this function and `em conform-scope`, MIL-179, run) reports that case: the
|
|
187
|
+
* record comes back unattributed (via `error`, the same non-fatal channel a git failure uses)
|
|
188
|
+
* rather than silently misattributed.
|
|
152
189
|
*/
|
|
153
190
|
export function resolveConformanceEntry(file, repoOverride, sliceDocFacts, runGit = realGit) {
|
|
154
191
|
const modelDir = dirname(file);
|
|
155
192
|
const repo = repoOverride ?? modelDir;
|
|
193
|
+
// MIL-202: independent of the state file and of git — the constitution is a per-model fact
|
|
194
|
+
// every entry carries, including the early-return branches below.
|
|
195
|
+
const constitution = resolveConstitution(modelDir);
|
|
156
196
|
const loaded = loadStateFile(modelDir);
|
|
157
197
|
if (!loaded.ok) {
|
|
158
|
-
return { file, modelDir, hasStateFile: false, lastConformance: null, repo, commitsBehindHead: null, slicePRsBehindHead: null, error: null };
|
|
198
|
+
return { file, modelDir, hasStateFile: false, lastConformance: null, repo, commitsBehindHead: null, slicePRsBehindHead: null, constitution, error: null };
|
|
159
199
|
}
|
|
160
200
|
const parsed = parseState(loaded.text);
|
|
161
201
|
if (!parsed.ok) {
|
|
@@ -167,23 +207,16 @@ export function resolveConformanceEntry(file, repoOverride, sliceDocFacts, runGi
|
|
|
167
207
|
repo,
|
|
168
208
|
commitsBehindHead: null,
|
|
169
209
|
slicePRsBehindHead: null,
|
|
210
|
+
constitution,
|
|
170
211
|
error: `state file: ${parsed.message}`,
|
|
171
212
|
};
|
|
172
213
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
modelDir,
|
|
177
|
-
hasStateFile: true,
|
|
178
|
-
lastConformance: null,
|
|
179
|
-
repo,
|
|
180
|
-
commitsBehindHead: null,
|
|
181
|
-
slicePRsBehindHead: null,
|
|
182
|
-
error: `state file describes "${parsed.state.modelPath}", not "${basename(file)}" — not attributing its conformance record`,
|
|
183
|
-
};
|
|
214
|
+
const mismatch = modelPathMismatch(parsed.state.modelPath, file);
|
|
215
|
+
if (mismatch) {
|
|
216
|
+
return { file, modelDir, hasStateFile: true, lastConformance: null, repo, commitsBehindHead: null, slicePRsBehindHead: null, constitution, error: mismatch };
|
|
184
217
|
}
|
|
185
218
|
if (!parsed.state.lastConformance) {
|
|
186
|
-
return { file, modelDir, hasStateFile: true, lastConformance: null, repo, commitsBehindHead: null, slicePRsBehindHead: null, error: null };
|
|
219
|
+
return { file, modelDir, hasStateFile: true, lastConformance: null, repo, commitsBehindHead: null, slicePRsBehindHead: null, constitution, error: null };
|
|
187
220
|
}
|
|
188
221
|
const { date, revision } = parsed.state.lastConformance;
|
|
189
222
|
const commitsResult = commitsBehindHead(repo, revision, runGit);
|
|
@@ -196,6 +229,7 @@ export function resolveConformanceEntry(file, repoOverride, sliceDocFacts, runGi
|
|
|
196
229
|
repo,
|
|
197
230
|
commitsBehindHead: null,
|
|
198
231
|
slicePRsBehindHead: null,
|
|
232
|
+
constitution,
|
|
199
233
|
error: commitsResult.message,
|
|
200
234
|
};
|
|
201
235
|
}
|
|
@@ -209,6 +243,7 @@ export function resolveConformanceEntry(file, repoOverride, sliceDocFacts, runGi
|
|
|
209
243
|
repo,
|
|
210
244
|
commitsBehindHead: commitsResult.count,
|
|
211
245
|
slicePRsBehindHead: null,
|
|
246
|
+
constitution,
|
|
212
247
|
error: slicePRsResult.message,
|
|
213
248
|
};
|
|
214
249
|
}
|
|
@@ -220,6 +255,7 @@ export function resolveConformanceEntry(file, repoOverride, sliceDocFacts, runGi
|
|
|
220
255
|
repo,
|
|
221
256
|
commitsBehindHead: commitsResult.count,
|
|
222
257
|
slicePRsBehindHead: slicePRsResult.count,
|
|
258
|
+
constitution,
|
|
223
259
|
error: null,
|
|
224
260
|
};
|
|
225
261
|
}
|
|
@@ -361,6 +397,12 @@ function formatConformanceValue(entry) {
|
|
|
361
397
|
return "never conformed";
|
|
362
398
|
return `\`${entry.lastConformance.revision}\` — ${formatBehindHead(entry)}`;
|
|
363
399
|
}
|
|
400
|
+
/** MIL-202: the per-model constitution clause — `present`, or `absent (<expected path>)` with
|
|
401
|
+
* the path the entry already resolved (relative to that model's own directory). Shared by the
|
|
402
|
+
* text and markdown reports so the two can't drift. Existence only; never a content judgment. */
|
|
403
|
+
export function formatConstitutionPart(entry) {
|
|
404
|
+
return entry.constitution.present ? "present" : `absent (${entry.constitution.path ?? "unresolved"})`;
|
|
405
|
+
}
|
|
364
406
|
/** The one-line rollup: `"8/8 implemented · 20/20 invariants covered · 0 open issues · last
|
|
365
407
|
* conformed <rev>, N commits behind HEAD"` (MIL-163's acceptance line). For multiple input
|
|
366
408
|
* models, the conformance clause reports the FIRST file's entry — a single-file invocation is
|
|
@@ -398,6 +440,12 @@ export function formatStatusDetail(report) {
|
|
|
398
440
|
const label = multi ? `conformance (${entry.file}): ` : "conformance: ";
|
|
399
441
|
lines.push(`${label}${formatConformancePart(entry)}`);
|
|
400
442
|
}
|
|
443
|
+
// MIL-202: one constitution line per model, after the conformance lines, same multi-model
|
|
444
|
+
// labelling convention.
|
|
445
|
+
for (const entry of report.conformance) {
|
|
446
|
+
const label = multi ? `constitution (${entry.file}): ` : "constitution: ";
|
|
447
|
+
lines.push(`${label}${formatConstitutionPart(entry)}`);
|
|
448
|
+
}
|
|
401
449
|
if (report.diagnostics.length > 0) {
|
|
402
450
|
lines.push(`doc issues: ${pluralize(report.diagnostics.length, "warning")} — see diagnostics (${report.diagnostics.map((d) => d.code).join(", ")})`);
|
|
403
451
|
}
|
|
@@ -440,6 +488,15 @@ export function formatStatusMarkdown(report) {
|
|
|
440
488
|
rows.push([`Last conformed (${entry.file})`, formatConformanceValue(entry)]);
|
|
441
489
|
}
|
|
442
490
|
}
|
|
491
|
+
// MIL-202: one Constitution row per model, same single-vs-multi labelling as "Last conformed".
|
|
492
|
+
if (report.conformance.length <= 1) {
|
|
493
|
+
rows.push(["Constitution", formatConstitutionPart(report.conformance[0])]);
|
|
494
|
+
}
|
|
495
|
+
else {
|
|
496
|
+
for (const entry of report.conformance) {
|
|
497
|
+
rows.push([`Constitution (${entry.file})`, formatConstitutionPart(entry)]);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
443
500
|
const header = "| Metric | Value |\n|---|---|";
|
|
444
501
|
const body = rows.map(([k, v]) => `| ${escapeCell(k)} | ${escapeCell(v)} |`).join("\n");
|
|
445
502
|
return `${header}\n${body}`;
|