@milehimikey/em 1.14.1 → 1.15.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.
Files changed (98) hide show
  1. package/.claude/skills/event-modeling/SKILL.md +3 -3
  2. package/.claude/skills/event-modeling-conform/SKILL.md +1 -1
  3. package/.claude/skills/event-modeling-design/SKILL.md +29 -18
  4. package/.claude/skills/event-modeling-discover/SKILL.md +1 -1
  5. package/.claude/skills/event-modeling-engagement/SKILL.md +54 -54
  6. package/.claude/skills/event-modeling-engagement/reference/engagement.md +5 -19
  7. package/.claude/skills/event-modeling-implement/SKILL.md +1 -1
  8. package/.claude/skills/event-modeling-implement/reference/implement.md +29 -23
  9. package/.claude/skills/event-modeling-review/SKILL.md +13 -3
  10. package/.claude/skills/event-modeling-shared/reference/em-dsl.md +230 -227
  11. package/.claude/skills/event-modeling-shared/reference/operating-principles.md +3 -3
  12. package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +58 -27
  13. package/.claude/skills/event-modeling-shared/templates/constitution.md +5 -7
  14. package/.claude-plugin/marketplace.json +2 -2
  15. package/README.md +12 -0
  16. package/dist/catalog/docJoin.d.ts +17 -1
  17. package/dist/catalog/docJoin.js +7 -1
  18. package/dist/catalog/docJoin.js.map +1 -1
  19. package/dist/catalog/driftSignal.d.ts +16 -12
  20. package/dist/catalog/driftSignal.js +14 -9
  21. package/dist/catalog/driftSignal.js.map +1 -1
  22. package/dist/catalog/sliceDoc.d.ts +51 -0
  23. package/dist/catalog/sliceDoc.js +47 -0
  24. package/dist/catalog/sliceDoc.js.map +1 -1
  25. package/dist/catalog/sliceReadyValidate.js +12 -0
  26. package/dist/catalog/sliceReadyValidate.js.map +1 -1
  27. package/dist/cli/conformScope.d.ts +4 -0
  28. package/dist/cli/conformScope.js +2 -2
  29. package/dist/cli/conformScope.js.map +1 -1
  30. package/dist/cli/coverage.js +7 -3
  31. package/dist/cli/coverage.js.map +1 -1
  32. package/dist/cli/defer.d.ts +61 -2
  33. package/dist/cli/defer.js +204 -23
  34. package/dist/cli/defer.js.map +1 -1
  35. package/dist/cli/engagement.d.ts +13 -5
  36. package/dist/cli/engagement.js +26 -19
  37. package/dist/cli/engagement.js.map +1 -1
  38. package/dist/cli/findings.d.ts +2 -2
  39. package/dist/cli/findings.js +2 -2
  40. package/dist/cli/frontmatterSurgery.d.ts +3 -3
  41. package/dist/cli/frontmatterSurgery.js +3 -3
  42. package/dist/cli/frontmatterSurgery.js.map +1 -1
  43. package/dist/cli/markImplemented.d.ts +20 -9
  44. package/dist/cli/markImplemented.js +112 -14
  45. package/dist/cli/markImplemented.js.map +1 -1
  46. package/dist/cli/ratify.d.ts +36 -6
  47. package/dist/cli/ratify.js +130 -35
  48. package/dist/cli/ratify.js.map +1 -1
  49. package/dist/cli/review.js +3 -3
  50. package/dist/cli/review.js.map +1 -1
  51. package/dist/cli/revise.d.ts +57 -0
  52. package/dist/cli/revise.js +207 -0
  53. package/dist/cli/revise.js.map +1 -0
  54. package/dist/cli/sliceConform.d.ts +4 -3
  55. package/dist/cli/sliceConform.js +29 -12
  56. package/dist/cli/sliceConform.js.map +1 -1
  57. package/dist/cli/status.d.ts +8 -0
  58. package/dist/cli/status.js +7 -4
  59. package/dist/cli/status.js.map +1 -1
  60. package/dist/cli/upgrade.js +7 -4
  61. package/dist/cli/upgrade.js.map +1 -1
  62. package/dist/cli.js +118 -77
  63. package/dist/cli.js.map +1 -1
  64. package/dist/emit/json.d.ts +1 -1
  65. package/dist/emit/json.js +13 -1
  66. package/dist/emit/json.js.map +1 -1
  67. package/dist/emit/statusJson.d.ts +1 -1
  68. package/dist/emit/statusJson.js +4 -1
  69. package/dist/emit/statusJson.js.map +1 -1
  70. package/dist/mcp/server.js +5 -5
  71. package/dist/mcp/server.js.map +1 -1
  72. package/dist/model/rules.d.ts +8 -0
  73. package/dist/model/rules.js +8 -0
  74. package/dist/model/rules.js.map +1 -1
  75. package/dist/model/sliceDocIndex.d.ts +3 -0
  76. package/dist/model/sliceDocIndex.js +5 -4
  77. package/dist/model/sliceDocIndex.js.map +1 -1
  78. package/dist/templates.d.ts +1 -1
  79. package/dist/templates.js +5 -7
  80. package/dist/templates.js.map +1 -1
  81. package/package.json +2 -2
  82. package/plugin/.claude-plugin/plugin.json +2 -2
  83. package/plugin/shared/reference/em-dsl.md +230 -227
  84. package/plugin/shared/reference/operating-principles.md +3 -3
  85. package/plugin/shared/reference/slice-doc-schema.md +58 -27
  86. package/plugin/shared/templates/constitution.md +5 -7
  87. package/plugin/skills/conform/SKILL.md +1 -1
  88. package/plugin/skills/design/SKILL.md +29 -18
  89. package/plugin/skills/discover/SKILL.md +1 -1
  90. package/plugin/skills/engagement/SKILL.md +54 -54
  91. package/plugin/skills/engagement/reference/engagement.md +5 -19
  92. package/plugin/skills/event-modeling/SKILL.md +3 -3
  93. package/plugin/skills/implement/SKILL.md +1 -1
  94. package/plugin/skills/implement/reference/implement.md +29 -23
  95. package/plugin/skills/review/SKILL.md +13 -3
  96. package/dist/cli/reratify.d.ts +0 -58
  97. package/dist/cli/reratify.js +0 -238
  98. package/dist/cli/reratify.js.map +0 -1
