@am_shork/attest 0.2.2 → 0.4.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 (80) hide show
  1. package/CHANGELOG.md +876 -62
  2. package/README.md +157 -19
  3. package/dist/cli/index.js +91 -21
  4. package/dist/cli/index.js.map +1 -1
  5. package/dist/cli/json.d.ts +52 -5
  6. package/dist/cli/json.d.ts.map +1 -1
  7. package/dist/cli/json.js +50 -2
  8. package/dist/cli/json.js.map +1 -1
  9. package/dist/cli/report.d.ts +11 -1
  10. package/dist/cli/report.d.ts.map +1 -1
  11. package/dist/cli/report.js +114 -3
  12. package/dist/cli/report.js.map +1 -1
  13. package/dist/core/apply.d.ts +8 -0
  14. package/dist/core/apply.d.ts.map +1 -1
  15. package/dist/core/apply.js +10 -0
  16. package/dist/core/apply.js.map +1 -1
  17. package/dist/core/gate.d.ts +27 -1
  18. package/dist/core/gate.d.ts.map +1 -1
  19. package/dist/core/gate.js +48 -1
  20. package/dist/core/gate.js.map +1 -1
  21. package/dist/core/loader.d.ts +8 -0
  22. package/dist/core/loader.d.ts.map +1 -1
  23. package/dist/core/loader.js +19 -1
  24. package/dist/core/loader.js.map +1 -1
  25. package/dist/core/locate.d.ts +22 -1
  26. package/dist/core/locate.d.ts.map +1 -1
  27. package/dist/core/locate.js +76 -7
  28. package/dist/core/locate.js.map +1 -1
  29. package/dist/core/paths.d.ts +15 -0
  30. package/dist/core/paths.d.ts.map +1 -0
  31. package/dist/core/paths.js +36 -0
  32. package/dist/core/paths.js.map +1 -0
  33. package/dist/core/pipeline.d.ts +75 -5
  34. package/dist/core/pipeline.d.ts.map +1 -1
  35. package/dist/core/pipeline.js +212 -35
  36. package/dist/core/pipeline.js.map +1 -1
  37. package/dist/core/red-record.d.ts +56 -0
  38. package/dist/core/red-record.d.ts.map +1 -0
  39. package/dist/core/red-record.js +177 -0
  40. package/dist/core/red-record.js.map +1 -0
  41. package/dist/core/render.d.ts +1 -1
  42. package/dist/core/render.d.ts.map +1 -1
  43. package/dist/core/render.js +16 -2
  44. package/dist/core/render.js.map +1 -1
  45. package/dist/core/runner.d.ts +1 -1
  46. package/dist/core/runner.d.ts.map +1 -1
  47. package/dist/core/runner.js +36 -11
  48. package/dist/core/runner.js.map +1 -1
  49. package/dist/core/skill.d.ts +23 -0
  50. package/dist/core/skill.d.ts.map +1 -0
  51. package/dist/core/skill.js +276 -0
  52. package/dist/core/skill.js.map +1 -0
  53. package/dist/core/static-registry.d.ts +28 -0
  54. package/dist/core/static-registry.d.ts.map +1 -1
  55. package/dist/core/static-registry.js +91 -25
  56. package/dist/core/static-registry.js.map +1 -1
  57. package/dist/core/status.d.ts +39 -0
  58. package/dist/core/status.d.ts.map +1 -0
  59. package/dist/core/status.js +64 -0
  60. package/dist/core/status.js.map +1 -0
  61. package/dist/core/targets.d.ts +52 -0
  62. package/dist/core/targets.d.ts.map +1 -0
  63. package/dist/core/targets.js +141 -0
  64. package/dist/core/targets.js.map +1 -0
  65. package/dist/core/types.d.ts +13 -0
  66. package/dist/core/types.d.ts.map +1 -1
  67. package/dist/core/types.js.map +1 -1
  68. package/dist/core/validator.d.ts +11 -0
  69. package/dist/core/validator.d.ts.map +1 -1
  70. package/dist/core/validator.js +28 -12
  71. package/dist/core/validator.js.map +1 -1
  72. package/dist/core/write.d.ts +2 -0
  73. package/dist/core/write.d.ts.map +1 -0
  74. package/dist/core/write.js +21 -0
  75. package/dist/core/write.js.map +1 -0
  76. package/dist/runtime.d.ts +9 -1
  77. package/dist/runtime.d.ts.map +1 -1
  78. package/dist/runtime.js +10 -2
  79. package/dist/runtime.js.map +1 -1
  80. package/package.json +5 -5
@@ -2,14 +2,20 @@
2
2
  // tool-agnostic; the CLI is a thin shell that calls them and renders the result.
3
3
  import { createLoader } from './loader.js';
4
4
  import { evalReader, loadRegistry, parseSpecs, parseChangeSpecs, listChangeNames, scanProject, staticReader, } from './locate.js';
5
- import { validateStructure, detectPotentialDrift } from './validator.js';
5
+ import { validateStructure, detectPotentialDrift, uncoveredIssues } from './validator.js';
6
6
  import { byCodeUnit } from './order.js';
7
7
  import { runAndCollect } from './runner.js';
