spec-controller 0.1.0-alpha.30 → 0.1.0-alpha.31

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/README.md CHANGED
@@ -78,7 +78,9 @@ The whole report is written before the code is set, so a failing run still tells
78
78
  its own rather than falling out of the process — a crash that exits `1` would be indistinguishable,
79
79
  by status, from an honest disagreement. **An input the tool cannot read is part of `2`**: a mistyped
80
80
  path, an unparseable report or a corpus the Gherkin parser rejects are all the invocation being
81
- wrong, never a verdict about your code.
81
+ wrong, never a verdict about your code. **So is an output location it cannot write**: a `--format` path that is
82
+ read-only, a directory, under a regular file or in a directory that does not exist, and a
83
+ `--store` root the run directory cannot be created under, are refused at `2`, naming the location and the operating system's reason, before any report is printed.
82
84
 
83
85
  **The enumeration is open at the top, and that is the one thing to design your pipeline around.** A
84
86
  state that is genuinely none of the above gets a **new** code rather than being folded into the
@@ -1,19 +1,6 @@
1
1
  /**
2
- * The output WRITER — the impure app-layer that realises an `OutputPlan` (the
3
- * three-layer split). For each planned output it renders
4
- * the payload via the PURE renderers (`renderMarkdown` / `renderJson` in `src/render/`)
5
- * and performs the IO: stdout, or a file.
6
- *
7
- * This is the ONLY layer that performs IO — the renderers stay pure (`model → string`)
8
- * and `planOutput` stays pure (parse+validate). So the writer carries the `@integration`
9
- * evidence: its real stdout/file effect is asserted directly (the anti-watermelon rule),
10
- * never a re-run of the `planOutput` `@unit`.
11
- *
12
- * FMT-001 (`@SCN-FMT-001`) writes markdown to stdout. The `json` format (FMT-002) and the
13
- * file destination (FMT-002/003) are wired on the same `render` + `dest` switch below as
14
- * later sub-issues plan them.
15
- *
16
- * Parent: @SCN-FMT-001 — the output-dispatch rework.
2
+ * The output writer: renders each planned output through the pure renderers and performs the only
3
+ * IO in the pipeline, to stdout or to a file.
17
4
  */
18
5
  import type { FeatureNames } from "@3f-consulting/spec-controller-core";
19
6
  import type { OutputPlan } from "./format.js";
@@ -22,12 +9,9 @@ import type { EvidenceObligations } from "@3f-consulting/spec-controller-core";
22
9
  import type { EvidenceReconciliation } from "@3f-consulting/spec-controller-core";
23
10
  /**
24
11
  * The reconciliation payloads the writer renders — the balance plus its sibling reads
25
- * (ctx / evidenceObligations / featureNames), exactly the arguments the pure renderers take. Threaded
26
- * from `cli.ts` (built once, rendered per planned output). `withRuntimeObservations` and
27
- * `withStaticChecks` are the GATES for the two observation axes (Test volume + the evidence grid;
28
- * the Static checks cut): the renderers fold BOTH off the Ledger themselves (3F-2103 / 3F-2118 —
29
- * the parallel censuses are retired), so the writer threads only whether each axis is in play,
30
- * never a census object.
12
+ * (ctx / evidenceObligations / featureNames), exactly the arguments the pure renderers take.
13
+ * `withRuntimeObservations` and `withStaticChecks` gate the two observation axes; the renderers
14
+ * fold both off the Ledger themselves, so the writer threads only whether each axis is in play.
31
15
  */