@@ -159,11 +159,15 @@ undocumented ordering, a contradiction with adjacent code. The discipline:
159
159
  answered open question or a small ratified delta alongside your fix, so the decision is
160
160
  recorded instead of buried in an implementation diff.
161
161
  - **How a delta is ratified on a doc that never shipped** (it is `ready-to-implement` with
162
- `ratifiedBy` set): once the human has answered, the doc changes by `em slice reratify
163
- <model>.em <slice-key>` (bumps `version:`, clears the old sign-off, leaves `status` alone),
164
- the answer is written into the doc, and the human re-signs with `em slice ratify <model>.em
165
- <slice-key> --by <name>` — on a slice owning a `public` element both commands also need
166
- `--meaning-unchanged` or `--contract-change "<why>"` (MIL-238). That is the human's step, not
162
+ `ratifiedBy` set): once the human has answered, the doc changes by `em slice revise
163
+ <model>.em <slice-key>` (MIL-283: opens the next version as a `draft` — `version:` bumped,
164
+ the old sign-off cleared; the ratification of the unshipped version is withdrawn),
165
+ the answer is written into the doc and committed, the room reviews it (`em slice review
166
+ --by`), and the human re-signs with `em slice ratify
167
+ <model>.em <slice-key> --by <name>` (it records the commit it signs and refuses uncommitted
168
+ changes, MIL-284) — on a slice owning a `public` element that `ratify` also needs
169
+ `--meaning-unchanged` or `--contract-change "<why>"` (MIL-238; `revise` takes neither — the
170
+ confirmation belongs to the new version's sign-off). That is the human's step, not
167
171
  yours — you never run `ratify`, and
168
172
  the doc is not ratified again until they do; resume the build after that.
169
173
  - **Never edit the ratified doc to record your own answer**, and never quietly pick a behavior
@@ -229,7 +233,15 @@ a bump here is a ledger defect.
229
233
  `em slice mark-implemented <model>.em <slice-key> <pr-url>` does the flip for you (MIL-103) —
230
234
  resolves the doc via the same note-binding join `--slice-ready` uses, is idempotent on a re-run
231
235
  with the same URL, and refuses (never silently overwrites) if the doc is already `implemented`
232
- with a different URL. Prefer it over hand-editing the doc's frontmatter.
236
+ with a different URL. It also refuses a doc that isn't `ready-to-implement` (MIL-277): if it
237
+ reports `doc is \`status: draft\``/`reviewed`, the slice was never ratified — stop and surface
238
+ that to the human rather than editing the frontmatter by hand; the §1 gate should have caught it.
239
+ Prefer it over hand-editing the doc's frontmatter. It also writes the **shipped record**
240
+ (`shippedVersion:`/`shippedRef:`/`shippedOn:`, MIL-284) — what every reader decides "has this
241
+ shipped?" on since 1.15.0 — and, when the ratified doc deferred a question to the next version,
242
+ **opens that version as a `draft` on the same write** (MIL-283: `status: draft`, `version` bumped,
243
+ the question back to `- [ ]`; the version you built stays shipped). If it prints `opened draft
244
+ v<N+1>`, say so in your report: the slice has known work, and a design session, not you, decides it.
233
245
 
234
246
  Then, if the project keeps a model README (from `../../../shared/templates/model-readme.md`), run
235
247
  `em slice index <model-name>.em` so its generated Slices table reflects the new status and
@@ -309,23 +321,17 @@ sibling slice's package to reuse it — the boundary the constitution drew is go
309
321
  contract into a pre-empted slice.
310
322
  2. **It merges before any slice PR opens.** Every slice branch is cut *after* the foundation PR
311
323
  has landed on `main` — never from a commit that predates it, and never alongside an open,
312
- unmerged foundation PR. Within an engagement, cut the slice branch from the base the
313
- engagement plan names (`em engagement plan`); outside an engagement, from `main`. A slice PR
314
- never carries foundation files. Because: a slice PR opened while the foundation is still in
315
- review shows a diff dominated by files the slice didn't write and can't be held accountable
316
- for, and its merge depends on someone else's review timeline instead of its own. The plan's
317
- base is either `main` or `impl/<upstream>` (the one unmerged upstream slice this slice builds
318
- on); either way it already contains the foundation.
319
-
320
- 2a. **While a dependent PR is open, the lower PR merges with a merge commit; squash is forbidden
321
- in that state (it strands the dependent's history).** A PR is the *lower* one when another
322
- open PR targets its branch as its base. Once no open PR depends on it, the project's usual
323
- merge strategy applies. Because: a squash rewrites the lower branch's commits into one new
324
- commit on `main`, so the dependent branch still carries the originals and its diff against
325
- `main` shows them again — it then needs a hand rebase (`git rebase --onto main <old base
326
- tip>`). A merge commit keeps the original commits: once the lower branch is merged and
327
- deleted, the dependent is retargeted to `main` and its diff shrinks to its own commits with
328
- no rebase.
324
+ unmerged foundation PR. Every slice branch is cut from `main` and every slice PR targets
325
+ `main` — inside an engagement (`em engagement plan` names `main` as every slice's base) and
326
+ outside one alike; never from another slice's branch, never targeting another slice's PR. A
327
+ slice PR never carries foundation files. Because: a slice PR opened while the foundation is
328
+ still in review shows a diff dominated by files the slice didn't write and can't be held
329
+ accountable for, and its merge depends on someone else's review timeline instead of its own.
330
+ And because the foundation already holds every event and rule 3 keeps a slice out of its
331
+ siblings' code, no slice needs another slice's branch to compile or test: a PR cut from a
332
+ sibling's branch (a "stack") carries a dependency this contract forbids, and turns N isolated
333
+ slices into one landing with merge-commit and retargeting ceremony attached. `main` already
334
+ contains the foundation; that is all a slice needs.
329
335
 
330
336
  3. **A slice never creates, edits, or reaches into another slice's code.** It *imports* events —
331
337
  only events — from wherever the foundation placed them; a sibling slice's handlers, storage,
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: review
3
- em-version: 1.14.1
3
+ em-version: 1.15.0
4
4
  description: >-
5
5
  Use when starting em's live browser viewer (`em watch --serve`) so a team can watch a model
6
6
  update in real time, or facilitating a SCHEDULED stakeholder walkthrough that steps through
@@ -54,10 +54,20 @@ walk each one with the user, same as any open issue. Update the state file's Par
54
54
  section with who attended, and run `em state set-review <date>` to set the `Last stakeholder
55
55
  review:` marker (mirrors `Last conformance:`).
56
56
 
57
- **Per-slice outcome.** A slice whose open questions are all resolved in the room →
57
+ **Per-slice outcome.** Walk the slice's questions — the doc's `## Open Questions` and every
58
+ `issue "..."` note the room added to its elements — and give each one of three endings:
59
+
60
+ - **Answered in the room** → edit the doc's authored section with the answer and delete the
61
+ `issue` note by hand. Defer is never used to record an answer.
62
+ - **Raised in the room, not for this version** → `em slice defer <model> <key> --from-issue "<text>" --until v<n> --decision "<what this version does>"`:
63
+ promotes the captured `issue` into the doc's Open Questions as a deferred item, mirrors it
64
+ into the state file and removes the red note — one command, no hand edit mid-session.
65
+ - **Already on the doc, not for this version** → the positional form. A question this version will not answer is deferred with `em slice defer <model> <key> "<question>" --until v<n> --decision "<what this version does>"` — never left `- [ ]`, never deleted, never answered by guessing.
66
+
67
+ Then, and only then: a slice with nothing left `- [ ]` and no open `issue` →
58
68
  `em slice review <model>.em <key> --by <name>` (flips its doc to `status: reviewed` and records
59
69
  `reviewedBy:`/`reviewedOn:`). Anything still open stays `draft` — the walkthrough doesn't decide
60
- it, the next session or the open-questions list does. A question this version will not answer is deferred with `em slice defer <model> <key> "<question>" --until v<n> --decision "<what this version does>"` — never left `- [ ]`, never deleted, never answered by guessing.
70
+ it, the next session or the open-questions list does.
61
71
 
62
72
  **The facilitator never ratifies, never offers to ratify, and never suggests ratification in a
63
73
  review session. Ratification is a separate human gate after review**
@@ -1,58 +0,0 @@
1
- import { NormalizedModel } from "../model/model.js";
2
- import { RefsResult } from "../model/refs.js";
3
- import { MeaningConfirmation } from "./ratify.js";
4
- export type ApplyReratifyResult = {
5
- ok: true;
6
- content: string;
7
- newVersion: number;
8
- kind: ReratifyKind;
9
- } | {
10
- ok: false;
11
- message: string;
12
- };
13
- /** MIL-258: `shipped` = the doc was `status: implemented` (status flips back); `unshipped` = a
14
- * ratified `ready-to-implement` doc that never shipped (status untouched). */
15
- export type ReratifyKind = "shipped" | "unshipped";
16
- /**
17
- * Pure text transform: bumps `version:` by 1 and flips `status:` to `ready-to-implement` in
18
- * `raw`'s frontmatter block, clearing any `ratifiedBy:`/`ratifiedOn:` lines found (see module
19
- * header). Refuses (`ok: false`) unless the doc's CURRENT `status:` is `implemented`, or
20
- * `ready-to-implement` with `ratifiedBy:` set (MIL-258, `kind: "unshipped"`, status left alone) —
21
- * see module header for why this precondition (not idempotent-no-op) is the right refusal
22
- * shape here. No fs access — the caller reads/writes; see `runReratify` below.
23
- */
24
- export declare function applyReratifyFrontmatter(raw: string, confirmation?: MeaningConfirmation | null): ApplyReratifyResult;
25
- /** MIL-214: the certification-aware advisory `runReratify` computes about the version being
26
- * superseded — never gates the bump, see module header. */
27
- export interface ReratifyAdvisory {
28
- /** True when the CURRENT (pre-bump) version has no matching `conformedVersion` — either never
29
- * certified at all, or certified against a different version. */
30
- neverCertified: boolean;
31
- /** Count of unruled (`locus: null`) conformance findings in scope for this slice, across every
32
- * `conformance/*-findings.json` beside the model — not scoped to one revision, since a
33
- * reratify has no `--at` of its own to anchor on. */
34
- unruledFindingsCount: number;
35
- }
36
- /** Pure: the two facts `runReratify`'s advisory reports, from the doc's own pre-bump
37
- * `version`/`conformedVersion` plus a scan of every findings file beside the model — see
38
- * `ReratifyAdvisory`. No refusal here or anywhere downstream; this is data for the CLI layer to
39
- * print as `warn:` lines. */
40
- export declare function reratifyAdvisory(baseDir: string, sliceKey: string, currentVersion: number | null, conformedVersion: number | null): ReratifyAdvisory;
41
- export type RunReratifyResult = {
42
- ok: true;
43
- path: string;
44
- newVersion: number;
45
- kind: ReratifyKind;
46
- advisory: ReratifyAdvisory | null;
47
- reopened: number;
48
- } | {
49
- ok: false;
50
- message: string;
51
- };
52
- /**
53
- * Resolves `sliceKey` to its bound doc via the same note-binding join `mark-implemented`/
54
- * `ratify`/`--slice-ready`/`em export` use (MIL-121 cross-binding included), then reads/applies/
55
- * writes it. `baseDir` is the `.em` file's directory, same convention every doc/note path in
56
- * `em` uses.
57
- */
58
- export declare function runReratify(model: NormalizedModel, refs: RefsResult, baseDir: string, sliceKey: string, confirmation?: MeaningConfirmation | null): RunReratifyResult;
@@ -1,238 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- // `em slice reratify` (MIL-161 finding #4): the version-bump / status-flip mechanical edit
3
- // SKILL.md's `slice` phase (step 0/2, re-ratification) has always described as "bump `version`
4
- // and flip `status` back to `ready-to-implement` by hand" — the same shape `em slice
5
- // mark-implemented` (MIL-103) already mechanized at the OTHER end of the lifecycle (the merge-
6
- // time flip). Sets exactly two frontmatter fields on the doc resolved from the key via the SAME
7
- // note-binding resolution `mark-implemented`/`ratify`/`--slice-ready`/`em export` use
8
- // (catalog/docJoin.ts's resolveSliceDocJoin):
9
- //
10
- // version: <current + 1>
11
- // status: ready-to-implement
12
- //
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
24
- // docs/slice-doc-schema.md#status-under-re-ratification describes ("a new version is ratified
25
- // for a slice whose previous version already shipped"). Refuses (never guesses) otherwise: a
26
- // `draft`/`reviewed` doc hasn't shipped yet, so there's no prior version to bump FROM, and a
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).
32
- //
33
- // Also clears `ratifiedBy:`/`ratifiedOn:` if either is present: those fields record who signed
34
- // off the PRIOR version (`em slice ratify`, MIL-165) and describing the brand-new, not-yet-
35
- // reviewed version as already ratified by the old signer would be actively misleading. Clearing
36
- // them (rather than leaving them stale) is also what lets a subsequent `em slice ratify --by
37
- // <name>` apply cleanly afterward — ratify's own idempotent-refusal guard would otherwise read
38
- // the leftover prior ratifiedBy/ratifiedOn as "already ratified by someone else" and refuse.
39
- //
40
- // MIL-201: `reviewedBy:`/`reviewedOn:` are cleared for the same reason and in the same sweep. The
41
- // review record describes the version that shipped, not the new one — a re-ratified version needs
42
- // no fresh review session (the doc lands at `ready-to-implement`, which `em slice ratify`'s review
43
- // gate accepts), but leaving the old review in place would claim the room walked a version it has
44
- // never seen.
45
- //
46
- // Write strategy: the same surgical index-math splicing markImplemented.ts/ratify.ts use, via
47
- // the shared primitives in ./frontmatterSurgery.js — never a parse+re-serialize. Everything
48
- // outside the edited value spans — the body, `implementedIn:`, the lineage/`covers` keys, and
49
- // (best-effort) the file's own line-ending style — is copied through verbatim. The `## Delta`
50
- // section (docs/slice-doc-schema.md#delta-section-grammar-and-lifecycle) recording WHAT changed
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.
60
- //
61
- // MIL-238: `meaningConfirmed:`/`contractChange:` describe the PRIOR version too, so they are
62
- // cleared in the same sweep as the sign-off keys. On a public-touching slice the bump itself
63
- // requires a fresh confirmation (`--meaning-unchanged` or `--contract-change "<why>"`), written
64
- // directly after the new `version:` line; on any other slice either flag is accepted and recorded.
65
- import { readFileSync, writeFileSync } from "node:fs";
66
- import { join } from "node:path";
67
- import { continuationOf } from "../model/continuation.js";
68
- import { resolveSliceDocJoin } from "../catalog/docJoin.js";
69
- import { fieldLineRegex, fieldLineWithEolRegex, locateFrontmatterInner, normalizeFieldValue } from "./frontmatterSurgery.js";
70
- import { listAllFindingsFiles, unruledFindingsInScope } from "./findings.js";
71
- import { MEANING_CONFIRMATION_KEYS, meaningConfirmationLine, meaningConfirmationRequiredMessage, } from "./ratify.js";
72
- import { isPublicTouchingSlice } from "../catalog/apiFirst.js";
73
- import { reopenDeferred } from "./defer.js";
74
- /** The status a doc must already be in for `reratify` to apply — mirrors `RATIFIED_STATUS` in
75
- * ratify.ts (the status this command flips TO), named separately since it's the precondition
76
- * here, not the target. */
77
- const IMPLEMENTED_STATUS = "implemented";
78
- const TARGET_STATUS = "ready-to-implement";
79
- /**
80
- * Pure text transform: bumps `version:` by 1 and flips `status:` to `ready-to-implement` in
81
- * `raw`'s frontmatter block, clearing any `ratifiedBy:`/`ratifiedOn:` lines found (see module
82
- * header). Refuses (`ok: false`) unless the doc's CURRENT `status:` is `implemented`, or
83
- * `ready-to-implement` with `ratifiedBy:` set (MIL-258, `kind: "unshipped"`, status left alone) —
84
- * see module header for why this precondition (not idempotent-no-op) is the right refusal
85
- * shape here. No fs access — the caller reads/writes; see `runReratify` below.
86
- */
87
- export function applyReratifyFrontmatter(raw, confirmation = null) {
88
- const range = locateFrontmatterInner(raw);
89
- if (!range)
90
- return { ok: false, message: "no frontmatter block found" };
91
- const inner = raw.slice(range.innerStart, range.innerEnd);
92
- const statusMatch = fieldLineRegex("status").exec(inner);
93
- if (!statusMatch)
94
- return { ok: false, message: "no `status:` field found in frontmatter" };
95
- const currentStatus = normalizeFieldValue(statusMatch[2])?.toLowerCase() ?? null;
96
- let kind = "shipped";
97
- if (currentStatus !== IMPLEMENTED_STATUS) {
98
- const ratifiedByMatch = fieldLineRegex("ratifiedBy").exec(inner);
99
- const hasRatifiedBy = ratifiedByMatch !== null && normalizeFieldValue(ratifiedByMatch[2]) !== null;
100
- if (currentStatus === TARGET_STATUS && hasRatifiedBy) {
101
- kind = "unshipped";
102
- }
103
- else if (currentStatus === TARGET_STATUS) {
104
- return {
105
- ok: false,
106
- message: "doc is `status: ready-to-implement` with no `ratifiedBy:` — it is awaiting ratification " +
107
- "(a reratify already ran, or it was never signed off), so another version bump would " +
108
- "double-increment `version:`; record the sign-off with `em slice ratify --by <name>`",
109
- };
110
- }
111
- else {
112
- return {
113
- ok: false,
114
- message: `doc is \`status: ${currentStatus ?? "(empty)"}\` — reratify only applies to a slice doc that has ` +
115
- "shipped (`status: implemented`) or to a ratified `ready-to-implement` doc that has not (see " +
116
- "docs/slice-doc-schema.md#status-under-re-ratification); a `draft`/`reviewed` doc is not ratified " +
117
- "and can simply be edited, and first-time authoring uses `em slice new`",
118
- };
119
- }
120
- }
121
- const versionMatch = fieldLineRegex("version").exec(inner);
122
- if (!versionMatch)
123
- return { ok: false, message: "no `version:` field found in frontmatter" };
124
- const currentVersionRaw = normalizeFieldValue(versionMatch[2]);
125
- const currentVersion = currentVersionRaw !== null ? Number(currentVersionRaw) : NaN;
126
- if (!Number.isInteger(currentVersion) || currentVersion < 1) {
127
- return {
128
- ok: false,
129
- message: `doc's \`version:\` value "${currentVersionRaw ?? ""}" isn't a positive integer — refusing to guess a bump`,
130
- };
131
- }
132
- const newVersion = currentVersion + 1;
133
- // Clear stale ratifiedBy:/ratifiedOn:/reviewedBy:/reviewedOn: — see module header — and
134
- // (MIL-238) the prior version's meaningConfirmed:/contractChange:. Done FIRST, on the original
135
- // text, so the fresh confirmation line spliced in after `version:` below is never swept away.
136
- // These keys are disjoint from `status:`/`version:` by construction (fieldLineRegex matches one
137
- // key at a time), so the two lines are re-located on the cleared text unchanged.
138
- let cleared = inner;
139
- for (const key of ["ratifiedBy", "ratifiedOn", "reviewedBy", "reviewedOn", ...MEANING_CONFIRMATION_KEYS]) {
140
- cleared = cleared.replace(fieldLineWithEolRegex(key), "");
141
- }
142
- const clearedStatus = fieldLineRegex("status").exec(cleared);
143
- const clearedVersion = fieldLineRegex("version").exec(cleared);
144
- const afterVersion = cleared.slice(clearedVersion.index + clearedVersion[0].length);
145
- const eol = afterVersion.startsWith("\r\n") ? "\r\n" : "\n";
146
- const versionNext = `${clearedVersion[1]}${newVersion}`;
147
- // Apply from the highest index first so an earlier edit's index stays valid — same convention
148
- // markImplemented.ts/ratify.ts use.
149
- const edits = [
150
- // MIL-258: the unshipped path is already at the target status — nothing to flip.
151
- ...(kind === "shipped"
152
- ? [{ index: clearedStatus.index, oldLen: clearedStatus[0].length, next: `${clearedStatus[1]}${TARGET_STATUS}` }]
153
- : []),
154
- {
155
- index: clearedVersion.index,
156
- oldLen: clearedVersion[0].length,
157
- next: confirmation ? `${versionNext}${eol}${meaningConfirmationLine(confirmation)}` : versionNext,
158
- },
159
- ].sort((a, b) => b.index - a.index);
160
- let updatedInner = cleared;
161
- for (const edit of edits) {
162
- updatedInner = updatedInner.slice(0, edit.index) + edit.next + updatedInner.slice(edit.index + edit.oldLen);
163
- }
164
- const content = raw.slice(0, range.innerStart) + updatedInner + raw.slice(range.innerEnd);
165
- return { ok: true, content, newVersion, kind };
166
- }
167
- /** Pure: the two facts `runReratify`'s advisory reports, from the doc's own pre-bump
168
- * `version`/`conformedVersion` plus a scan of every findings file beside the model — see
169
- * `ReratifyAdvisory`. No refusal here or anywhere downstream; this is data for the CLI layer to
170
- * print as `warn:` lines. */
171
- export function reratifyAdvisory(baseDir, sliceKey, currentVersion, conformedVersion) {
172
- const neverCertified = conformedVersion === null || conformedVersion !== currentVersion;
173
- let unruledFindingsCount = 0;
174
- for (const { doc } of listAllFindingsFiles(baseDir)) {
175
- unruledFindingsCount += unruledFindingsInScope(doc.findings, new Set([sliceKey])).length;
176
- }
177
- return { neverCertified, unruledFindingsCount };
178
- }
179
- /**
180
- * Resolves `sliceKey` to its bound doc via the same note-binding join `mark-implemented`/
181
- * `ratify`/`--slice-ready`/`em export` use (MIL-121 cross-binding included), then reads/applies/
182
- * writes it. `baseDir` is the `.em` file's directory, same convention every doc/note path in
183
- * `em` uses.
184
- */
185
- export function runReratify(model, refs, baseDir, sliceKey, confirmation = null) {
186
- const sliceIndex = refs.sliceKeys.indexOf(sliceKey);
187
- if (sliceIndex === -1) {
188
- return { ok: false, message: `no slice with export key "${sliceKey}" in this model` };
189
- }
190
- const slice = model.slices[sliceIndex];
191
- const { doc, continuationOf: continuationOfKey } = resolveSliceDocJoin(model, refs, slice, sliceKey, baseDir, (id) => refs.refById.get(id));
192
- // MIL-208: see runRatify's own comment — a continuation slice has no status of its own.
193
- if (continuationOfKey) {
194
- const continuation = continuationOf(model, refs, sliceIndex);
195
- const viewName = model.byId.get(continuation.viewLogicalId).name;
196
- return {
197
- ok: false,
198
- message: `"${sliceKey}" is a continuation of "${continuationOfKey}" (view "${viewName}" again) — ` +
199
- `it has no doc of its own; reratify "${continuationOfKey}" instead`,
200
- };
201
- }
202
- if (doc.reason === "no-doc-bound") {
203
- return {
204
- ok: false,
205
- message: `slice "${sliceKey}" has no doc bound via \`note "slices/${sliceKey}.md"\` — bind a slice doc before reratifying it`,
206
- };
207
- }
208
- if (doc.reason === "binding-missing-file") {
209
- return { ok: false, message: `slice "${sliceKey}" notes "${doc.path}" but no such file exists` };
210
- }
211
- if (doc.reason === "frontmatter-invalid") {
212
- return {
213
- ok: false,
214
- message: `slice doc "${doc.path}" has missing or invalid frontmatter — run \`em validate\` for details`,
215
- };
216
- }
217
- const absPath = join(baseDir, doc.path);
218
- const raw = readFileSync(absPath, "utf8");
219
- const result = applyReratifyFrontmatter(raw, confirmation);
220
- if (!result.ok) {
221
- return { ok: false, message: `${doc.path}: ${result.message}` };
222
- }
223
- // MIL-238: the API-first gate — after the doc's own preconditions, before any write: a
224
- // public-touching slice's new version needs a meaning confirmation.
225
- if (confirmation === null && isPublicTouchingSlice(model, refs, sliceKey)) {
226
- return { ok: false, message: meaningConfirmationRequiredMessage(sliceKey) };
227
- }
228
- // MIL-214: computed from the doc's PRE-BUMP version/certification (`doc` was resolved before
229
- // the write below changes `version`) — "was the version we're about to supersede ever fully
230
- // certified". MIL-258: only meaningful for a SHIPPED version; an unshipped one has no
231
- // certification to lack, so that path carries no advisory at all.
232
- const advisory = result.kind === "shipped" ? reratifyAdvisory(baseDir, sliceKey, doc.version, doc.conformedVersion) : null;
233
- // MIL-275: questions deferred to the version this bump reaches come back as `- [ ]`.
234
- const reopened = reopenDeferred(result.content, result.newVersion);
235
- writeFileSync(absPath, reopened.content, "utf8");
236
- return { ok: true, path: doc.path, newVersion: result.newVersion, kind: result.kind, advisory, reopened: reopened.count };
237
- }
238
- //# sourceMappingURL=reratify.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"reratify.js","sourceRoot":"","sources":["../../src/cli/reratify.ts"],"names":[],"mappings":"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"}