8
- import { applyDelta } from './apply.js';
8
+ import { applyDelta, addedIds } from './apply.js';
9
+ import { readDeltaSource } from './static-registry.js';
10
+ import { statusRows, statusCounts } from './status.js';
9
11
  import { evaluateGate, declaredNotRunIssues } from './gate.js';
10
12
  import { renderMarkdown, staleIssue } from './render.js';
11
- import { readFile } from 'node:fs/promises';
12
- import { join, relative } from 'node:path';
13
+ import { mergeRedRecord, readRedRecord, redRecordPath, serialiseRedRecord, } from './red-record.js';
14
+ import { DEFAULT_TARGET, resolveTargets } from './targets.js';
15
+ import { writeAtomic } from './write.js';
16
+ import { mkdir, readFile } from 'node:fs/promises';
17
+ import { basename, dirname, join } from 'node:path';
18
+ import { relativePath } from './paths.js';
13
19
  import { configDefaults } from 'vitest/config';
14
20
  import { hasError } from './types.js';
15
21
  /**
@@ -94,7 +100,11 @@ export async function runVerify(root, options = {}) {
94
100
  // the child run keeps an incumbent suite untouched; the verdict comes from
95
101
  // empty-spec or uncovered-requirement, both already ERRORs above.
96
102
  const run = attesting.length === 0
97
- ? { passed: true, runtimeCoverage: new Map() }
103
+ ? {
104
+ passed: true,
105
+ runtimeCoverage: new Map(),
106
+ outcomes: new Map(),
107
+ }
98
108
  : await runAndCollect({
99
109
  root,
100
110
  quiet: true,
@@ -107,22 +117,35 @@ export async function runVerify(root, options = {}) {
107
117
  issues.push(...declaredNotRunIssues(plan, run));
108
118
  return { issues, passed: run.passed, ok: run.passed && !hasError(issues), counts };
109
119
  }
110
- /** Coverage-only report (design §9: `attest cover`). */
120
+ /**
121
+ * Coverage-only report (design §9: `attest cover`).
122
+ *
123
+ * A registry that failed to load is reported, never coveraged. Discarding the
124
+ * load issues turned an unreadable registry into an empty one, and an empty
125
+ * registry is fully covered — so the command answered `ok: true` on exactly the
126
+ * repo whose intent layer had stopped being readable. Refusing here is the same
127
+ * call `runRender` makes for the same reason: a report computed from a
128
+ * half-loaded registry is a lie, and a lie that reads as a pass is the worst
129
+ * shape it can take.
130
+ */
111
131
  export async function runCover(root, options = {}) {
112
132
  const scan = await scanProject(root);
113
- const { registry } = await readRegistry(root, options, scan.reqsFiles);
133
+ const { registry, issues: loadIssues } = await readRegistry(root, options, scan.reqsFiles);
134
+ if (hasError(loadIssues))
135
+ return { rows: [], issues: loadIssues };
114
136
  const plan = await parseSpecs(scan.specFiles, root);
115
137
  const counts = new Map();
116
138
  for (const s of plan.scenarios) {
117
139
  counts.set(s.reqId, (counts.get(s.reqId) ?? 0) + 1);
118
140
  }
119
- return Object.keys(registry)
141
+ const rows = Object.keys(registry)
120
142
  .sort()
121
143
  .map((reqId) => ({
122
144
  reqId,
123
145
  covered: (counts.get(reqId) ?? 0) > 0,
124
146
  scenarioCount: counts.get(reqId) ?? 0,
125
147
  }));
148
+ return { rows, issues: [...loadIssues, ...uncoveredIssues(registry, plan)] };
126
149
  }
