@milehimikey/em 1.12.0 → 1.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/event-modeling/SKILL.md +5 -2
- package/.claude/skills/event-modeling-conform/SKILL.md +20 -9
- package/.claude/skills/event-modeling-conform/reference/conform.md +107 -10
- package/.claude/skills/event-modeling-design/SKILL.md +26 -4
- package/.claude/skills/event-modeling-discover/SKILL.md +1 -1
- package/.claude/skills/event-modeling-implement/SKILL.md +7 -4
- package/.claude/skills/event-modeling-implement/reference/implement.md +26 -8
- package/.claude/skills/event-modeling-review/SKILL.md +5 -1
- package/.claude/skills/event-modeling-shared/reference/em-dsl.md +45 -6
- package/.claude/skills/event-modeling-shared/reference/operating-principles.md +13 -3
- package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +39 -0
- package/.claude/skills/event-modeling-shared/templates/conformance-report.md +8 -1
- package/.claude/skills/event-modeling-shared/templates/state.md +3 -0
- package/README.md +1 -0
- package/dist/catalog/docJoin.d.ts +9 -0
- package/dist/catalog/docJoin.js +6 -0
- package/dist/catalog/docJoin.js.map +1 -1
- package/dist/catalog/driftSignal.d.ts +11 -5
- package/dist/catalog/driftSignal.js +18 -4
- package/dist/catalog/driftSignal.js.map +1 -1
- package/dist/catalog/modelVersionValidate.d.ts +9 -0
- package/dist/catalog/modelVersionValidate.js +38 -0
- package/dist/catalog/modelVersionValidate.js.map +1 -0
- package/dist/catalog/sliceDoc.d.ts +12 -0
- package/dist/catalog/sliceDoc.js +15 -0
- package/dist/catalog/sliceDoc.js.map +1 -1
- package/dist/cli/ciInit.d.ts +24 -0
- package/dist/cli/ciInit.js +85 -15
- package/dist/cli/ciInit.js.map +1 -1
- package/dist/cli/conformScope.d.ts +1 -0
- package/dist/cli/conformScope.js +3 -1
- package/dist/cli/conformScope.js.map +1 -1
- package/dist/cli/conformSupersede.d.ts +24 -2
- package/dist/cli/conformSupersede.js +44 -3
- package/dist/cli/conformSupersede.js.map +1 -1
- package/dist/cli/coverage.d.ts +16 -2
- package/dist/cli/coverage.js +26 -4
- package/dist/cli/coverage.js.map +1 -1
- package/dist/cli/findings.d.ts +134 -0
- package/dist/cli/findings.js +355 -0
- package/dist/cli/findings.js.map +1 -0
- package/dist/cli/metrics.d.ts +93 -0
- package/dist/cli/metrics.js +331 -0
- package/dist/cli/metrics.js.map +1 -0
- package/dist/cli/modelVersion.d.ts +139 -0
- package/dist/cli/modelVersion.js +256 -0
- package/dist/cli/modelVersion.js.map +1 -0
- package/dist/cli/reratify.d.ts +24 -1
- package/dist/cli/reratify.js +73 -17
- package/dist/cli/reratify.js.map +1 -1
- package/dist/cli/skillCheck.js +2 -2
- package/dist/cli/skillCheck.js.map +1 -1
- package/dist/cli/sliceConform.d.ts +50 -0
- package/dist/cli/sliceConform.js +206 -0
- package/dist/cli/sliceConform.js.map +1 -0
- package/dist/cli/sliceIndex.d.ts +2 -0
- package/dist/cli/sliceIndex.js +15 -3
- package/dist/cli/sliceIndex.js.map +1 -1
- package/dist/cli/sliceNew.d.ts +12 -0
- package/dist/cli/sliceNew.js +23 -0
- package/dist/cli/sliceNew.js.map +1 -1
- package/dist/cli/sliceStubAll.d.ts +76 -0
- package/dist/cli/sliceStubAll.js +189 -0
- package/dist/cli/sliceStubAll.js.map +1 -0
- package/dist/cli/stateFile.d.ts +63 -7
- package/dist/cli/stateFile.js +179 -18
- package/dist/cli/stateFile.js.map +1 -1
- package/dist/cli/status.d.ts +79 -1
- package/dist/cli/status.js +134 -15
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/upgrade.d.ts +132 -0
- package/dist/cli/upgrade.js +524 -0
- package/dist/cli/upgrade.js.map +1 -0
- package/dist/cli.js +609 -50
- package/dist/cli.js.map +1 -1
- package/dist/emit/coverageJson.d.ts +5 -2
- package/dist/emit/coverageJson.js +6 -2
- package/dist/emit/coverageJson.js.map +1 -1
- package/dist/emit/freshnessJson.d.ts +1 -1
- package/dist/emit/freshnessJson.js +3 -1
- package/dist/emit/freshnessJson.js.map +1 -1
- package/dist/emit/json.d.ts +11 -1
- package/dist/emit/json.js +35 -1
- package/dist/emit/json.js.map +1 -1
- package/dist/emit/metricsJson.d.ts +7 -0
- package/dist/emit/metricsJson.js +27 -0
- package/dist/emit/metricsJson.js.map +1 -0
- package/dist/emit/statusJson.d.ts +1 -1
- package/dist/emit/statusJson.js +17 -1
- package/dist/emit/statusJson.js.map +1 -1
- package/dist/emit/upgradeJson.d.ts +5 -0
- package/dist/emit/upgradeJson.js +29 -0
- package/dist/emit/upgradeJson.js.map +1 -0
- package/dist/emit/validateJson.d.ts +6 -2
- package/dist/emit/validateJson.js +12 -5
- package/dist/emit/validateJson.js.map +1 -1
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +137 -9
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/rules.d.ts +7 -0
- package/dist/model/rules.js +12 -0
- package/dist/model/rules.js.map +1 -1
- package/dist/model/validate.d.ts +20 -0
- package/dist/model/validate.js +94 -45
- package/dist/model/validate.js.map +1 -1
- package/dist/templates.d.ts +2 -2
- package/dist/templates.js +7 -1
- package/dist/templates.js.map +1 -1
- package/dist/util/semver.d.ts +19 -0
- package/dist/util/semver.js +54 -0
- package/dist/util/semver.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// `em model version` (MIL-218, from the MIL-214 discussion): the model-level counterpart to
|
|
3
|
+
// `em slice conform`'s per-slice certification. Slices carry their own `version:` and drift
|
|
4
|
+
// apart over time; nothing before this named "the model" as a whole. Two facts, kept separate:
|
|
5
|
+
//
|
|
6
|
+
// - **Design version** — an explicit, human-bumped integer (`em model version bump --by <name>
|
|
7
|
+
// [--on <date>]`), same identity discipline as `em slice ratify`. Bumps when structure
|
|
8
|
+
// changes (slice added/removed, seam change) or a batch of slice deltas is ratified
|
|
9
|
+
// together.
|
|
10
|
+
// - **Certified version** — "design version N was certified at revision R on date D", written
|
|
11
|
+
// by a full (non-`--partial`) `em state set-conformance` (MIL-214) into the CURRENT design
|
|
12
|
+
// version's manifest. A partial marker never certifies.
|
|
13
|
+
//
|
|
14
|
+
// Sidecar manifest, not the state file: `model-versions/v<N>.json`, sibling of `slices/` and
|
|
15
|
+
// `conformance/` — history, not progress, which is why it's not in `.event-modeling.md` (that
|
|
16
|
+
// file only ever carries a POINTER: the `Model version:`/`Certified:` bullets, stateFile.ts).
|
|
17
|
+
// Deterministic serialization through ONE writer (`serializeModelVersionDoc`), same discipline
|
|
18
|
+
// `serializeFindingsDoc` (findings.ts) holds — keys in a fixed order, 2-space, trailing newline,
|
|
19
|
+
// never a bare `JSON.stringify`.
|
|
20
|
+
//
|
|
21
|
+
// `modelHash` is the sha256 of the `.em` file's own bytes, after normalizing line endings to
|
|
22
|
+
// `\n` first — so a checkout with different line-ending settings (CRLF vs LF) never reads as a
|
|
23
|
+
// content change on its own; only real edits move the hash.
|
|
24
|
+
//
|
|
25
|
+
// `slices` covers every non-continuation slice (MIL-208's "an `again` view instance is a
|
|
26
|
+
// continuation of its originating slice, never a slice with its own doc/version to vector") —
|
|
27
|
+
// export key -> that slice's doc `version:` (or `null` when the slice has no usable doc yet).
|
|
28
|
+
//
|
|
29
|
+
// `modelVersionDrift` is the one shared predicate every warn-only surface (`em status`, `em
|
|
30
|
+
// validate`'s `model-version-stale`, `em slice ratify`/`reratify`'s advisory) reads — never
|
|
31
|
+
// re-derived three different ways. It never refuses anything itself; every caller decides how
|
|
32
|
+
// (or whether) to surface what it found.
|
|
33
|
+
import { createHash } from "node:crypto";
|
|
34
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
35
|
+
import { join } from "node:path";
|
|
36
|
+
import { resolveSliceDocJoin } from "../catalog/docJoin.js";
|
|
37
|
+
export const MODEL_VERSION_SCHEMA_VERSION = "1.0";
|
|
38
|
+
/** sha256 of `source`'s bytes, after normalizing every line ending to `\n` first — so a
|
|
39
|
+
* CRLF-vs-LF checkout difference never reads as a content change on its own. */
|
|
40
|
+
export function computeModelHash(source) {
|
|
41
|
+
const normalized = source.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
42
|
+
return createHash("sha256").update(normalized, "utf8").digest("hex");
|
|
43
|
+
}
|
|
44
|
+
/** Serialize a `ModelVersionManifest` deterministically — see module header. The ONE write path
|
|
45
|
+
* every producer of this file's bytes must go through, same discipline
|
|
46
|
+
* `findings.ts`'s `serializeFindingsDoc` holds. */
|
|
47
|
+
export function serializeModelVersionDoc(doc) {
|
|
48
|
+
const sortedSlices = {};
|
|
49
|
+
for (const key of Object.keys(doc.slices).sort())
|
|
50
|
+
sortedSlices[key] = doc.slices[key];
|
|
51
|
+
const canonical = {
|
|
52
|
+
bumpedBy: doc.bumpedBy,
|
|
53
|
+
bumpedOn: doc.bumpedOn,
|
|
54
|
+
certified: doc.certified
|
|
55
|
+
? { at: doc.certified.at, findings: doc.certified.findings, on: doc.certified.on, report: doc.certified.report }
|
|
56
|
+
: null,
|
|
57
|
+
emVersion: doc.emVersion,
|
|
58
|
+
model: doc.model,
|
|
59
|
+
modelHash: doc.modelHash,
|
|
60
|
+
modelVersionSchemaVersion: doc.modelVersionSchemaVersion,
|
|
61
|
+
slices: sortedSlices,
|
|
62
|
+
version: doc.version,
|
|
63
|
+
};
|
|
64
|
+
return `${JSON.stringify(canonical, null, 2)}\n`;
|
|
65
|
+
}
|
|
66
|
+
/** `<baseDir>/model-versions` — sibling of `slices/`/`conformance/`. `baseDir` is the `.em`
|
|
67
|
+
* file's directory, same convention every doc/note/manifest path in `em` uses. */
|
|
68
|
+
export function modelVersionsDir(baseDir) {
|
|
69
|
+
return join(baseDir, "model-versions");
|
|
70
|
+
}
|
|
71
|
+
export function modelVersionManifestPath(baseDir, version) {
|
|
72
|
+
return join(modelVersionsDir(baseDir), `v${version}.json`);
|
|
73
|
+
}
|
|
74
|
+
const MANIFEST_NAME_RE = /^v(\d+)\.json$/;
|
|
75
|
+
/** Every design version this model directory has ever bumped to, ascending. `[]` when
|
|
76
|
+
* `model-versions/` doesn't exist at all — the routine state for a model that has never
|
|
77
|
+
* bumped. Malformed/non-matching filenames in the directory are silently ignored (this is a
|
|
78
|
+
* discovery scan, not a validator). */
|
|
79
|
+
export function listModelVersionNumbers(baseDir) {
|
|
80
|
+
let entries;
|
|
81
|
+
try {
|
|
82
|
+
entries = readdirSync(modelVersionsDir(baseDir));
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
const nums = new Set();
|
|
88
|
+
for (const name of entries) {
|
|
89
|
+
const m = MANIFEST_NAME_RE.exec(name);
|
|
90
|
+
if (m)
|
|
91
|
+
nums.add(Number(m[1]));
|
|
92
|
+
}
|
|
93
|
+
return [...nums].sort((a, b) => a - b);
|
|
94
|
+
}
|
|
95
|
+
/** The highest bumped design version, or `null` when this model directory has never bumped. */
|
|
96
|
+
export function latestModelVersionNumber(baseDir) {
|
|
97
|
+
const nums = listModelVersionNumbers(baseDir);
|
|
98
|
+
return nums.length > 0 ? nums[nums.length - 1] : null;
|
|
99
|
+
}
|
|
100
|
+
/** Read+parse one design version's manifest. `null` when it doesn't exist at all (not an
|
|
101
|
+
* error — the routine "never bumped to this version" state); `{ ok: false }` when the file
|
|
102
|
+
* exists but isn't readable/valid JSON (a genuine problem, reported rather than silently
|
|
103
|
+
* swallowed). No shape validation beyond "is it JSON" — this file is written by exactly one
|
|
104
|
+
* writer (`serializeModelVersionDoc`) in this codebase. */
|
|
105
|
+
export function readModelVersionManifest(baseDir, version) {
|
|
106
|
+
const path = modelVersionManifestPath(baseDir, version);
|
|
107
|
+
if (!existsSync(path))
|
|
108
|
+
return null;
|
|
109
|
+
let raw;
|
|
110
|
+
try {
|
|
111
|
+
raw = readFileSync(path, "utf8");
|
|
112
|
+
}
|
|
113
|
+
catch (e) {
|
|
114
|
+
return { ok: false, message: `could not read ${path}: ${e.message}` };
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
return { ok: true, manifest: JSON.parse(raw) };
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return { ok: false, message: `${path} is not valid JSON` };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** The current slices vector: every non-continuation slice's export key -> its doc's `version:`
|
|
124
|
+
* (or `null` when the slice has no usable doc yet). MIL-208: a continuation slice (an
|
|
125
|
+
* `again`-view-only slice with no legacy doc of its own) is excluded — its originating slice's
|
|
126
|
+
* own entry already covers it, same exclusion `conformScope.ts`'s `resolveSliceDocFacts` makes.
|
|
127
|
+
* `baseDir` is the `.em` file's directory, same doc-resolution convention every other doc-aware
|
|
128
|
+
* command uses. */
|
|
129
|
+
export function computeSlicesVector(model, refs, baseDir) {
|
|
130
|
+
const vector = {};
|
|
131
|
+
model.slices.forEach((slice, i) => {
|
|
132
|
+
const key = refs.sliceKeys[i];
|
|
133
|
+
const { doc, continuationOf: continuationOfKey } = resolveSliceDocJoin(model, refs, slice, key, baseDir, (id) => refs.refById.get(id));
|
|
134
|
+
if (continuationOfKey !== null)
|
|
135
|
+
return;
|
|
136
|
+
vector[key] = doc.version;
|
|
137
|
+
});
|
|
138
|
+
return vector;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* `em model version bump`: write `model-versions/v<N+1>.json` (N+1 = highest existing + 1, or
|
|
142
|
+
* 1 for the first-ever bump). Refuses when `by` is empty, and when nothing has changed since
|
|
143
|
+
* the latest existing manifest (same `modelHash` AND same slices vector) unless `force` — a
|
|
144
|
+
* no-op bump is the one case `--force` is right for (the caller wants a new version stamped
|
|
145
|
+
* even though nothing moved). Pure computation + one fs write; the caller is responsible for
|
|
146
|
+
* the state-file-missing precondition (a model-version bump without a resumable state file to
|
|
147
|
+
* point the `Model version:` bullet at makes no sense — `em model version bump`'s CLI action
|
|
148
|
+
* checks that first, before this function is ever called) and for rewriting the state file's
|
|
149
|
+
* own `Model version:` bullet afterward (`stateFile.ts`'s `setModelVersion`).
|
|
150
|
+
*/
|
|
151
|
+
export function runModelVersionBump(baseDir, modelFileName, model, refs, source, by, on, emVersion, force) {
|
|
152
|
+
const trimmedBy = by.trim();
|
|
153
|
+
if (!trimmedBy)
|
|
154
|
+
return { ok: false, message: "a bumper name is required (--by)" };
|
|
155
|
+
const modelHash = computeModelHash(source);
|
|
156
|
+
const slices = computeSlicesVector(model, refs, baseDir);
|
|
157
|
+
const current = latestModelVersionNumber(baseDir);
|
|
158
|
+
if (current !== null && !force) {
|
|
159
|
+
const read = readModelVersionManifest(baseDir, current);
|
|
160
|
+
if (read && read.ok) {
|
|
161
|
+
const sameHash = read.manifest.modelHash === modelHash;
|
|
162
|
+
const sameSlices = JSON.stringify(Object.keys(read.manifest.slices).sort()) === JSON.stringify(Object.keys(slices).sort()) &&
|
|
163
|
+
Object.keys(slices).every((k) => (read.manifest.slices[k] ?? null) === (slices[k] ?? null));
|
|
164
|
+
if (sameHash && sameSlices) {
|
|
165
|
+
return {
|
|
166
|
+
ok: false,
|
|
167
|
+
message: `nothing has changed since v${current} (same model content and slice versions) — pass --force to bump anyway`,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const newVersion = (current ?? 0) + 1;
|
|
173
|
+
const manifest = {
|
|
174
|
+
modelVersionSchemaVersion: MODEL_VERSION_SCHEMA_VERSION,
|
|
175
|
+
model: modelFileName,
|
|
176
|
+
version: newVersion,
|
|
177
|
+
bumpedBy: trimmedBy,
|
|
178
|
+
bumpedOn: on,
|
|
179
|
+
emVersion,
|
|
180
|
+
modelHash,
|
|
181
|
+
slices,
|
|
182
|
+
certified: null,
|
|
183
|
+
};
|
|
184
|
+
mkdirSync(modelVersionsDir(baseDir), { recursive: true });
|
|
185
|
+
const path = modelVersionManifestPath(baseDir, newVersion);
|
|
186
|
+
writeFileSync(path, serializeModelVersionDoc(manifest), "utf8");
|
|
187
|
+
return { ok: true, version: newVersion, path };
|
|
188
|
+
}
|
|
189
|
+
export function modelVersionDrift(baseDir, model, refs, source) {
|
|
190
|
+
const current = latestModelVersionNumber(baseDir);
|
|
191
|
+
if (current === null)
|
|
192
|
+
return { current: null, hashChanged: false, slicesChanged: [] };
|
|
193
|
+
const read = readModelVersionManifest(baseDir, current);
|
|
194
|
+
if (!read || !read.ok)
|
|
195
|
+
return { current, hashChanged: false, slicesChanged: [] };
|
|
196
|
+
const hashChanged = read.manifest.modelHash !== computeModelHash(source);
|
|
197
|
+
const currentVector = computeSlicesVector(model, refs, baseDir);
|
|
198
|
+
const keys = new Set([...Object.keys(read.manifest.slices), ...Object.keys(currentVector)]);
|
|
199
|
+
const slicesChanged = [];
|
|
200
|
+
for (const key of [...keys].sort()) {
|
|
201
|
+
const from = read.manifest.slices[key] ?? null;
|
|
202
|
+
const to = currentVector[key] ?? null;
|
|
203
|
+
if (from !== to)
|
|
204
|
+
slicesChanged.push({ key, from, to });
|
|
205
|
+
}
|
|
206
|
+
return { current, hashChanged, slicesChanged };
|
|
207
|
+
}
|
|
208
|
+
/** The most recently bumped design version that has ever been certified — walking every
|
|
209
|
+
* manifest newest-first, since a later bump doesn't clear an earlier version's own
|
|
210
|
+
* `certified` stamp (only the CURRENT design version's manifest is ever written to by `em
|
|
211
|
+
* state set-conformance`; older manifests keep whatever certification they already carried).
|
|
212
|
+
* `null` when no manifest has ever been certified. Malformed manifests are skipped (best
|
|
213
|
+
* effort, same posture `findings.ts`'s `listAllFindingsFiles` takes toward a broken file it
|
|
214
|
+
* isn't itself the loud diagnostic for). */
|
|
215
|
+
export function findCertifiedVersion(baseDir) {
|
|
216
|
+
const nums = listModelVersionNumbers(baseDir).sort((a, b) => b - a);
|
|
217
|
+
for (const v of nums) {
|
|
218
|
+
const read = readModelVersionManifest(baseDir, v);
|
|
219
|
+
if (read && read.ok && read.manifest.certified)
|
|
220
|
+
return { version: v, certified: read.manifest.certified };
|
|
221
|
+
}
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* `em state set-conformance` (non-`--partial`, MIL-218 ruling D): write `certified: { at, on,
|
|
226
|
+
* report, findings }` into the CURRENT design version's manifest. Refuses when no manifest
|
|
227
|
+
* exists yet ("bump a model version first") and when the vector has drifted since that
|
|
228
|
+
* manifest was bumped (`modelVersionDrift`, computed here — the question is exactly "has THIS
|
|
229
|
+
* model changed since v<N> was bumped", the same predicate every other warn-only surface
|
|
230
|
+
* reads): the certification would otherwise name a version that isn't what was actually
|
|
231
|
+
* checked. Idempotent on an identical `certified` value; a DIFFERENT one simply overwrites —
|
|
232
|
+
* re-certifying at a later revision is legal and common (MIL-214's own `em slice conform` holds
|
|
233
|
+
* the same "overwrite, no --force" posture for exactly this reason).
|
|
234
|
+
*/
|
|
235
|
+
export function runCertifyModelVersion(baseDir, model, refs, source, at, on, report, findings) {
|
|
236
|
+
const current = latestModelVersionNumber(baseDir);
|
|
237
|
+
if (current === null) {
|
|
238
|
+
return { ok: false, message: "no model-versions/ manifest exists yet — bump a model version first (`em model version bump`)" };
|
|
239
|
+
}
|
|
240
|
+
const drift = modelVersionDrift(baseDir, model, refs, source);
|
|
241
|
+
if (drift.hashChanged || drift.slicesChanged.length > 0) {
|
|
242
|
+
return {
|
|
243
|
+
ok: false,
|
|
244
|
+
message: `the model has drifted since v${current} was bumped — bump a new model version first (\`em model version bump\`) before certifying`,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
const read = readModelVersionManifest(baseDir, current);
|
|
248
|
+
if (!read || !read.ok) {
|
|
249
|
+
return { ok: false, message: (read && "message" in read && read.message) || `model-versions/v${current}.json is missing or unreadable` };
|
|
250
|
+
}
|
|
251
|
+
const manifest = { ...read.manifest, certified: { at, on, report, findings } };
|
|
252
|
+
const path = modelVersionManifestPath(baseDir, current);
|
|
253
|
+
writeFileSync(path, serializeModelVersionDoc(manifest), "utf8");
|
|
254
|
+
return { ok: true, version: current, path };
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=modelVersion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modelVersion.js","sourceRoot":"","sources":["../../src/cli/modelVersion.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/reratify.d.ts
CHANGED
|
@@ -4,22 +4,45 @@ export type ApplyReratifyResult = {
|
|
|
4
4
|
ok: true;
|
|
5
5
|
content: string;
|
|
6
6
|
newVersion: number;
|
|
7
|
+
kind: ReratifyKind;
|
|
7
8
|
} | {
|
|
8
9
|
ok: false;
|
|
9
10
|
message: string;
|
|
10
11
|
};
|
|
12
|
+
/** MIL-258: `shipped` = the doc was `status: implemented` (status flips back); `unshipped` = a
|
|
13
|
+
* ratified `ready-to-implement` doc that never shipped (status untouched). */
|
|
14
|
+
export type ReratifyKind = "shipped" | "unshipped";
|
|
11
15
|
/**
|
|
12
16
|
* Pure text transform: bumps `version:` by 1 and flips `status:` to `ready-to-implement` in
|
|
13
17
|
* `raw`'s frontmatter block, clearing any `ratifiedBy:`/`ratifiedOn:` lines found (see module
|
|
14
|
-
* header). Refuses (`ok: false`) unless the doc's CURRENT `status:` is
|
|
18
|
+
* header). Refuses (`ok: false`) unless the doc's CURRENT `status:` is `implemented`, or
|
|
19
|
+
* `ready-to-implement` with `ratifiedBy:` set (MIL-258, `kind: "unshipped"`, status left alone) —
|
|
15
20
|
* see module header for why this precondition (not idempotent-no-op) is the right refusal
|
|
16
21
|
* shape here. No fs access — the caller reads/writes; see `runReratify` below.
|
|
17
22
|
*/
|
|
18
23
|
export declare function applyReratifyFrontmatter(raw: string): ApplyReratifyResult;
|
|
24
|
+
/** MIL-214: the certification-aware advisory `runReratify` computes about the version being
|
|
25
|
+
* superseded — never gates the bump, see module header. */
|
|
26
|
+
export interface ReratifyAdvisory {
|
|
27
|
+
/** True when the CURRENT (pre-bump) version has no matching `conformedVersion` — either never
|
|
28
|
+
* certified at all, or certified against a different version. */
|
|
29
|
+
neverCertified: boolean;
|
|
30
|
+
/** Count of unruled (`locus: null`) conformance findings in scope for this slice, across every
|
|
31
|
+
* `conformance/*-findings.json` beside the model — not scoped to one revision, since a
|
|
32
|
+
* reratify has no `--at` of its own to anchor on. */
|
|
33
|
+
unruledFindingsCount: number;
|
|
34
|
+
}
|
|
35
|
+
/** Pure: the two facts `runReratify`'s advisory reports, from the doc's own pre-bump
|
|
36
|
+
* `version`/`conformedVersion` plus a scan of every findings file beside the model — see
|
|
37
|
+
* `ReratifyAdvisory`. No refusal here or anywhere downstream; this is data for the CLI layer to
|
|
38
|
+
* print as `warn:` lines. */
|
|
39
|
+
export declare function reratifyAdvisory(baseDir: string, sliceKey: string, currentVersion: number | null, conformedVersion: number | null): ReratifyAdvisory;
|
|
19
40
|
export type RunReratifyResult = {
|
|
20
41
|
ok: true;
|
|
21
42
|
path: string;
|
|
22
43
|
newVersion: number;
|
|
44
|
+
kind: ReratifyKind;
|
|
45
|
+
advisory: ReratifyAdvisory | null;
|
|
23
46
|
} | {
|
|
24
47
|
ok: false;
|
|
25
48
|
message: string;
|
package/dist/cli/reratify.js
CHANGED
|
@@ -10,15 +10,25 @@
|
|
|
10
10
|
// version: <current + 1>
|
|
11
11
|
// status: ready-to-implement
|
|
12
12
|
//
|
|
13
|
-
//
|
|
13
|
+
// MIL-258: that is the SHIPPED path. A second path covers a doc at `status: ready-to-implement`
|
|
14
|
+
// that still carries `ratifiedBy:` — a ratified version that has not shipped (the most common
|
|
15
|
+
// change during delivery: an implementer hits a gap, a human answers it, the doc changes before
|
|
16
|
+
// the build resumes). It bumps `version:` and clears the same four sign-off fields but leaves
|
|
17
|
+
// `status:` (and any `implementedIn:`) alone, since there is nothing to flip back. A
|
|
18
|
+
// `ready-to-implement` doc with NO `ratifiedBy:` still refuses: that is the exact state a
|
|
19
|
+
// reratify leaves a doc in, so refusing keeps the double-bump guard — the doc is awaiting
|
|
20
|
+
// `em slice ratify --by`, not another bump. `draft`/`reviewed` docs are not ratified and refuse
|
|
21
|
+
// too; they can simply be edited.
|
|
22
|
+
//
|
|
23
|
+
// Shipped path precondition (original, MIL-161) — a doc currently `status: implemented`, the precondition
|
|
14
24
|
// docs/slice-doc-schema.md#status-under-re-ratification describes ("a new version is ratified
|
|
15
25
|
// for a slice whose previous version already shipped"). Refuses (never guesses) otherwise: a
|
|
16
26
|
// `draft`/`reviewed` doc hasn't shipped yet, so there's no prior version to bump FROM, and a
|
|
17
|
-
// doc already `ready-to-implement` means either first-time authoring (never
|
|
18
|
-
// reratify at all — `em slice new` is what scaffolds those) or a reratify
|
|
19
|
-
// second bump would silently double-increment `version`, which this command
|
|
20
|
-
// does — bumping isn't naturally idempotent the way ratify/mark-implemented's
|
|
21
|
-
// writes are).
|
|
27
|
+
// doc already `ready-to-implement` WITHOUT `ratifiedBy:` means either first-time authoring (never
|
|
28
|
+
// touch this doc with reratify at all — `em slice new` is what scaffolds those) or a reratify
|
|
29
|
+
// that already ran (a second bump would silently double-increment `version`, which this command
|
|
30
|
+
// deliberately never does — bumping isn't naturally idempotent the way ratify/mark-implemented's
|
|
31
|
+
// absolute-value writes are).
|
|
22
32
|
//
|
|
23
33
|
// Also clears `ratifiedBy:`/`ratifiedOn:` if either is present: those fields record who signed
|
|
24
34
|
// off the PRIOR version (`em slice ratify`, MIL-165) and describing the brand-new, not-yet-
|
|
@@ -39,11 +49,20 @@
|
|
|
39
49
|
// (best-effort) the file's own line-ending style — is copied through verbatim. The `## Delta`
|
|
40
50
|
// section (docs/slice-doc-schema.md#delta-section-grammar-and-lifecycle) recording WHAT changed
|
|
41
51
|
// stays entirely hand-authored — this command only ever touches the two lifecycle fields above.
|
|
52
|
+
//
|
|
53
|
+
// MIL-214: `reratifyAdvisory` below is the certification-aware counterpart to MIL-198's
|
|
54
|
+
// upstream-timeline advisory (ratify.ts's `upstreamUnratifiedSlices`) — same shape, same
|
|
55
|
+
// never-refuses stance. Bumping a version whose CURRENT one was never certified (or still has
|
|
56
|
+
// unruled conformance findings) isn't wrong — the team may have good reason to move on before a
|
|
57
|
+
// conform sweep ever ran — so this is advisory only, printed by the CLI layer, never gating the
|
|
58
|
+
// bump itself. MIL-258: the advisory is about superseding a SHIPPED version, so the unshipped
|
|
59
|
+
// path skips it entirely (`advisory: null`) — an unshipped version has no certification to lack.
|
|
42
60
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
43
61
|
import { join } from "node:path";
|
|
44
62
|
import { continuationOf } from "../model/continuation.js";
|
|
45
63
|
import { resolveSliceDocJoin } from "../catalog/docJoin.js";
|
|
46
64
|
import { fieldLineRegex, fieldLineWithEolRegex, locateFrontmatterInner, normalizeFieldValue } from "./frontmatterSurgery.js";
|
|
65
|
+
import { listAllFindingsFiles, unruledFindingsInScope } from "./findings.js";
|
|
47
66
|
/** The status a doc must already be in for `reratify` to apply — mirrors `RATIFIED_STATUS` in
|
|
48
67
|
* ratify.ts (the status this command flips TO), named separately since it's the precondition
|
|
49
68
|
* here, not the target. */
|
|
@@ -52,7 +71,8 @@ const TARGET_STATUS = "ready-to-implement";
|
|
|
52
71
|
/**
|
|
53
72
|
* Pure text transform: bumps `version:` by 1 and flips `status:` to `ready-to-implement` in
|
|
54
73
|
* `raw`'s frontmatter block, clearing any `ratifiedBy:`/`ratifiedOn:` lines found (see module
|
|
55
|
-
* header). Refuses (`ok: false`) unless the doc's CURRENT `status:` is
|
|
74
|
+
* header). Refuses (`ok: false`) unless the doc's CURRENT `status:` is `implemented`, or
|
|
75
|
+
* `ready-to-implement` with `ratifiedBy:` set (MIL-258, `kind: "unshipped"`, status left alone) —
|
|
56
76
|
* see module header for why this precondition (not idempotent-no-op) is the right refusal
|
|
57
77
|
* shape here. No fs access — the caller reads/writes; see `runReratify` below.
|
|
58
78
|
*/
|
|
@@ -65,14 +85,30 @@ export function applyReratifyFrontmatter(raw) {
|
|
|
65
85
|
if (!statusMatch)
|
|
66
86
|
return { ok: false, message: "no `status:` field found in frontmatter" };
|
|
67
87
|
const currentStatus = normalizeFieldValue(statusMatch[2])?.toLowerCase() ?? null;
|
|
88
|
+
let kind = "shipped";
|
|
68
89
|
if (currentStatus !== IMPLEMENTED_STATUS) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
90
|
+
const ratifiedByMatch = fieldLineRegex("ratifiedBy").exec(inner);
|
|
91
|
+
const hasRatifiedBy = ratifiedByMatch !== null && normalizeFieldValue(ratifiedByMatch[2]) !== null;
|
|
92
|
+
if (currentStatus === TARGET_STATUS && hasRatifiedBy) {
|
|
93
|
+
kind = "unshipped";
|
|
94
|
+
}
|
|
95
|
+
else if (currentStatus === TARGET_STATUS) {
|
|
96
|
+
return {
|
|
97
|
+
ok: false,
|
|
98
|
+
message: "doc is `status: ready-to-implement` with no `ratifiedBy:` — it is awaiting ratification " +
|
|
99
|
+
"(a reratify already ran, or it was never signed off), so another version bump would " +
|
|
100
|
+
"double-increment `version:`; record the sign-off with `em slice ratify --by <name>`",
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
return {
|
|
105
|
+
ok: false,
|
|
106
|
+
message: `doc is \`status: ${currentStatus ?? "(empty)"}\` — reratify only applies to a slice doc that has ` +
|
|
107
|
+
"shipped (`status: implemented`) or to a ratified `ready-to-implement` doc that has not (see " +
|
|
108
|
+
"docs/slice-doc-schema.md#status-under-re-ratification); a `draft`/`reviewed` doc is not ratified " +
|
|
109
|
+
"and can simply be edited, and first-time authoring uses `em slice new`",
|
|
110
|
+
};
|
|
111
|
+
}
|
|
76
112
|
}
|
|
77
113
|
const versionMatch = fieldLineRegex("version").exec(inner);
|
|
78
114
|
if (!versionMatch)
|
|
@@ -89,7 +125,10 @@ export function applyReratifyFrontmatter(raw) {
|
|
|
89
125
|
// Apply from the highest index first so an earlier edit's index stays valid — same convention
|
|
90
126
|
// markImplemented.ts/ratify.ts use.
|
|
91
127
|
const edits = [
|
|
92
|
-
|
|
128
|
+
// MIL-258: the unshipped path is already at the target status — nothing to flip.
|
|
129
|
+
...(kind === "shipped"
|
|
130
|
+
? [{ index: statusMatch.index, oldLen: statusMatch[0].length, next: `${statusMatch[1]}${TARGET_STATUS}` }]
|
|
131
|
+
: []),
|
|
93
132
|
{ index: versionMatch.index, oldLen: versionMatch[0].length, next: `${versionMatch[1]}${newVersion}` },
|
|
94
133
|
].sort((a, b) => b.index - a.index);
|
|
95
134
|
let updatedInner = inner;
|
|
@@ -105,7 +144,19 @@ export function applyReratifyFrontmatter(raw) {
|
|
|
105
144
|
updatedInner = updatedInner.replace(fieldLineWithEolRegex(key), "");
|
|
106
145
|
}
|
|
107
146
|
const content = raw.slice(0, range.innerStart) + updatedInner + raw.slice(range.innerEnd);
|
|
108
|
-
return { ok: true, content, newVersion };
|
|
147
|
+
return { ok: true, content, newVersion, kind };
|
|
148
|
+
}
|
|
149
|
+
/** Pure: the two facts `runReratify`'s advisory reports, from the doc's own pre-bump
|
|
150
|
+
* `version`/`conformedVersion` plus a scan of every findings file beside the model — see
|
|
151
|
+
* `ReratifyAdvisory`. No refusal here or anywhere downstream; this is data for the CLI layer to
|
|
152
|
+
* print as `warn:` lines. */
|
|
153
|
+
export function reratifyAdvisory(baseDir, sliceKey, currentVersion, conformedVersion) {
|
|
154
|
+
const neverCertified = conformedVersion === null || conformedVersion !== currentVersion;
|
|
155
|
+
let unruledFindingsCount = 0;
|
|
156
|
+
for (const { doc } of listAllFindingsFiles(baseDir)) {
|
|
157
|
+
unruledFindingsCount += unruledFindingsInScope(doc.findings, new Set([sliceKey])).length;
|
|
158
|
+
}
|
|
159
|
+
return { neverCertified, unruledFindingsCount };
|
|
109
160
|
}
|
|
110
161
|
/**
|
|
111
162
|
* Resolves `sliceKey` to its bound doc via the same note-binding join `mark-implemented`/
|
|
@@ -151,7 +202,12 @@ export function runReratify(model, refs, baseDir, sliceKey) {
|
|
|
151
202
|
if (!result.ok) {
|
|
152
203
|
return { ok: false, message: `${doc.path}: ${result.message}` };
|
|
153
204
|
}
|
|
205
|
+
// MIL-214: computed from the doc's PRE-BUMP version/certification (`doc` was resolved before
|
|
206
|
+
// the write below changes `version`) — "was the version we're about to supersede ever fully
|
|
207
|
+
// certified". MIL-258: only meaningful for a SHIPPED version; an unshipped one has no
|
|
208
|
+
// certification to lack, so that path carries no advisory at all.
|
|
209
|
+
const advisory = result.kind === "shipped" ? reratifyAdvisory(baseDir, sliceKey, doc.version, doc.conformedVersion) : null;
|
|
154
210
|
writeFileSync(absPath, result.content, "utf8");
|
|
155
|
-
return { ok: true, path: doc.path, newVersion: result.newVersion };
|
|
211
|
+
return { ok: true, path: doc.path, newVersion: result.newVersion, kind: result.kind, advisory };
|
|
156
212
|
}
|
|
157
213
|
//# sourceMappingURL=reratify.js.map
|
package/dist/cli/reratify.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reratify.js","sourceRoot":"","sources":["../../src/cli/reratify.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,2FAA2F;AAC3F,+FAA+F;AAC/F,qFAAqF;AACrF,+FAA+F;AAC/F,gGAAgG;AAChG,sFAAsF;AACtF,8CAA8C;AAC9C,EAAE;AACF,2BAA2B;AAC3B,+BAA+B;AAC/B,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"reratify.js","sourceRoot":"","sources":["../../src/cli/reratify.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/skillCheck.js
CHANGED
|
@@ -44,7 +44,7 @@ export function checkSkillSync(packagedDir, vendoredDir, installedVersion) {
|
|
|
44
44
|
else if (vendoredStamp !== installedVersion) {
|
|
45
45
|
findings.push({
|
|
46
46
|
code: "skill-check-stamp-mismatch",
|
|
47
|
-
message: `vendored skill's em-version: stamp (${vendoredStamp}) doesn't match installed em (${installedVersion}) — run \`em skill sync
|
|
47
|
+
message: `vendored skill's em-version: stamp (${vendoredStamp}) doesn't match installed em (${installedVersion}) — run \`em skill sync\` (or \`em upgrade\`)`,
|
|
48
48
|
vendoredStamp,
|
|
49
49
|
installedVersion,
|
|
50
50
|
});
|
|
@@ -54,7 +54,7 @@ export function checkSkillSync(packagedDir, vendoredDir, installedVersion) {
|
|
|
54
54
|
const driftedFiles = plan.changes.map((c) => c.relPath).sort();
|
|
55
55
|
findings.push({
|
|
56
56
|
code: "skill-check-content-drift",
|
|
57
|
-
message: `vendored skill differs from the packaged skill in ${driftedFiles.length} file(s) — run \`em skill sync
|
|
57
|
+
message: `vendored skill differs from the packaged skill in ${driftedFiles.length} file(s) — run \`em skill sync\` (or \`em upgrade\`)`,
|
|
58
58
|
driftedFiles,
|
|
59
59
|
});
|
|
60
60
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skillCheck.js","sourceRoot":"","sources":["../../src/cli/skillCheck.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,6FAA6F;AAC7F,0FAA0F;AAC1F,6FAA6F;AAC7F,6FAA6F;AAC7F,kFAAkF;AAClF,uDAAuD;AACvD,EAAE;AACF,+EAA+E;AAC/E,kFAAkF;AAClF,+FAA+F;AAC/F,0FAA0F;AAC1F,iEAAiE;AAEjE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAqB/C;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,WAAmB,EAAE,gBAAwB;IAC/F,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,2BAA2B;oBACjC,OAAO,EAAE,8BAA8B,WAAW,gCAAgC;iBACnF;aACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAwB,EAAE,CAAC;IAEzC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAClD,MAAM,aAAa,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEhH,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,2BAA2B;YACjC,OAAO,EAAE,GAAG,WAAW,8EAA8E;SACtG,CAAC,CAAC;IACL,CAAC;SAAM,IAAI,aAAa,KAAK,gBAAgB,EAAE,CAAC;QAC9C,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,4BAA4B;YAClC,OAAO,EAAE,uCAAuC,aAAa,iCAAiC,gBAAgB
|
|
1
|
+
{"version":3,"file":"skillCheck.js","sourceRoot":"","sources":["../../src/cli/skillCheck.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { NormalizedModel } from "../model/model.js";
|
|
2
|
+
import { RefsResult } from "../model/refs.js";
|
|
3
|
+
import { FindingsDoc } from "./findings.js";
|
|
4
|
+
export type ApplyConformResult = {
|
|
5
|
+
ok: true;
|
|
6
|
+
content: string;
|
|
7
|
+
changed: boolean;
|
|
8
|
+
version: number;
|
|
9
|
+
} | {
|
|
10
|
+
ok: false;
|
|
11
|
+
message: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Pure text transform: reads the CURRENT `version:` value (never writes it) and writes
|
|
15
|
+
* `conformedVersion:`/`conformedAt:`/`conformedOn:` in `raw`'s frontmatter block. See module
|
|
16
|
+
* header for the full precondition/idempotency contract. No fs access — the caller reads/writes;
|
|
17
|
+
* see `runSliceConform` below.
|
|
18
|
+
*/
|
|
19
|
+
export declare function applyConformFrontmatter(raw: string, sliceKey: string, at: string, on: string): ApplyConformResult;
|
|
20
|
+
/** Scan `<baseDir>/conformance/*-findings.json`, newest filename first, for the first one whose
|
|
21
|
+
* `revision` matches `at` — the "newest findings JSON whose revision == --at" the ruling
|
|
22
|
+
* describes. A malformed candidate is silently skipped (not refused): this is a best-effort
|
|
23
|
+
* lookup for the findings-check gate below, not itself a validator — `em conform-findings
|
|
24
|
+
* check` is where a broken findings file gets a loud diagnosis. Returns null when the
|
|
25
|
+
* `conformance/` directory doesn't exist, or no candidate matches `at`. */
|
|
26
|
+
export declare function findLatestFindingsForRevision(baseDir: string, at: string): {
|
|
27
|
+
path: string;
|
|
28
|
+
doc: FindingsDoc;
|
|
29
|
+
} | null;
|
|
30
|
+
export type RunSliceConformResult = {
|
|
31
|
+
ok: true;
|
|
32
|
+
path: string;
|
|
33
|
+
changed: boolean;
|
|
34
|
+
version: number;
|
|
35
|
+
/** Non-null exactly when `--skip-findings-check` is what let this certification through —
|
|
36
|
+
* the finding ids that were still unruled, for the caller's loud notice. `null` whenever
|
|
37
|
+
* the findings-check gate passed on its own merits (no findings file for this revision, or
|
|
38
|
+
* nothing unruled in scope), whether or not the flag was passed. */
|
|
39
|
+
skippedFindingsCheck: number[] | null;
|
|
40
|
+
} | {
|
|
41
|
+
ok: false;
|
|
42
|
+
message: string;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Resolves `sliceKey` to its bound doc via the same note-binding join `ratify`/`reratify`/
|
|
46
|
+
* `mark-implemented`/`em export` use (MIL-121 cross-binding included), runs the findings-check
|
|
47
|
+
* gate, then reads/applies/writes it. `baseDir` is the `.em` file's directory, same convention
|
|
48
|
+
* every doc/note path in `em` uses.
|
|
49
|
+
*/
|
|
50
|
+
export declare function runSliceConform(model: NormalizedModel, refs: RefsResult, baseDir: string, sliceKey: string, at: string, on: string, skipFindingsCheck?: boolean): RunSliceConformResult;
|