32
16
  export interface OutputPayloads {
33
17
  readonly balance: EvidenceReconciliation;
@@ -38,8 +22,9 @@ export interface OutputPayloads {
38
22
  readonly featureNames?: FeatureNames;
39
23
  }
40
24
  /**
41
- * Realise the plan: render each planned output and write it to its destination. The only
42
- * IO in the pipeline. FMT-001 exercises the markdown→stdout path.
25
+ * Every file destination is proved writable before any output is emitted, so a refused run never
26
+ * leaves a report behind, on stdout or in a file, whose headline names an exit the process does not
27
+ * take. Writing files first and stdout last would not do: an earlier file would still be written.
43
28
  */
44
29
  export declare function writeOutputs(plan: OutputPlan, payloads: OutputPayloads): void;
45
30
  //# sourceMappingURL=writer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../../src/cli-balance/emit/writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,KAAK,EAAgB,UAAU,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAElF;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC;IACzC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IACnD,QAAQ,CAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAC3C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;CACtC;AAWD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CAc7E"}
1
+ {"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../../src/cli-balance/emit/writer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,KAAK,EAAgB,UAAU,EAAiB,MAAM,aAAa,CAAC;AAC3E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAGlF;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC;IACzC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IACnD,QAAQ,CAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAC3C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;CACtC;AAQD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CAO7E"}
@@ -1,48 +1,40 @@
1
1
  /**
2
- * The output WRITER — the impure app-layer that realises an `OutputPlan` (the
3
- * three-layer split). For each planned output it renders
4
- * the payload via the PURE renderers (`renderMarkdown` / `renderJson` in `src/render/`)
5
- * and performs the IO: stdout, or a file.
6
- *
7
- * This is the ONLY layer that performs IO — the renderers stay pure (`model → string`)
8
- * and `planOutput` stays pure (parse+validate). So the writer carries the `@integration`
9
- * evidence: its real stdout/file effect is asserted directly (the anti-watermelon rule),
10
- * never a re-run of the `planOutput` `@unit`.
11
- *
12
- * FMT-001 (`@SCN-FMT-001`) writes markdown to stdout. The `json` format (FMT-002) and the
13
- * file destination (FMT-002/003) are wired on the same `render` + `dest` switch below as
14
- * later sub-issues plan them.
15
- *
16
- * Parent: @SCN-FMT-001 — the output-dispatch rework.
2
+ * The output writer: renders each planned output through the pure renderers and performs the only
3
+ * IO in the pipeline, to stdout or to a file.
17
4
  */
18
5
  import { writeFileSync } from "node:fs";
19
6
  import { renderMarkdown } from "@3f-consulting/spec-controller-core";
20
7
  import { renderJson } from "@3f-consulting/spec-controller-core";
21
- /** Render one format from the payloads via the matching pure renderer. */
8
+ import { probeWritable, writeOrRefuse } from "../../outputLocation.js";
22
9
  function render(fmt, p) {
23
- // The axis gates moved onto the concept's factory (3F-2233) — by the time a payload reaches a
24
- // renderer the totals are already folded, so there is nothing left here to switch on.
25
10
  return fmt === "json"
26
11
  ? renderJson(p.balance, p.ctx, p.evidenceObligations, p.featureNames)
27
12
  : renderMarkdown(p.balance, p.ctx, p.evidenceObligations, p.featureNames);
28
13
  }
29
14
  /**
30
- * Realise the plan: render each planned output and write it to its destination. The only
31
- * IO in the pipeline. FMT-001 exercises the markdown→stdout path.
15
+ * Every file destination is proved writable before any output is emitted, so a refused run never
16
+ * leaves a report behind, on stdout or in a file, whose headline names an exit the process does not
17
+ * take. Writing files first and stdout last would not do: an earlier file would still be written.
32
18
  */
33
19
  export function writeOutputs(plan, payloads) {
34
- for (const output of plan.outputs) {
35
- const rendered = render(output.fmt, payloads);
36
- switch (output.dest.kind) {
37
- case "stdout":
38
- // Trailing newline so the report ends cleanly on a terminal — FMT-001's path.
39
- process.stdout.write(rendered + "\n");
40
- break;
41
- case "file":
42
- // The file destination (FMT-002/003) — same rendered bytes, to a caller path.
43
- writeFileSync(output.dest.path, rendered + "\n", "utf8");
44
- break;
45
- }
20
+ const emissions = plan.outputs.map((output) => ({ output, text: render(output.fmt, payloads) + "\n" }));
21
+ for (const { output } of emissions) {
22
+ const dest = output.dest;
23
+ if (dest.kind === "file")
24
+ writeOrRefuse(refusalSubject(output), dest.path, () => probeWritable(dest.path));
46
25
  }
26
+ for (const { output, text } of emissions)
27
+ emit(output, text);
28
+ }
29
+ function refusalSubject(output) {
30
+ return `The ${output.fmt} report could not be written`;
31
+ }
32
+ function emit(output, text) {
33
+ const dest = output.dest;
34
+ if (dest.kind === "stdout") {
35
+ process.stdout.write(text);
36
+ return;
37
+ }
38
+ writeOrRefuse(refusalSubject(output), dest.path, () => writeFileSync(dest.path, text, "utf8"));
47
39
  }
48
40
  //# sourceMappingURL=writer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"writer.js","sourceRoot":"","sources":["../../../src/cli-balance/emit/writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAyBjE,0EAA0E;AAC1E,SAAS,MAAM,CAAC,GAAiB,EAAE,CAAiB;IAClD,8FAA8F;IAC9F,sFAAsF;IACtF,OAAO,GAAG,KAAK,MAAM;QACnB,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,mBAAmB,EAAE,CAAC,CAAC,YAAY,CAAC;QACrE,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,mBAAmB,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC;AAC9E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAgB,EAAE,QAAwB;IACrE,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC9C,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACzB,KAAK,QAAQ;gBACX,8EAA8E;gBAC9E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;gBACtC,MAAM;YACR,KAAK,MAAM;gBACT,8EAA8E;gBAC9E,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;gBACzD,MAAM;QACV,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"writer.js","sourceRoot":"","sources":["../../../src/cli-balance/emit/writer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAMjE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAiBvE,SAAS,MAAM,CAAC,GAAiB,EAAE,CAAiB;IAClD,OAAO,GAAG,KAAK,MAAM;QACnB,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,mBAAmB,EAAE,CAAC,CAAC,YAAY,CAAC;QACrE,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,mBAAmB,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC;AAC9E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAgB,EAAE,QAAwB;IACrE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;IACxG,KAAK,MAAM,EAAE,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,aAAa,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7G,CAAC;IACD,KAAK,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,SAAS;QAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,cAAc,CAAC,MAAqB;IAC3C,OAAO,OAAO,MAAM,CAAC,GAAG,8BAA8B,CAAC;AACzD,CAAC;AAED,SAAS,IAAI,CAAC,MAAqB,EAAE,IAAY;IAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACzB,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO;IACT,CAAC;IACD,aAAa,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;AACjG,CAAC"}
@@ -0,0 +1,15 @@
1
+ export declare function unwritableRefusal(subject: string, path: string, err: unknown): string;
2
+ /**
3
+ * The catch sits on the one write it guards rather than on the process, so a refusal can only ever
4
+ * name a location this call was asked to write, and a crash anywhere else is not dressed up as one.
5
+ */
6
+ export declare function writeOrRefuse(subject: string, path: string, write: () => void): void;
7
+ /**
8
+ * Throws the operating system's own error when `path` cannot be written as a file, and leaves the
9
+ * path as it found it: an existing file is opened write-only without truncation (not "r+", which
10
+ * would also demand read permission), and an absent one is created exclusively and removed again,
11
+ * so a missing, read-only or non-directory parent answers with its real reason instead of one this
12
+ * module would have to invent.
13
+ */
14
+ export declare function probeWritable(path: string): void;
15
+ //# sourceMappingURL=outputLocation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outputLocation.d.ts","sourceRoot":"","sources":["../src/outputLocation.ts"],"names":[],"mappings":"AAIA,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,CAGrF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,GAAG,IAAI,CAOpF;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAShD"}
@@ -0,0 +1,39 @@
1
+ import { closeSync, constants, openSync, unlinkSync } from "node:fs";
2
+ const USAGE_EXIT_CODE = 2;
3
+ export function unwritableRefusal(subject, path, err) {
4
+ const reason = err instanceof Error ? err.message : String(err);
5
+ return `${subject}: ${path} (${reason})`;
6
+ }
7
+ /**
8
+ * The catch sits on the one write it guards rather than on the process, so a refusal can only ever
9
+ * name a location this call was asked to write, and a crash anywhere else is not dressed up as one.
10
+ */
11
+ export function writeOrRefuse(subject, path, write) {
12
+ try {
13
+ write();
14
+ }
15
+ catch (err) {
16
+ process.stderr.write(unwritableRefusal(subject, path, err) + "\n");
17
+ process.exit(USAGE_EXIT_CODE);
18
+ }
19
+ }
20
+ /**
21
+ * Throws the operating system's own error when `path` cannot be written as a file, and leaves the
22
+ * path as it found it: an existing file is opened write-only without truncation (not "r+", which
23
+ * would also demand read permission), and an absent one is created exclusively and removed again,
24
+ * so a missing, read-only or non-directory parent answers with its real reason instead of one this
25
+ * module would have to invent.
26
+ */
27
+ export function probeWritable(path) {
28
+ try {
29
+ closeSync(openSync(path, constants.O_WRONLY));
30
+ return;
31
+ }
32
+ catch (err) {
33
+ if (err.code !== "ENOENT")
34
+ throw err;
35
+ }
36
+ closeSync(openSync(path, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL));
37
+ unlinkSync(path);
38
+ }
39
+ //# sourceMappingURL=outputLocation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outputLocation.js","sourceRoot":"","sources":["../src/outputLocation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErE,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B,MAAM,UAAU,iBAAiB,CAAC,OAAe,EAAE,IAAY,EAAE,GAAY;IAC3E,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChE,OAAO,GAAG,OAAO,KAAK,IAAI,KAAK,MAAM,GAAG,CAAC;AAC3C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,IAAY,EAAE,KAAiB;IAC5E,IAAI,CAAC;QACH,KAAK,EAAE,CAAC;IACV,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAChC,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,CAAC;QACH,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,GAAG,CAAC;IAClE,CAAC;IACD,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACrF,UAAU,CAAC,IAAI,CAAC,CAAC;AACnB,CAAC"}
@@ -15,24 +15,20 @@
15
15
  * files under a temp root + the repo untouched — never a planner re-run).
16
16
  *
17
17
  * The store root is an INJECTED parameter — never hardcoded — so the scaffold is
18
- * location-agnostic (proven against a temp root; the repo is never written). RMG-001 is
19
- * the dir + the routed outputs; the `run.yaml` stamp (RMG-002) and the `--run-id` mnemonic
20
- * override (RMG-003) land in later sub-issues.
21
- *
22
- * Parent: @SCN-RMG-001 — the run-management layer.
18
+ * location-agnostic (proven against a temp root; the repo is never written).
23
19
  */
24
20
  /** The two artefact filenames a kept run routes the tool's outputs into. */
25
21
  export declare const RECONCILIATION_DOCUMENT = "spec-reconciliation.md";
26
22
  /**
27
- * The machine artefact filename (@SCN-RMD-001) — renamed `ledger.json` →
23
+ * The machine artefact filename — renamed `ledger.json` →
28
24
  * `spec-reconciliation.json` (parity with `spec-reconciliation.md`): it is the machine form
29
25
  * of the WHOLE reconciliation document, not just the ledger.
30
26
  */
31
27
  export declare const RECONCILIATION_JSON = "spec-reconciliation.json";
32
- /** The manifest filename a kept run stamps in the run dir (RMG-002). */
28
+ /** The manifest filename a kept run stamps in the run dir. */
33
29
  export declare const RUN_MANIFEST = "run.yaml";
34
30
  /**
35
- * The run.yaml schema version this scaffold stamps. Bumped 1 → 2 by 3F-1916, which added
31
+ * The run.yaml schema version this scaffold stamps. Bumped 1 → 2 when it added
36
32
  * the tool identity (`tool_sha` / `tool_version`) — so a reader can tell a run that
37
33
  * predates tool-identity recording (schema 1) from one that should carry it (schema 2).
38
34
  * run.yaml is write-only (no production reader), so the bump breaks no read path.
@@ -47,7 +43,7 @@ export type RunMode = "balance" | "analyse" | "migrate";
47
43
  export interface RunManifestMeta {
48
44
  readonly sourceSha: string;
49
45
  /**
50
- * The TOOL's own git SHA — which spec-controller produced this run (3F-1916), distinct
46
+ * The TOOL's own git SHA — which spec-controller produced this run, distinct
51
47
  * from the target's `sourceSha`. A string ("unknown" when the tool is not a git
52
48
  * checkout), mirroring `sourceSha`'s own "unknown" fallback — so run.yaml is internally
53
49
  * consistent (both facts use the same absent-marker, never a bare null).
@@ -73,7 +69,7 @@ export interface RunManifest {
73
69
  readonly run_id: string;
74
70
  readonly target: string;
75
71
  readonly source_sha: string;
76
- /** The TOOL's identity (3F-1916) — which spec-controller produced the run. */
72
+ /** The TOOL's identity — which spec-controller produced the run. */
77
73
  readonly tool_sha: string;
78
74
  readonly tool_version: string;
79
75
  readonly mode: RunMode;
@@ -112,7 +108,7 @@ export type RouteOutputs = (formatSpecs: readonly string[]) => void;
112
108
  */
113
109
  export declare function planKeptRun(spec: KeptRunSpec): KeptRunPlan;
114
110
  /**
115
- * Options for the pure run-id resolver (RMG-003): the operator's OPTIONAL `--run-id` mnemonic
111
+ * Options for the pure run-id resolver: the operator's OPTIONAL `--run-id` mnemonic
116
112
  * and the INJECTED clock instant the default timestamp derives from.
117
113
  */
118
114
  export interface ResolveRunIdOptions {
@@ -129,14 +125,14 @@ export interface ResolveRunIdOptions {
129
125
  * run-id naming the run dir (feeds `KeptRunSpec.runId`). No `--run-id` → an ISO-8601 UTC
130
126
  * timestamp derived from the INJECTED `now` (filesystem-safe: no colons, no millis — matching
131
127
  * the existing store run dir); `--run-id <mnemonic>` → that mnemonic verbatim (`acme-q3`, `e1`
132
- * — an earlier precedent), which ignores the clock. No IO — proven `@unit` (RMG-003).
128
+ * — an earlier precedent), which ignores the clock. No IO — proven `@unit`.
133
129
  * The clock is injected (never a bare `new Date()`) so the default timestamp is deterministic
134
130
  * under test (the discipline the old `formatRunTimestamp` used). Just default-vs-override — no
135
131
  * sanitisation / collision policy (deferred).
136
132
  */
137
133
  export declare function resolveRunId(options: ResolveRunIdOptions): string;
138
134
  /**
139
- * PURE: build the run.yaml manifest object from the run metadata (RMG-002). `purpose` and
135
+ * PURE: build the run.yaml manifest object from the run metadata. `purpose` and
140
136
  * `links` are stamped EMPTY (the ad-hoc default; slugs are added by operator hand-edit of
141
137
  * run.yaml afterward — the documented curation convention); `artefacts` carry the decided
142
138
  * filenames. No IO — proven `@unit`.
@@ -145,12 +141,11 @@ export declare function planRunManifest(input: RunManifestInput): RunManifest;
145
141
  /** PURE: serialise the manifest to YAML text the impure runner writes verbatim. */
146
142
  export declare function serialiseRunManifest(manifest: RunManifest): string;
147
143
  /**
148
- * IMPURE runner: `mkdir -p` the run dir, route the tool's `--format` outputs into the two
149
- * files via the injected `route` — the document as `md:<documentPath>`, the reconciliation
150
- * JSON as `json:<reconciliationJsonPath>` — and stamp `run.yaml` with the manifest built from the spec + `meta`
151
- * (RMG-002). Returns the plan it realised. The only IO. The `mkdir` is load-bearing: the
152
- * tool's writer uses `writeFileSync`, which needs the parent dir to exist — so the scaffold
153
- * creates the dir the location-agnostic tool writes into.
144
+ * IMPURE runner: `mkdir -p` the run dir, route the tool's `--format` outputs into the two files
145
+ * via the injected `route` — the document as `md:<documentPath>`, the reconciliation JSON as
146
+ * `json:<reconciliationJsonPath>` — and stamp `run.yaml` from the spec + `meta`. Returns the
147
+ * plan it realised. The `mkdir` is load-bearing: the tool's writer creates no directories, so the
148
+ * scaffold creates the one the location-agnostic tool writes into.
154
149
  */
155
150
  export declare function executeKeptRun(spec: KeptRunSpec, meta: RunManifestMeta, route: RouteOutputs): KeptRunPlan;
156
151
  //# sourceMappingURL=keptRun.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"keptRun.d.ts","sourceRoot":"","sources":["../../src/run-management/keptRun.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keptRun.d.ts","sourceRoot":"","sources":["../../src/run-management/keptRun.ts"],"names":[],"mappings":"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"}
@@ -15,27 +15,24 @@
15
15
  * files under a temp root + the repo untouched — never a planner re-run).
16
16
  *
17
17
  * The store root is an INJECTED parameter — never hardcoded — so the scaffold is
18
- * location-agnostic (proven against a temp root; the repo is never written). RMG-001 is
19
- * the dir + the routed outputs; the `run.yaml` stamp (RMG-002) and the `--run-id` mnemonic
20
- * override (RMG-003) land in later sub-issues.
21
- *
22
- * Parent: @SCN-RMG-001 — the run-management layer.
18
+ * location-agnostic (proven against a temp root; the repo is never written).
23
19
  */
24
20
  import { mkdirSync, writeFileSync } from "node:fs";
25
21
  import { join } from "node:path";
26
22
  import { stringify } from "yaml";
23
+ import { writeOrRefuse } from "../outputLocation.js";
27
24
  /** The two artefact filenames a kept run routes the tool's outputs into. */
28
25
  export const RECONCILIATION_DOCUMENT = "spec-reconciliation.md";
29
26
  /**
30
- * The machine artefact filename (@SCN-RMD-001) — renamed `ledger.json` →
27
+ * The machine artefact filename — renamed `ledger.json` →
31
28
  * `spec-reconciliation.json` (parity with `spec-reconciliation.md`): it is the machine form
32
29
  * of the WHOLE reconciliation document, not just the ledger.
33
30
  */
34
31
  export const RECONCILIATION_JSON = "spec-reconciliation.json";
35
- /** The manifest filename a kept run stamps in the run dir (RMG-002). */
32
+ /** The manifest filename a kept run stamps in the run dir. */
36
33
  export const RUN_MANIFEST = "run.yaml";
37
34
  /**
38
- * The run.yaml schema version this scaffold stamps. Bumped 1 → 2 by 3F-1916, which added
35
+ * The run.yaml schema version this scaffold stamps. Bumped 1 → 2 when it added
39
36
  * the tool identity (`tool_sha` / `tool_version`) — so a reader can tell a run that
40
37
  * predates tool-identity recording (schema 1) from one that should carry it (schema 2).
41
38
  * run.yaml is write-only (no production reader), so the bump breaks no read path.
@@ -60,7 +57,7 @@ export function planKeptRun(spec) {
60
57
  * run-id naming the run dir (feeds `KeptRunSpec.runId`). No `--run-id` → an ISO-8601 UTC
61
58
  * timestamp derived from the INJECTED `now` (filesystem-safe: no colons, no millis — matching
62
59
  * the existing store run dir); `--run-id <mnemonic>` → that mnemonic verbatim (`acme-q3`, `e1`
63
- * — an earlier precedent), which ignores the clock. No IO — proven `@unit` (RMG-003).
60
+ * — an earlier precedent), which ignores the clock. No IO — proven `@unit`.
64
61
  * The clock is injected (never a bare `new Date()`) so the default timestamp is deterministic
65
62
  * under test (the discipline the old `formatRunTimestamp` used). Just default-vs-override — no
66
63
  * sanitisation / collision policy (deferred).
@@ -83,7 +80,7 @@ function formatRunTimestamp(instant) {
83
80
  return instant.toISOString().replace(/\.\d+Z$/, "Z").replace(/:/g, "-");
84
81
  }
85
82
  /**
86
- * PURE: build the run.yaml manifest object from the run metadata (RMG-002). `purpose` and
83
+ * PURE: build the run.yaml manifest object from the run metadata. `purpose` and
87
84
  * `links` are stamped EMPTY (the ad-hoc default; slugs are added by operator hand-edit of
88
85
  * run.yaml afterward — the documented curation convention); `artefacts` carry the decided
89
86
  * filenames. No IO — proven `@unit`.
@@ -113,21 +110,19 @@ export function serialiseRunManifest(manifest) {
113
110
  return stringify(manifest);
114
111
  }
115
112
  /**
116
- * IMPURE runner: `mkdir -p` the run dir, route the tool's `--format` outputs into the two
117
- * files via the injected `route` — the document as `md:<documentPath>`, the reconciliation
118
- * JSON as `json:<reconciliationJsonPath>` — and stamp `run.yaml` with the manifest built from the spec + `meta`
119
- * (RMG-002). Returns the plan it realised. The only IO. The `mkdir` is load-bearing: the
120
- * tool's writer uses `writeFileSync`, which needs the parent dir to exist — so the scaffold
121
- * creates the dir the location-agnostic tool writes into.
113
+ * IMPURE runner: `mkdir -p` the run dir, route the tool's `--format` outputs into the two files
114
+ * via the injected `route` — the document as `md:<documentPath>`, the reconciliation JSON as
115
+ * `json:<reconciliationJsonPath>` — and stamp `run.yaml` from the spec + `meta`. Returns the
116
+ * plan it realised. The `mkdir` is load-bearing: the tool's writer creates no directories, so the
117
+ * scaffold creates the one the location-agnostic tool writes into.
122
118
  */
123
119
  export function executeKeptRun(spec, meta, route) {
124
120
  const plan = planKeptRun(spec);
125
- mkdirSync(plan.runDir, { recursive: true });
121
+ writeOrRefuse("The stored run's directory could not be created", plan.runDir, () => mkdirSync(plan.runDir, { recursive: true }));
126
122
  route([`md:${plan.documentPath}`, `json:${plan.reconciliationJsonPath}`]);
127
- // Stamp run.yaml from the spec's run-id/target (so it can't drift from the run dir) + the
128
- // manifest-only meta. The serialised YAML is valid — the @integration parses it back.
129
123
  const manifest = planRunManifest({ runId: spec.runId, target: spec.target, ...meta });
130
- writeFileSync(join(plan.runDir, RUN_MANIFEST), serialiseRunManifest(manifest));
124
+ const manifestPath = join(plan.runDir, RUN_MANIFEST);
125
+ writeOrRefuse("The stored run's run.yaml could not be written", manifestPath, () => writeFileSync(manifestPath, serialiseRunManifest(manifest)));
131
126
  return plan;
132
127
  }
133
128
  //# sourceMappingURL=keptRun.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"keptRun.js","sourceRoot":"","sources":["../../src/run-management/keptRun.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keptRun.js","sourceRoot":"","sources":["../../src/run-management/keptRun.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spec-controller",
3
- "version": "0.1.0-alpha.30",
3
+ "version": "0.1.0-alpha.31",
4
4
  "description": "Reconcile the behaviour your scenarios name against the evidence that actually ran — the deterministic `balance` CLI.",
5
5
  "keywords": [
6
6
  "reconciliation",
@@ -25,7 +25,7 @@
25
25
  "@cucumber/gherkin": "^41.0.0",
26
26
  "@cucumber/messages": "^34.0.1",
27
27
  "yaml": "^2.9.0",
28
- "@3f-consulting/spec-controller-core": "0.1.0-alpha.30"
28
+ "@3f-consulting/spec-controller-core": "0.1.0-alpha.31"
29
29
  },
30
30
  "publishConfig": {
31
31
  "access": "public"