127
150
  /**
128
151
  * Markdown projection of the intent layer (design §9: `attest render`).
@@ -155,6 +178,35 @@ export async function runRenderCheck(root, outFile, target, options = {}) {
155
178
  const stale = staleIssue(target, current, markdown);
156
179
  return stale ? [...issues, stale] : issues;
157
180
  }
181
+ export { SKILL_FILE, skillContent, TARGETS, TARGET_NAMES, DEFAULT_TARGET } from './targets.js';
182
+ /**
183
+ * `attest init`: write the workflow document for each agent target asked for.
184
+ *
185
+ * Naming none means the default one, decided here rather than in the CLI: it is
186
+ * what `init` does, not how a flag parses, and the CLI is a shell over these.
187
+ *
188
+ * Nothing is written while any name is unresolvable. A partial write would
189
+ * leave the repo carrying instructions for some agents and a failing command
190
+ * with no way to tell which — and the whole reason this is safe to put in a
191
+ * script is that its effect is the same on every run.
192
+ *
193
+ * Each file is a pure function of nothing, so re-running after an upgrade is the
194
+ * entire update mechanism (design §9); the write is atomic because every file
195
+ * Attest writes is one the user commits.
196
+ */
197
+ export async function runInit(root, names) {
198
+ const { targets, issues } = resolveTargets(names.length > 0 ? names : [DEFAULT_TARGET]);
199
+ if (issues.length > 0)
200
+ return { files: [], issues };
201
+ const files = [];
202
+ for (const target of targets) {
203
+ const dest = join(root, target.file);
204
+ await mkdir(dirname(dest), { recursive: true });
205
+ await writeAtomic(dest, target.content());
206
+ files.push(target.file);
207
+ }
208
+ return { files, issues };
209
+ }
158
210
  /**
159
211
  * A change name must name one directory inside `changes/`, and nothing else.
160
212
  *
@@ -189,53 +241,162 @@ export function changeExcludeGlobs(others) {
189
241
  return others.map((n) => `**/changes/${escapeGlob(n)}/**`);
190
242
  }
191
243
  function escapeGlob(name) {
192
- return name.replace(/[*?[\]{}()!+@|^$]/g, '\\$&');
244
+ // The backslash comes first, and it is the one that matters most: it is
245
+ // glob's own escape character, so a name containing one is not merely
246
+ // unescaped, it silently rewrites the pattern around it. On POSIX a
247
+ // backslash is a legal filename character, so `changes/a\b` produced the
248
+ // exclude glob `**/changes/a\b/**`, which globbing reads as an escaped `b` —
249
+ // matching `ab`, never the directory itself. That sibling's specs then
250
+ // joined the gate run, quietly widening the scope of the one check that
251
+ // decides whether a change is done.
252
+ //
253
+ // Escaped rather than rejected, because these names are not the change name
254
+ // the guard above screens: they come from `readdir`, and a directory that
255
+ // exists is not ours to refuse.
256
+ return name.replace(/[\\*?[\]{}()!+@|^$]/g, '\\$&');
257
+ }
258
+ /** The delta a change is declared in (design §7). */
259
+ const CHANGE_DELTA_FILE = 'requirements.delta.ts';
260
+ function changeDeltaPath(root, changeName) {
261
+ return join(root, 'changes', changeName, CHANGE_DELTA_FILE);
262
+ }
263
+ /** The guard's refusal, as the issue every change-scoped command reports. */
264
+ function invalidChangeNameIssue(changeName) {
265
+ return {
266
+ level: 'ERROR',
267
+ code: 'invalid-change-name',
268
+ message: `Invalid change name ${JSON.stringify(changeName)}. A change name must be one directory inside changes/: it cannot be empty, "." or "..", or contain a path separator.`,
269
+ };
270
+ }
271
+ function changeNotFoundIssue(root, deltaPath, changeName, err) {
272
+ return {
273
+ level: 'ERROR',
274
+ code: 'change-not-found',
275
+ file: relativePath(root, deltaPath),
276
+ message: `Could not find or load the delta for change "${changeName}": ${err instanceof Error ? err.message : String(err)}`,
277
+ };
278
+ }
279
+ /**
280
+ * Read a change's delta the way `options` asks for, or the one issue that
281
+ * stopped it.
282
+ *
283
+ * The static path is the default for the same reason it is for `check`, `cover`
284
+ * and `render` (design §5.1): a command that only reports has no business
285
+ * executing a file out of `changes/`, where the content is by definition still
286
+ * under review. `archive` evaluates unconditionally because it runs the suite
287
+ * anyway, so declining to evaluate one more module would buy it nothing.
288
+ */
289
+ async function readDelta(root, changeName, options) {
290
+ const deltaPath = changeDeltaPath(root, changeName);
291
+ if (options.evaluate) {
292
+ const loader = await createLoader();
293
+ try {
294
+ const mod = await loader.load(deltaPath);
295
+ if (!mod.default || typeof mod.default !== 'object') {
296
+ return {
297
+ issue: changeNotFoundIssue(root, deltaPath, changeName, new Error(`${CHANGE_DELTA_FILE} must default-export the result of delta(...).`)),
298
+ };
299
+ }
300
+ return { delta: mod.default };
301
+ }
302
+ catch (err) {
303
+ return { issue: changeNotFoundIssue(root, deltaPath, changeName, err) };
304
+ }
305
+ finally {
306
+ await loader.close();
307
+ }
308
+ }
309
+ let source;
310
+ try {
311
+ source = await readFile(deltaPath, 'utf8');
312
+ }
313
+ catch (err) {
314
+ return { issue: changeNotFoundIssue(root, deltaPath, changeName, err) };
315
+ }
316
+ const read = readDeltaSource(basename(deltaPath), source);
317
+ if (read.ok)
318
+ return { delta: read.delta };
319
+ return {
320
+ issue: {
321
+ level: 'ERROR',
322
+ code: read.code,
323
+ file: relativePath(root, deltaPath),
324
+ message: read.message,
325
+ ...(read.line === undefined ? {} : { line: read.line }),
326
+ },
327
+ };
328
+ }
329
+ /**
330
+ * The static plan a change is gated and reported against: the base suite plus
331
+ * the change's own specs (design §8). Takes the spec files rather than finding
332
+ * them, so a caller that already scanned the tree does not walk it twice.
333
+ */
334
+ async function changeMergedPlan(root, changeName, specFiles) {
335
+ const basePlan = await parseSpecs(specFiles, root);
336
+ const changePlan = await parseChangeSpecs(root, changeName);
337
+ return {
338
+ scenarios: [...basePlan.scenarios, ...changePlan.scenarios],
339
+ paramRefs: [...basePlan.paramRefs, ...changePlan.paramRefs],
340
+ };
341
+ }
342
+ /** Per-change progress (design §9: `attest status <change>`). */
343
+ export async function runStatus(root, changeName, options = {}) {
344
+ const nothing = (issues) => ({
345
+ change: changeName,
346
+ rows: [],
347
+ counts: statusCounts([]),
348
+ issues,
349
+ });
350
+ // Checked before anything is read on the name's behalf, for the reason the
351
+ // gate checks it: under `--eval` the name reaches a module that is executed.
352
+ if (!isSafeChangeName(changeName))
353
+ return nothing([invalidChangeNameIssue(changeName)]);
354
+ const read = await readDelta(root, changeName, options);
355
+ if ('issue' in read)
356
+ return nothing([read.issue]);
357
+ const scan = await scanProject(root);
358
+ const plan = await changeMergedPlan(root, changeName, scan.specFiles);
359
+ const firstRun = await readRedRecord(root, changeName);
360
+ const rows = statusRows(addedIds(read.delta), plan, firstRun);
361
+ return { change: changeName, rows, counts: statusCounts(rows), issues: [] };
193
362
  }
194
363
  /** Archive gate for a change (design §8, §9: `attest archive <change>`). */
195
364
  export async function runArchive(root, changeName, options = {}) {
196
365
  // Checked before any loader starts: nothing should be resolved, let alone
197
366
  // evaluated, on behalf of a name we have already rejected.
198
- if (!isSafeChangeName(changeName)) {
199
- return [
200
- {
201
- level: 'ERROR',
202
- code: 'invalid-change-name',
203
- message: `Invalid change name ${JSON.stringify(changeName)}. A change name must be one directory inside changes/: it cannot be empty, "." or "..", or contain a path separator.`,
204
- },
205
- ];
206
- }
367
+ if (!isSafeChangeName(changeName))
368
+ return [invalidChangeNameIssue(changeName)];
207
369
  const scan = await scanProject(root);
208
370
  const loader = await createLoader();
209
371
  try {
210
372
  const { registry: base, issues } = await loadRegistry(root, evalReader(loader), scan.reqsFiles);
211
373
  if (issues.some((i) => i.level === 'ERROR'))
212
374
  return issues;
213
- const deltaPath = join(root, 'changes', changeName, 'requirements.delta.ts');
375
+ const deltaPath = changeDeltaPath(root, changeName);
214
376
  let delta;
215
377
  try {
216
378
  const mod = await loader.load(deltaPath);
379
+ // The same check `readDelta` makes, for the same file. Without it a delta
380
+ // file that loads but exports nothing reached `applyDelta` as `undefined`,
381
+ // where `d.renamed ?? []` threw a TypeError — so `archive` answered
382
+ // `internal-error` for a file `status` already diagnoses as
383
+ // `change-not-found`, and the fix hint went with it. Two commands reading
384
+ // one file must not disagree about what is wrong with it.
385
+ if (!mod.default || typeof mod.default !== 'object') {
386
+ throw new Error(`${CHANGE_DELTA_FILE} must default-export the result of delta(...).`);
387
+ }
217
388
  delta = mod.default;
218
389
  }
219
390
  catch (err) {
220
- return [
221
- {
222
- level: 'ERROR',
223
- code: 'change-not-found',
224
- file: relative(root, deltaPath),
225
- message: `Could not find or load the delta for change "${changeName}": ${err instanceof Error ? err.message : String(err)}`,
226
- },
227
- ];
391
+ return [changeNotFoundIssue(root, deltaPath, changeName, err)];
228
392
  }
229
393
  const applied = applyDelta(base, delta);
230
394
  if (applied.issues.length > 0)
231
395
  return applied.issues;
232
- // Static plan = merged base suite + this change's specs (design §8).
233
- const basePlan = await parseSpecs(scan.specFiles, root);
234
- const changePlan = await parseChangeSpecs(root, changeName);
235
- const plan = {
236
- scenarios: [...basePlan.scenarios, ...changePlan.scenarios],
237
- paramRefs: [...basePlan.paramRefs, ...changePlan.paramRefs],
238
- };
396
+ // Static plan = merged base suite + this change's specs (design §8), by the
397
+ // same function `status` reports against — a progress report computed over a
398
+ // different spec set than the gate uses would be a report about nothing.
399
+ const plan = await changeMergedPlan(root, changeName, scan.specFiles);
239
400
  // Run base specs + this change's specs; exclude other proposals and archive.
240
401
  const others = (await listChangeNames(root)).filter((n) => n !== changeName);
241
402
  const exclude = [
@@ -253,7 +414,23 @@ export async function runArchive(root, changeName, options = {}) {
253
414
  exclude,
254
415
  vitestConfig: options.vitestConfig,
255
416
  });
256
- return evaluateGate({ registry: applied.registry, plan, run });
417
+ // Mechanism 2 (design §6). The stage-1 run of this same command is where a
418
+ // scenario is *supposed* to be red, so recording happens on every archive
419
+ // run, before the verdict — a run whose gate fails is exactly the run whose
420
+ // observation matters most. First write wins, so the green run at the end
421
+ // cannot overwrite the red that came before it.
422
+ const added = addedIds(delta);
423
+ let firstRun = await readRedRecord(root, changeName);
424
+ if (added.length > 0) {
425
+ const merged = mergeRedRecord(firstRun, plan, run, added);
426
+ firstRun = merged.record;
427
+ // Only when something was actually learned: re-running the gate on an
428
+ // unchanged change must not dirty the working tree.
429
+ if (merged.changed) {
430
+ await writeAtomic(redRecordPath(root, changeName), serialiseRedRecord(changeName, merged.record));
431
+ }
432
+ }
433
+ return evaluateGate({ registry: applied.registry, plan, run, addedIds: added, firstRun });
257
434
  }
258
435
  finally {
259
436
  await loader.close();
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,iFAAiF;AAEjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,UAAU,EACV,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAiBtC;;;GAGG;AACH,KAAK,UAAU,YAAY,CACzB,IAAY,EACZ,OAAoB,EACpB,KAAgB;IAEhB,IAAI,CAAC,OAAO,CAAC,QAAQ;QAAE,OAAO,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,MAAM,YAAY,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,OAAO,MAAM,YAAY,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;IAC7D,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;AACH,CAAC;AAED,2DAA2D;AAC3D,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,UAAuB,EAAE;IACpE,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/E,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACpD,OAAO;QACL,GAAG,MAAM;QACT,GAAG,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC;QACpC,GAAG,oBAAoB,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;KACxD,CAAC;AACJ,CAAC;AAqBD;;;;;;;;GAQG;AACH,SAAS,cAAc,CAAC,IAAgB;IACtC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAC1E,CAAC;AAQD,4DAA4D;AAC5D,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY,EAAE,UAAsB,EAAE;IACpE,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,MAAM,YAAY,EAAE,CAAC;IACpC,IAAI,QAAkB,CAAC;IACvB,IAAI,IAAgB,CAAC;IACrB,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5E,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAChD,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;IAClD,MAAM,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IAErE,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,MAAM,GAAiB;QAC3B,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM;QAC1C,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM;QAChC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM;QAChC,SAAS,EAAE,SAAS,CAAC,MAAM;KAC5B,CAAC;IAEF,wEAAwE;IACxE,0EAA0E;IAC1E,6EAA6E;IAC7E,4EAA4E;IAC5E,8EAA8E;IAC9E,yEAAyE;IACzE,2CAA2C;IAC3C,IAAI,MAAM,CAAC,YAAY,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC;YACV,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,YAAY;YAClB,OAAO,EACL,uEAAuE;gBACvE,yEAAyE;SAC5E,CAAC,CAAC;IACL,CAAC;IAED,2EAA2E;IAC3E,2EAA2E;IAC3E,kEAAkE;IAClE,MAAM,GAAG,GACP,SAAS,CAAC,MAAM,KAAK,CAAC;QACpB,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,GAAG,EAAuB,EAAE;QACnE,CAAC,CAAC,MAAM,aAAa,CAAC;YAClB,IAAI;YACJ,KAAK,EAAE,IAAI;YACX,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC;YAClC,YAAY,EAAE,OAAO,CAAC,YAAY;SACnC,CAAC,CAAC;IACT,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;IAEhD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;AACrF,CAAC;AAQD,wDAAwD;AACxD,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,UAAuB,EAAE;IACpE,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;SACzB,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACf,KAAK;QACL,OAAO,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC;QACrC,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;KACtC,CAAC,CAAC,CAAC;AACR,CAAC;AASD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY,EAAE,UAAuB,EAAE;IACrE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/D,uEAAuE;IACvE,sEAAsE;IACtE,IAAI,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IACtD,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;AACxD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAY,EACZ,OAAe,EACf,MAAoB,EACpB,UAAuB,EAAE;IAEzB,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5D,IAAI,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAEpC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACvE,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAC7C,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAS,gBAAgB,CAAC,IAAY;IACpC,OAAO,CACL,IAAI,KAAK,EAAE;QACX,IAAI,KAAK,GAAG;QACZ,IAAI,KAAK,IAAI;QACb,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QACnB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QACpB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CACrB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAgB;IACjD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAC7D,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,UAAkB,EAClB,UAAsB,EAAE;IAExB,0EAA0E;IAC1E,2DAA2D;IAC3D,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,OAAO;YACL;gBACE,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,qBAAqB;gBAC3B,OAAO,EAAE,uBAAuB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,sHAAsH;aACjL;SACF,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,MAAM,YAAY,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAChG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC;YAAE,OAAO,MAAM,CAAC;QAE3D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,uBAAuB,CAAC,CAAC;QAC7E,IAAI,KAAoB,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAA6B,SAAS,CAAC,CAAC;YACrE,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC;QACtB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL;oBACE,KAAK,EAAE,OAAO;oBACd,IAAI,EAAE,kBAAkB;oBACxB,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;oBAC/B,OAAO,EAAE,gDAAgD,UAAU,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;iBAC5H;aACF,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACxC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC;QAErD,qEAAqE;QACrE,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACxD,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAC5D,MAAM,IAAI,GAAe;YACvB,SAAS,EAAE,CAAC,GAAG,QAAQ,CAAC,SAAS,EAAE,GAAG,UAAU,CAAC,SAAS,CAAC;YAC3D,SAAS,EAAE,CAAC,GAAG,QAAQ,CAAC,SAAS,EAAE,GAAG,UAAU,CAAC,SAAS,CAAC;SAC5D,CAAC;QAEF,6EAA6E;QAC7E,MAAM,MAAM,GAAG,CAAC,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC;QAC7E,MAAM,OAAO,GAAG;YACd,GAAG,cAAc,CAAC,OAAO;YACzB,eAAe;YACf,GAAG,kBAAkB,CAAC,MAAM,CAAC;SAC9B,CAAC;QACF,2EAA2E;QAC3E,2EAA2E;QAC3E,oDAAoD;QACpD,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC;YAC9B,IAAI;YACJ,KAAK,EAAE,IAAI;YACX,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC;YAC7C,OAAO;YACP,YAAY,EAAE,OAAO,CAAC,YAAY;SACnC,CAAC,CAAC;QAEH,OAAO,YAAY,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IACjE,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import type { AttestPlan, Outcome, RunResult } from './types.js';
2
+ /** Where the record lives, relative to the project root. */
3
+ export declare function redRecordPath(root: string, changeName: string): string;
4
+ /** The file name, exported so a diagnostic can name it without rebuilding it. */
5
+ export declare const RED_RECORD_FILE = "first-run.json";
6
+ /**
7
+ * reqId -> scenario name -> the outcome of its first observed run.
8
+ *
9
+ * Deliberately not a list of "red scenarios": a scenario whose first run passed
10
+ * is the case mechanism 2 exists to catch, so it has to be recorded as a fact
11
+ * rather than as an absence. An absence then means only one thing — never
12
+ * observed at all — and the gate can report the two separately.
13
+ */
14
+ export type RedRecord = Record<string, Record<string, Outcome>>;
15
+ /**
16
+ * Read the record for a change. A missing or unreadable file is an empty
17
+ * record, never an error: the first stage-1 run legitimately finds nothing, and
18
+ * a corrupt file must not be more permissive than a missing one — with an empty
19
+ * record every obligation is "never observed", which the gate blocks on.
20
+ *
21
+ * A file whose `firstRun` does not validate is discarded whole rather than
22
+ * per-entry, which is the same "as strict as a missing file" rule one step
23
+ * further: the cost is a stage-1 run to re-observe, and the alternative — keeping
24
+ * the entries that happened to parse — reports a partial history as if it were
25
+ * the whole one.
26
+ */
27
+ export declare function readRedRecord(root: string, changeName: string): Promise<RedRecord>;
28
+ /** What the record says about one scenario, or undefined if it never saw it. */
29
+ export declare function recordedOutcome(record: RedRecord, reqId: string, scenario: string): Outcome | undefined;
30
+ /**
31
+ * Whether this scenario has satisfied the first-red obligation (design §6).
32
+ *
33
+ * One definition, because two readers now decide on it: the gate blocks when it
34
+ * is false, and `status` reports what the gate will do before it is run. A
35
+ * second spelling of `=== 'fail'` would let the report and the verdict drift
36
+ * apart — the same argument that extracted `declaredNotRunIssues` and
37
+ * `uncoveredIssues` from the commands that had a copy each.
38
+ */
39
+ export declare function hasRecordedRed(record: RedRecord, reqId: string, scenario: string): boolean;
40
+ /**
41
+ * Fold this run's outcomes into the record, for the scenarios that carry an
42
+ * obligation — those covering a requirement this change ADDs.
43
+ *
44
+ * Scoped that way rather than to every scenario in the run, because the base
45
+ * suite's scenarios have no obligation here and recording them would grow a file
46
+ * nobody reads with facts nothing checks. Returns the merged record and whether
47
+ * anything changed, so an unchanged record is not rewritten (an archive run that
48
+ * only re-reads must not dirty the working tree).
49
+ */
50
+ export declare function mergeRedRecord(existing: RedRecord, plan: AttestPlan, run: RunResult, addedIds: readonly string[]): {
51
+ record: RedRecord;
52
+ changed: boolean;
53
+ };
54
+ /** Serialise the record. A trailing newline, so the file is a well-formed text file. */
55
+ export declare function serialiseRedRecord(changeName: string, record: RedRecord): string;
56
+ //# sourceMappingURL=red-record.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"red-record.d.ts","sourceRoot":"","sources":["../../src/core/red-record.ts"],"names":[],"mappings":"AAiDA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGjE,4DAA4D;AAC5D,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED,iFAAiF;AACjF,eAAO,MAAM,eAAe,mBAAmB,CAAC;AAEhD;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AA8BhE;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAkBxF;AAED,gFAAgF;AAChF,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,OAAO,GAAG,SAAS,CAErB;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE1F;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,SAAS,EACnB,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,SAAS,EACd,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAmCzC;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,MAAM,CAGhF"}
@@ -0,0 +1,177 @@
1
+ // Mechanism 2's record: what each of a change's scenarios did the *first* time
2
+ // it ran (design §6).
3
+ //
4
+ // §8's gate requires green at archive time. That certifies "these tests pass",
5
+ // not "these tests ever discriminated" — a scenario that asserted nothing has
6
+ // been green since the commit that added it and clears the gate exactly like one
7
+ // that drove an implementation. Closing that needs a fact about history, and
8
+ // history needs a record: nothing observable at archive time can distinguish the
9
+ // two, because by then both are green.
10
+ //
11
+ // **The observation point already existed.** The workflow (§9, and the skill
12
+ // `attest init` writes) has stage 1 run `attest archive <name>` and *expect*
13
+ // `tests-red`. The engine saw every one of those reds and threw them away. This
14
+ // file keeps them.
15
+ //
16
+ // **Why a generated file, committed, is acceptable here and nowhere else.** This
17
+ // project treats a committed generated artifact as a liability — the argument
18
+ // against `init --check`, and the reason `render` takes no formatting options.
19
+ // The difference is lifetime. `changes/<name>/` is temporary by construction: it
20
+ // exists while a change is in flight and goes away when the change is archived,
21
+ // so this file has exactly the change's lifetime and never becomes a permanent
22
+ // asset that can drift. It is also *evidence*, and evidence belongs in the diff
23
+ // a reviewer reads.
24
+ //
25
+ // It has to be committed rather than kept in a scratch directory, because the
26
+ // gate must reach the same verdict on a CI runner's fresh checkout as it does on
27
+ // the author's machine — a witness that only exists locally would block every
28
+ // change that CI archives.
29
+ //
30
+ // **A fail is sticky; a pass is provisional.** The record moves one way only,
31
+ // toward `fail`, and the asymmetry is load-bearing in both directions.
32
+ //
33
+ // Sticky fail: recording the latest outcome would erase the very fact being
34
+ // recorded, because by the time a change is archivable everything is green — a
35
+ // last-write-wins record says "green" about a scenario that spent the whole
36
+ // change red. Once a scenario has been seen to fail, nothing can take it back.
37
+ //
38
+ // Provisional pass: plain first-write-wins was the first design here, and it
39
+ // makes the defect this mechanism exists to catch *unrecoverable*. A scenario
40
+ // that passed on its first run is one that asserts nothing; the fix is to give
41
+ // it a real assertion and watch it fail — but under first-write-wins that
42
+ // observation could never be recorded, so the only way out was deleting the
43
+ // record by hand, a manual step that would equally let someone delete a genuine
44
+ // red. Allowing a later `fail` to replace an earlier `pass` cannot be abused,
45
+ // because the only way to produce one is for the scenario to actually fail.
46
+ import { readFile } from 'node:fs/promises';
47
+ import { join } from 'node:path';
48
+ import { z } from 'zod';
49
+ import { byCodeUnit } from './order.js';
50
+ /** Where the record lives, relative to the project root. */
51
+ export function redRecordPath(root, changeName) {
52
+ return join(root, 'changes', changeName, RED_RECORD_FILE);
53
+ }
54
+ /** The file name, exported so a diagnostic can name it without rebuilding it. */
55
+ export const RED_RECORD_FILE = 'first-run.json';
56
+ /**
57
+ * The record as it is allowed to come back off disk.
58
+ *
59
+ * The values are the two `Outcome`s and nothing else. Reading the file used to
60
+ * be `JSON.parse(raw) as RedRecordFile` followed by an "is it an object" probe
61
+ * declared as `value is RedRecord` — a type predicate that checked the
62
+ * container and asserted the contents. A hand-edited or half-written file then
63
+ * put an arbitrary string where an `Outcome` is declared, and it travelled: out
64
+ * through `StatusRow.scenarios[].firstRun`, whose type says `Outcome | null`,
65
+ * into the `--json` contract, and into a human row whose hint counted it as
66
+ * neither `pass` nor never-run and so rendered blank.
67
+ *
68
+ * The gate was never at risk — `hasRecordedRed` compares against `'fail'`, so an
69
+ * unrecognised value blocks exactly like a missing one. This closes the report.
70
+ */
71
+ const RedRecordSchema = z.record(z.string(), z.record(z.string(), z.enum(['pass', 'fail'])));
72
+ /**
73
+ * Read the record for a change. A missing or unreadable file is an empty
74
+ * record, never an error: the first stage-1 run legitimately finds nothing, and
75
+ * a corrupt file must not be more permissive than a missing one — with an empty
76
+ * record every obligation is "never observed", which the gate blocks on.
77
+ *
78
+ * A file whose `firstRun` does not validate is discarded whole rather than
79
+ * per-entry, which is the same "as strict as a missing file" rule one step
80
+ * further: the cost is a stage-1 run to re-observe, and the alternative — keeping
81
+ * the entries that happened to parse — reports a partial history as if it were
82
+ * the whole one.
83
+ */
84
+ export async function readRedRecord(root, changeName) {
85
+ let raw;
86
+ try {
87
+ raw = await readFile(redRecordPath(root, changeName), 'utf8');
88
+ }
89
+ catch {
90
+ return {};
91
+ }
92
+ let parsed;
93
+ try {
94
+ parsed = JSON.parse(raw);
95
+ }
96
+ catch {
97
+ return {};
98
+ }
99
+ // `JSON.parse` yields `any`; nothing about the file is known until the schema
100
+ // says so, including whether it is an object at all (`JSON.parse('null')`).
101
+ const firstRun = isRecord(parsed) ? parsed['firstRun'] : undefined;
102
+ const result = RedRecordSchema.safeParse(firstRun);
103
+ return result.success ? result.data : {};
104
+ }
105
+ /** What the record says about one scenario, or undefined if it never saw it. */
106
+ export function recordedOutcome(record, reqId, scenario) {
107
+ return record[reqId]?.[scenario];
108
+ }
109
+ /**
110
+ * Whether this scenario has satisfied the first-red obligation (design §6).
111
+ *
112
+ * One definition, because two readers now decide on it: the gate blocks when it
113
+ * is false, and `status` reports what the gate will do before it is run. A
114
+ * second spelling of `=== 'fail'` would let the report and the verdict drift
115
+ * apart — the same argument that extracted `declaredNotRunIssues` and
116
+ * `uncoveredIssues` from the commands that had a copy each.
117
+ */
118
+ export function hasRecordedRed(record, reqId, scenario) {
119
+ return recordedOutcome(record, reqId, scenario) === 'fail';
120
+ }
121
+ /**
122
+ * Fold this run's outcomes into the record, for the scenarios that carry an
123
+ * obligation — those covering a requirement this change ADDs.
124
+ *
125
+ * Scoped that way rather than to every scenario in the run, because the base
126
+ * suite's scenarios have no obligation here and recording them would grow a file
127
+ * nobody reads with facts nothing checks. Returns the merged record and whether
128
+ * anything changed, so an unchanged record is not rewritten (an archive run that
129
+ * only re-reads must not dirty the working tree).
130
+ */
131
+ export function mergeRedRecord(existing, plan, run, addedIds) {
132
+ const added = new Set(addedIds);
133
+ const record = {};
134
+ // Rebuild rather than mutate, so key order is a function of the data and two
135
+ // machines write byte-identical files (the same reason `render` orders ids
136
+ // through one code-unit comparator).
137
+ for (const id of Object.keys(existing).sort(byCodeUnit)) {
138
+ record[id] = { ...existing[id] };
139
+ }
140
+ let changed = false;
141
+ for (const s of plan.scenarios) {
142
+ if (!added.has(s.reqId))
143
+ continue;
144
+ const outcome = run.outcomes.get(s.reqId)?.get(s.name);
145
+ // No outcome means the scenario did not execute. That is `declared-not-run`,
146
+ // reported by the gate on its own terms; writing nothing here leaves the
147
+ // obligation unobserved rather than inventing a state for it.
148
+ if (!outcome)
149
+ continue;
150
+ const forId = (record[s.reqId] ??= {});
151
+ // Monotonic toward `fail`: a recorded fail is final, a recorded pass can
152
+ // still be corrected by a real one. See the note at the top of this file.
153
+ if (forId[s.name] === 'fail' || forId[s.name] === outcome)
154
+ continue;
155
+ forId[s.name] = outcome;
156
+ changed = true;
157
+ }
158
+ // Sort within each requirement for the same byte-stability reason.
159
+ for (const id of Object.keys(record)) {
160
+ const sorted = {};
161
+ for (const name of Object.keys(record[id]).sort(byCodeUnit)) {
162
+ sorted[name] = record[id][name];
163
+ }
164
+ record[id] = sorted;
165
+ }
166
+ return { record, changed };
167
+ }
168
+ /** Serialise the record. A trailing newline, so the file is a well-formed text file. */
169
+ export function serialiseRedRecord(changeName, record) {
170
+ const file = { version: 1, change: changeName, firstRun: record };
171
+ return `${JSON.stringify(file, null, 2)}\n`;
172
+ }
173
+ /** Container check only — what is *in* it is the schema's business, not this. */
174
+ function isRecord(value) {
175
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
176
+ }
177
+ //# sourceMappingURL=red-record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"red-record.js","sourceRoot":"","sources":["../../src/core/red-record.ts"],"names":[],"mappings":"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"}
@@ -23,7 +23,7 @@ export interface RenderTarget {
23
23
  }
24
24
  /**
25
25
  * The freshness verdict for a committed rendering: `undefined` when the file on
26
- * disk is exactly what the registry renders to now, an ERROR otherwise.
26
+ * disk is the document the registry renders to now, an ERROR otherwise.
27
27
  *
28
28
  * The two failures get distinct codes — `missing-spec-doc` for a rendering that
29
29
  * was never generated, `stale-spec-doc` for one whose bytes drifted — even
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/core/render.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAe,MAAM,YAAY,CAAC;AAQ/D;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAezD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,KAAK,EAAE,MAAM,GACZ,KAAK,GAAG,SAAS,CAYnB"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/core/render.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAe,MAAM,YAAY,CAAC;AAQ/D;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAezD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;CACjB;AAiBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,KAAK,EAAE,MAAM,GACZ,KAAK,GAAG,SAAS,CAYnB"}