truecourse 0.7.0-next.3 → 0.7.0-next.4

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/server.mjs CHANGED
@@ -109,7 +109,7 @@ var require_package = __commonJS({
109
109
  // node_modules/.pnpm/dotenv@16.6.1/node_modules/dotenv/lib/main.js
110
110
  var require_main = __commonJS({
111
111
  "node_modules/.pnpm/dotenv@16.6.1/node_modules/dotenv/lib/main.js"(exports, module) {
112
- var fs66 = __require("fs");
112
+ var fs67 = __require("fs");
113
113
  var path74 = __require("path");
114
114
  var os10 = __require("os");
115
115
  var crypto6 = __require("crypto");
@@ -218,7 +218,7 @@ var require_main = __commonJS({
218
218
  if (options && options.path && options.path.length > 0) {
219
219
  if (Array.isArray(options.path)) {
220
220
  for (const filepath of options.path) {
221
- if (fs66.existsSync(filepath)) {
221
+ if (fs67.existsSync(filepath)) {
222
222
  possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
223
223
  }
224
224
  }
@@ -228,7 +228,7 @@ var require_main = __commonJS({
228
228
  } else {
229
229
  possibleVaultPath = path74.resolve(process.cwd(), ".env.vault");
230
230
  }
231
- if (fs66.existsSync(possibleVaultPath)) {
231
+ if (fs67.existsSync(possibleVaultPath)) {
232
232
  return possibleVaultPath;
233
233
  }
234
234
  return null;
@@ -277,7 +277,7 @@ var require_main = __commonJS({
277
277
  const parsedAll = {};
278
278
  for (const path75 of optionPaths) {
279
279
  try {
280
- const parsed = DotenvModule.parse(fs66.readFileSync(path75, { encoding }));
280
+ const parsed = DotenvModule.parse(fs67.readFileSync(path75, { encoding }));
281
281
  DotenvModule.populate(parsedAll, parsed, options);
282
282
  } catch (e) {
283
283
  if (debug2) {
@@ -28079,7 +28079,7 @@ function parseBlockedOnCapabilities(reason) {
28079
28079
  return [];
28080
28080
  return m[1].split(",").map((s) => s.trim()).filter(Boolean);
28081
28081
  }
28082
- var GuardWrittenScenarioSchema, GuardCoverageGapKindSchema, GuardCoverageGapSchema, GuardBirthFindingSchema, GuardGenerateErrorSchema, GuardEntryPreflightSchema, GuardExtractionFailureSchema, GuardOrphanedSectionSchema, GuardRecipeReportSchema, GuardGenerateUsageSchema, GuardGenerateReportSchema;
28082
+ var GuardWrittenScenarioSchema, GuardCoverageGapKindSchema, GuardCoverageGapSchema, GuardBirthFindingSchema, GuardGenerateErrorSchema, GuardReadyScenarioSchema, GuardHeldSectionSchema, GuardEntryPreflightSchema, GuardExtractionFailureSchema, GuardOrphanedDismissalSchema, GuardOrphanedSectionSchema, GuardRecipeReportSchema, GuardGenerateUsageSchema, GuardGenerateReportSchema;
28083
28083
  var init_report = __esm({
28084
28084
  "packages/shared/dist/guard/report.js"() {
28085
28085
  "use strict";
@@ -28097,7 +28097,8 @@ var init_report = __esm({
28097
28097
  "awaiting-driver",
28098
28098
  "untestable",
28099
28099
  "no-claim",
28100
- "blocked-on"
28100
+ "blocked-on",
28101
+ "dismissed"
28101
28102
  ]);
28102
28103
  GuardCoverageGapSchema = external_exports.object({
28103
28104
  doc: external_exports.string(),
@@ -28119,6 +28120,22 @@ var init_report = __esm({
28119
28120
  actual: external_exports.string(),
28120
28121
  /** Repo-relative pointer into `guard/evidence/`, when a transcript was written. */
28121
28122
  evidencePath: external_exports.string().optional(),
28123
+ /**
28124
+ * The failed candidate's authored YAML, serialized inline AT FINDING CREATION
28125
+ * (same serialize-at-creation as heldSections' readyScenarios). The finding
28126
+ * detail renders it in the scenario-source code block so the user can judge
28127
+ * "defect or drift" with the exact commands the scenario ran on-screen.
28128
+ * Optional so older `result.json` files keep parsing.
28129
+ */
28130
+ yaml: external_exports.string().optional(),
28131
+ /**
28132
+ * The EXTRACTED CLAIM's stable text — the claim identity a dismissal keys on
28133
+ * (anchor + this). The finding detail's Dismiss action writes it into
28134
+ * `scenarios/decisions.json`; generate then skips a matching claim before
28135
+ * authoring. Distinct from `title` (the scenario title). Optional so older
28136
+ * reports (and the internal retry-evidence findings) parse.
28137
+ */
28138
+ claim: external_exports.string().optional(),
28122
28139
  /**
28123
28140
  * The bound section's human heading, joined SERVER-SIDE at report read time
28124
28141
  * (never written to `result.json` — the enrichment is read-side). A finding's
@@ -28132,6 +28149,18 @@ var init_report = __esm({
28132
28149
  anchor: external_exports.string(),
28133
28150
  message: external_exports.string()
28134
28151
  }).strict();
28152
+ GuardReadyScenarioSchema = external_exports.object({
28153
+ id: external_exports.string(),
28154
+ title: external_exports.string(),
28155
+ /** The committed YAML the scenario would have been written as. */
28156
+ yaml: external_exports.string()
28157
+ }).strict();
28158
+ GuardHeldSectionSchema = external_exports.object({
28159
+ doc: external_exports.string(),
28160
+ anchor: external_exports.string(),
28161
+ headingText: external_exports.string().optional(),
28162
+ readyScenarios: external_exports.array(GuardReadyScenarioSchema)
28163
+ }).strict();
28135
28164
  GuardEntryPreflightSchema = external_exports.object({
28136
28165
  /** Display form of the entry argv, e.g. `node tools/cli/dist/index.js`. */
28137
28166
  entry: external_exports.string(),
@@ -28144,6 +28173,11 @@ var init_report = __esm({
28144
28173
  doc: external_exports.string(),
28145
28174
  reason: external_exports.string()
28146
28175
  }).strict();
28176
+ GuardOrphanedDismissalSchema = external_exports.object({
28177
+ doc: external_exports.string(),
28178
+ anchor: external_exports.string(),
28179
+ title: external_exports.string()
28180
+ }).strict();
28147
28181
  GuardOrphanedSectionSchema = external_exports.object({
28148
28182
  doc: external_exports.string(),
28149
28183
  anchor: external_exports.string(),
@@ -28184,6 +28218,19 @@ var init_report = __esm({
28184
28218
  * `written.length` when a passing scenario's section didn't settle.
28185
28219
  */
28186
28220
  birthPassed: external_exports.number().int().nonnegative().optional(),
28221
+ /**
28222
+ * Unsettled sections whose birth-passed candidates were withheld — the
28223
+ * ready-but-held scenarios, each carrying its authored YAML inline. Optional so
28224
+ * older reports (written before this field existed) keep parsing; absent reads
28225
+ * as "no held work".
28226
+ */
28227
+ heldSections: external_exports.array(GuardHeldSectionSchema).optional(),
28228
+ /**
28229
+ * Dismissals whose claim text matched nothing in a doc this run re-extracted —
28230
+ * stale entries in `scenarios/decisions.json`, surfaced (never silently
28231
+ * honored). Optional so older reports parse; absent reads as "none".
28232
+ */
28233
+ orphanedDismissals: external_exports.array(GuardOrphanedDismissalSchema).optional(),
28187
28234
  manifestPath: external_exports.string().optional(),
28188
28235
  usage: GuardGenerateUsageSchema.optional(),
28189
28236
  /**
@@ -28234,6 +28281,35 @@ var init_manifest = __esm({
28234
28281
  }
28235
28282
  });
28236
28283
 
28284
+ // packages/shared/dist/guard/decisions.js
28285
+ function dismissedClaimKey(doc, anchor, title) {
28286
+ return `${doc}\0${anchor}\0${title}`;
28287
+ }
28288
+ var GuardDismissedClaimSchema, GuardDecisionsSchema, EMPTY_GUARD_DECISIONS;
28289
+ var init_decisions = __esm({
28290
+ "packages/shared/dist/guard/decisions.js"() {
28291
+ "use strict";
28292
+ init_zod();
28293
+ GuardDismissedClaimSchema = external_exports.object({
28294
+ /** Repo-relative doc path the claim's section lives in. */
28295
+ doc: external_exports.string().min(1),
28296
+ /** The section anchor (slug) the claim was extracted under. */
28297
+ anchor: external_exports.string().min(1),
28298
+ /** The extracted claim's stable text — the identity, with `anchor`. */
28299
+ title: external_exports.string().min(1),
28300
+ /** ISO timestamp the dismissal was recorded. */
28301
+ dismissedAt: external_exports.string(),
28302
+ /** Optional free-text rationale ("flaky", "won't fix", …). */
28303
+ note: external_exports.string().optional()
28304
+ });
28305
+ GuardDecisionsSchema = external_exports.object({
28306
+ version: external_exports.literal(1),
28307
+ dismissedClaims: external_exports.array(GuardDismissedClaimSchema).default([])
28308
+ });
28309
+ EMPTY_GUARD_DECISIONS = { version: 1, dismissedClaims: [] };
28310
+ }
28311
+ });
28312
+
28237
28313
  // packages/shared/dist/guard/dashboard.js
28238
28314
  var init_dashboard = __esm({
28239
28315
  "packages/shared/dist/guard/dashboard.js"() {
@@ -28284,6 +28360,11 @@ function summarizeGenerate(r) {
28284
28360
  }
28285
28361
  }
28286
28362
  }
28363
+ const heldSections = r.heldSections ?? [];
28364
+ const heldKeys = new Set(heldSections.map((h) => `${h.doc}\0${h.anchor}`));
28365
+ const readyButHeld = heldSections.reduce((n, h) => n + h.readyScenarios.length, 0);
28366
+ const heldByFindings = r.birthFindings.filter((f2) => heldKeys.has(`${f2.doc}\0${f2.anchor}`)).length;
28367
+ const heldByErrors = r.errors.filter((e) => heldKeys.has(`${e.doc}\0${e.anchor}`)).length;
28287
28368
  return {
28288
28369
  generatedAt: r.generatedAt,
28289
28370
  status: r.status,
@@ -28294,6 +28375,9 @@ function summarizeGenerate(r) {
28294
28375
  blockedOnCapabilities,
28295
28376
  birthFindings: r.birthFindings.length,
28296
28377
  errors: r.errors.length,
28378
+ readyButHeld,
28379
+ heldByFindings,
28380
+ heldByErrors,
28297
28381
  ...r.usage ? { usage: r.usage } : {}
28298
28382
  };
28299
28383
  }
@@ -28314,6 +28398,7 @@ var init_guard = __esm({
28314
28398
  init_result();
28315
28399
  init_report();
28316
28400
  init_manifest();
28401
+ init_decisions();
28317
28402
  init_dashboard();
28318
28403
  init_summary();
28319
28404
  }
@@ -30177,8 +30262,8 @@ var require_node2 = __commonJS({
30177
30262
  }
30178
30263
  break;
30179
30264
  case "FILE":
30180
- var fs66 = __require("fs");
30181
- stream2 = new fs66.SyncWriteStream(fd2, { autoClose: false });
30265
+ var fs67 = __require("fs");
30266
+ stream2 = new fs67.SyncWriteStream(fd2, { autoClose: false });
30182
30267
  stream2._type = "fs";
30183
30268
  break;
30184
30269
  case "PIPE":
@@ -38666,7 +38751,7 @@ var require_view = __commonJS({
38666
38751
  "use strict";
38667
38752
  var debug2 = require_src2()("express:view");
38668
38753
  var path74 = __require("path");
38669
- var fs66 = __require("fs");
38754
+ var fs67 = __require("fs");
38670
38755
  var dirname10 = path74.dirname;
38671
38756
  var basename2 = path74.basename;
38672
38757
  var extname = path74.extname;
@@ -38732,7 +38817,7 @@ var require_view = __commonJS({
38732
38817
  function tryStat(path75) {
38733
38818
  debug2('stat "%s"', path75);
38734
38819
  try {
38735
- return fs66.statSync(path75);
38820
+ return fs67.statSync(path75);
38736
38821
  } catch (e) {
38737
38822
  return void 0;
38738
38823
  }
@@ -39087,7 +39172,7 @@ var require_types = __commonJS({
39087
39172
  var require_mime = __commonJS({
39088
39173
  "node_modules/.pnpm/mime@1.6.0/node_modules/mime/mime.js"(exports, module) {
39089
39174
  var path74 = __require("path");
39090
- var fs66 = __require("fs");
39175
+ var fs67 = __require("fs");
39091
39176
  function Mime() {
39092
39177
  this.types = /* @__PURE__ */ Object.create(null);
39093
39178
  this.extensions = /* @__PURE__ */ Object.create(null);
@@ -39108,7 +39193,7 @@ var require_mime = __commonJS({
39108
39193
  };
39109
39194
  Mime.prototype.load = function(file) {
39110
39195
  this._loading = file;
39111
- var map2 = {}, content = fs66.readFileSync(file, "ascii"), lines = content.split(/[\r\n]+/);
39196
+ var map2 = {}, content = fs67.readFileSync(file, "ascii"), lines = content.split(/[\r\n]+/);
39112
39197
  lines.forEach(function(line) {
39113
39198
  var fields = line.replace(/\s*#.*|^\s*|\s*$/g, "").split(/\s+/);
39114
39199
  map2[fields.shift()] = fields;
@@ -39230,7 +39315,7 @@ var require_send = __commonJS({
39230
39315
  var escapeHtml = require_escape_html();
39231
39316
  var etag = require_etag();
39232
39317
  var fresh = require_fresh();
39233
- var fs66 = __require("fs");
39318
+ var fs67 = __require("fs");
39234
39319
  var mime = require_mime();
39235
39320
  var ms = require_ms();
39236
39321
  var onFinished = require_on_finished();
@@ -39563,7 +39648,7 @@ var require_send = __commonJS({
39563
39648
  var i = 0;
39564
39649
  var self2 = this;
39565
39650
  debug2('stat "%s"', path75);
39566
- fs66.stat(path75, function onstat(err, stat) {
39651
+ fs67.stat(path75, function onstat(err, stat) {
39567
39652
  if (err && err.code === "ENOENT" && !extname(path75) && path75[path75.length - 1] !== sep3) {
39568
39653
  return next(err);
39569
39654
  }
@@ -39578,7 +39663,7 @@ var require_send = __commonJS({
39578
39663
  }
39579
39664
  var p = path75 + "." + self2._extensions[i++];
39580
39665
  debug2('stat "%s"', p);
39581
- fs66.stat(p, function(err2, stat) {
39666
+ fs67.stat(p, function(err2, stat) {
39582
39667
  if (err2) return next(err2);
39583
39668
  if (stat.isDirectory()) return next();
39584
39669
  self2.emit("file", p, stat);
@@ -39596,7 +39681,7 @@ var require_send = __commonJS({
39596
39681
  }
39597
39682
  var p = join11(path75, self2._index[i]);
39598
39683
  debug2('stat "%s"', p);
39599
- fs66.stat(p, function(err2, stat) {
39684
+ fs67.stat(p, function(err2, stat) {
39600
39685
  if (err2) return next(err2);
39601
39686
  if (stat.isDirectory()) return next();
39602
39687
  self2.emit("file", p, stat);
@@ -39608,7 +39693,7 @@ var require_send = __commonJS({
39608
39693
  SendStream.prototype.stream = function stream(path75, options) {
39609
39694
  var self2 = this;
39610
39695
  var res = this.res;
39611
- var stream2 = fs66.createReadStream(path75, options);
39696
+ var stream2 = fs67.createReadStream(path75, options);
39612
39697
  this.emit("stream", stream2);
39613
39698
  stream2.pipe(res);
39614
39699
  function cleanup() {
@@ -43603,7 +43688,7 @@ var init_guardrail = __esm({
43603
43688
  // packages/shared/dist/llm/transport.js
43604
43689
  import { spawn as spawn4 } from "node:child_process";
43605
43690
  import { createHash, randomUUID } from "node:crypto";
43606
- import fs25 from "node:fs";
43691
+ import fs26 from "node:fs";
43607
43692
  import path24 from "node:path";
43608
43693
  import { StringDecoder } from "node:string_decoder";
43609
43694
  function resetStageUsage() {
@@ -44006,15 +44091,15 @@ function cliTransport(opts = {}) {
44006
44091
  function agentTransport(ioDir, opts = {}) {
44007
44092
  const reqDir = path24.join(ioDir, "requests");
44008
44093
  const resDir = path24.join(ioDir, "responses");
44009
- fs25.mkdirSync(reqDir, { recursive: true });
44010
- fs25.mkdirSync(resDir, { recursive: true });
44094
+ fs26.mkdirSync(reqDir, { recursive: true });
44095
+ fs26.mkdirSync(resDir, { recursive: true });
44011
44096
  const pollMs = opts.pollMs ?? 200;
44012
44097
  const defaultTimeout = opts.defaultTimeoutMs ?? 6e5;
44013
44098
  return async (req) => {
44014
44099
  const id = sanitizeId(req.id ?? deriveId(req));
44015
44100
  const reqPath = path24.join(reqDir, `${id}.json`);
44016
44101
  const resPath = path24.join(resDir, `${id}.json`);
44017
- if (!fs25.existsSync(resPath)) {
44102
+ if (!fs26.existsSync(resPath)) {
44018
44103
  atomicWrite(reqPath, JSON.stringify({
44019
44104
  id,
44020
44105
  stage: req.stage,
@@ -44028,10 +44113,10 @@ function agentTransport(ioDir, opts = {}) {
44028
44113
  }
44029
44114
  const deadline = Date.now() + (req.timeoutMs ?? defaultTimeout) * resolveTimeoutScale();
44030
44115
  for (; ; ) {
44031
- if (fs25.existsSync(resPath)) {
44116
+ if (fs26.existsSync(resPath)) {
44032
44117
  let parsed;
44033
44118
  try {
44034
- parsed = JSON.parse(fs25.readFileSync(resPath, "utf-8"));
44119
+ parsed = JSON.parse(fs26.readFileSync(resPath, "utf-8"));
44035
44120
  } catch {
44036
44121
  await sleep(pollMs);
44037
44122
  continue;
@@ -44057,8 +44142,8 @@ function sanitizeId(id) {
44057
44142
  }
44058
44143
  function atomicWrite(filePath, data) {
44059
44144
  const tmp = `${filePath}.tmp-${randomUUID()}`;
44060
- fs25.writeFileSync(tmp, data);
44061
- fs25.renameSync(tmp, filePath);
44145
+ fs26.writeFileSync(tmp, data);
44146
+ fs26.renameSync(tmp, filePath);
44062
44147
  }
44063
44148
  function sleep(ms) {
44064
44149
  return new Promise((r) => setTimeout(r, ms));
@@ -44545,10 +44630,10 @@ import { Parser, Language } from "web-tree-sitter";
44545
44630
  import { createRequire as _createRequire } from "node:module";
44546
44631
  import { fileURLToPath } from "node:url";
44547
44632
  import path29 from "node:path";
44548
- import fs32 from "node:fs";
44633
+ import fs33 from "node:fs";
44549
44634
  function resolveWasmPath(subpath) {
44550
44635
  const bundled = path29.join(BUNDLED_WASM_DIR, path29.basename(subpath));
44551
- if (fs32.existsSync(bundled))
44636
+ if (fs33.existsSync(bundled))
44552
44637
  return bundled;
44553
44638
  return _require.resolve(subpath);
44554
44639
  }
@@ -172378,7 +172463,7 @@ var require_form_data = __commonJS({
172378
172463
  var http = __require("http");
172379
172464
  var https = __require("https");
172380
172465
  var parseUrl = __require("url").parse;
172381
- var fs66 = __require("fs");
172466
+ var fs67 = __require("fs");
172382
172467
  var Stream = __require("stream").Stream;
172383
172468
  var crypto6 = __require("crypto");
172384
172469
  var mime = require_mime_types();
@@ -172445,7 +172530,7 @@ var require_form_data = __commonJS({
172445
172530
  if (value.end != void 0 && value.end != Infinity && value.start != void 0) {
172446
172531
  callback(null, value.end + 1 - (value.start ? value.start : 0));
172447
172532
  } else {
172448
- fs66.stat(value.path, function(err, stat) {
172533
+ fs67.stat(value.path, function(err, stat) {
172449
172534
  if (err) {
172450
172535
  callback(err);
172451
172536
  return;
@@ -176758,7 +176843,7 @@ var require_windows = __commonJS({
176758
176843
  "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js"(exports, module) {
176759
176844
  module.exports = isexe;
176760
176845
  isexe.sync = sync;
176761
- var fs66 = __require("fs");
176846
+ var fs67 = __require("fs");
176762
176847
  function checkPathExt(path74, options) {
176763
176848
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
176764
176849
  if (!pathext) {
@@ -176783,12 +176868,12 @@ var require_windows = __commonJS({
176783
176868
  return checkPathExt(path74, options);
176784
176869
  }
176785
176870
  function isexe(path74, options, cb) {
176786
- fs66.stat(path74, function(er, stat) {
176871
+ fs67.stat(path74, function(er, stat) {
176787
176872
  cb(er, er ? false : checkStat(stat, path74, options));
176788
176873
  });
176789
176874
  }
176790
176875
  function sync(path74, options) {
176791
- return checkStat(fs66.statSync(path74), path74, options);
176876
+ return checkStat(fs67.statSync(path74), path74, options);
176792
176877
  }
176793
176878
  }
176794
176879
  });
@@ -176798,14 +176883,14 @@ var require_mode = __commonJS({
176798
176883
  "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js"(exports, module) {
176799
176884
  module.exports = isexe;
176800
176885
  isexe.sync = sync;
176801
- var fs66 = __require("fs");
176886
+ var fs67 = __require("fs");
176802
176887
  function isexe(path74, options, cb) {
176803
- fs66.stat(path74, function(er, stat) {
176888
+ fs67.stat(path74, function(er, stat) {
176804
176889
  cb(er, er ? false : checkStat(stat, options));
176805
176890
  });
176806
176891
  }
176807
176892
  function sync(path74, options) {
176808
- return checkStat(fs66.statSync(path74), options);
176893
+ return checkStat(fs67.statSync(path74), options);
176809
176894
  }
176810
176895
  function checkStat(stat, options) {
176811
176896
  return stat.isFile() && checkMode(stat, options);
@@ -176829,7 +176914,7 @@ var require_mode = __commonJS({
176829
176914
  // node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js
176830
176915
  var require_isexe = __commonJS({
176831
176916
  "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js"(exports, module) {
176832
- var fs66 = __require("fs");
176917
+ var fs67 = __require("fs");
176833
176918
  var core2;
176834
176919
  if (process.platform === "win32" || global.TESTING_WINDOWS) {
176835
176920
  core2 = require_windows();
@@ -177093,16 +177178,16 @@ var require_shebang_command = __commonJS({
177093
177178
  var require_readShebang = __commonJS({
177094
177179
  "node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js"(exports, module) {
177095
177180
  "use strict";
177096
- var fs66 = __require("fs");
177181
+ var fs67 = __require("fs");
177097
177182
  var shebangCommand = require_shebang_command();
177098
177183
  function readShebang(command) {
177099
177184
  const size = 150;
177100
177185
  const buffer = Buffer.alloc(size);
177101
177186
  let fd;
177102
177187
  try {
177103
- fd = fs66.openSync(command, "r");
177104
- fs66.readSync(fd, buffer, 0, size, 0);
177105
- fs66.closeSync(fd);
177188
+ fd = fs67.openSync(command, "r");
177189
+ fs67.readSync(fd, buffer, 0, size, 0);
177190
+ fs67.closeSync(fd);
177106
177191
  } catch (e) {
177107
177192
  }
177108
177193
  return shebangCommand(buffer.toString());
@@ -186683,7 +186768,7 @@ function getIO() {
186683
186768
  // apps/dashboard/server/src/app.ts
186684
186769
  var import_express16 = __toESM(require_express2(), 1);
186685
186770
  var import_cors = __toESM(require_lib(), 1);
186686
- import fs65 from "node:fs";
186771
+ import fs66 from "node:fs";
186687
186772
  import { fileURLToPath as fileURLToPath6 } from "node:url";
186688
186773
  import path72 from "node:path";
186689
186774
 
@@ -186893,7 +186978,7 @@ async function projectResolver(req, res, next) {
186893
186978
  // apps/dashboard/server/src/routes/repos.ts
186894
186979
  var import_express = __toESM(require_express2(), 1);
186895
186980
  init_dist();
186896
- import * as fs59 from "fs";
186981
+ import * as fs60 from "fs";
186897
186982
 
186898
186983
  // packages/core/dist/lib/errors.js
186899
186984
  function createAppError(message, statusCode) {
@@ -194473,6 +194558,7 @@ var HISTORY_FILE2 = "history.json";
194473
194558
  var RESULT_FILE = "result.json";
194474
194559
  var RECIPE_FILE = "recipe.json";
194475
194560
  var MANIFEST_FILE = "manifest.json";
194561
+ var DECISIONS_FILE = "decisions.json";
194476
194562
  function guardDir(repoRoot) {
194477
194563
  return path11.join(repoRoot, TRUECOURSE_DIR3, GUARD_DIR);
194478
194564
  }
@@ -194500,6 +194586,9 @@ function recipePath(repoRoot) {
194500
194586
  function manifestPath(repoRoot) {
194501
194587
  return path11.join(scenariosDir(repoRoot), MANIFEST_FILE);
194502
194588
  }
194589
+ function guardDecisionsPath(repoRoot) {
194590
+ return path11.join(scenariosDir(repoRoot), DECISIONS_FILE);
194591
+ }
194503
194592
  function evidenceRunDir(repoRoot, runId) {
194504
194593
  return path11.join(guardDir(repoRoot), EVIDENCE_DIR, runId);
194505
194594
  }
@@ -195232,6 +195321,14 @@ function writeFile(dir, name, content) {
195232
195321
 
195233
195322
  // packages/guard-runner/dist/run-scenario.js
195234
195323
  var ENV_PINS = DETERMINISM_PINS;
195324
+ var SANDBOX_SETUP_EXPECTED = "sandbox setup to succeed";
195325
+ var CAPABILITY_SETUP_EXPECTED = "setup capabilities to materialize";
195326
+ function isSetupDefectResult(result) {
195327
+ if (result.outcome !== "error")
195328
+ return false;
195329
+ const expected = result.failure?.expected;
195330
+ return expected === SANDBOX_SETUP_EXPECTED || expected === CAPABILITY_SETUP_EXPECTED;
195331
+ }
195235
195332
  async function runScenario(scenario, ctx) {
195236
195333
  const start = Date.now();
195237
195334
  const base = {
@@ -195252,7 +195349,7 @@ async function runScenario(scenario, ctx) {
195252
195349
  ...base,
195253
195350
  outcome: "error",
195254
195351
  durationMs: Date.now() - start,
195255
- failure: { step: 1, expected: "sandbox setup to succeed", actual: message }
195352
+ failure: { step: 1, expected: SANDBOX_SETUP_EXPECTED, actual: message }
195256
195353
  };
195257
195354
  }
195258
195355
  const normCtx = { sandboxRoot: sandbox.root, repoRoot: ctx.repoRoot };
@@ -195267,7 +195364,7 @@ async function runScenario(scenario, ctx) {
195267
195364
  ...base,
195268
195365
  outcome: "error",
195269
195366
  durationMs: Date.now() - start,
195270
- failure: { step: 1, expected: "setup capabilities to materialize", actual: message }
195367
+ failure: { step: 1, expected: CAPABILITY_SETUP_EXPECTED, actual: message }
195271
195368
  };
195272
195369
  }
195273
195370
  for (let i = 0; i < scenario.steps.length; i++) {
@@ -195747,8 +195844,47 @@ async function mapWithConcurrency(items, limit, fn) {
195747
195844
  return results;
195748
195845
  }
195749
195846
 
195750
- // packages/core/dist/lib/spec-store.js
195847
+ // packages/guard-runner/dist/decisions.js
195848
+ init_dist();
195751
195849
  import fs21 from "node:fs";
195850
+ function readGuardDecisions(repoRoot) {
195851
+ const file = guardDecisionsPath(repoRoot);
195852
+ if (!fs21.existsSync(file))
195853
+ return EMPTY_GUARD_DECISIONS;
195854
+ try {
195855
+ const parsed = GuardDecisionsSchema.safeParse(JSON.parse(fs21.readFileSync(file, "utf-8")));
195856
+ return parsed.success ? parsed.data : EMPTY_GUARD_DECISIONS;
195857
+ } catch {
195858
+ return EMPTY_GUARD_DECISIONS;
195859
+ }
195860
+ }
195861
+ function writeGuardDecisions(repoRoot, decisions) {
195862
+ const target = guardDecisionsPath(repoRoot);
195863
+ atomicWriteJson2(target, decisions);
195864
+ return target;
195865
+ }
195866
+ function dismissGuardClaim(repoRoot, claim) {
195867
+ const decisions = readGuardDecisions(repoRoot);
195868
+ const key4 = dismissedClaimKey(claim.doc, claim.anchor, claim.title);
195869
+ const dismissedClaims = decisions.dismissedClaims.filter((d) => dismissedClaimKey(d.doc, d.anchor, d.title) !== key4);
195870
+ dismissedClaims.push(claim);
195871
+ const next = { ...decisions, dismissedClaims };
195872
+ writeGuardDecisions(repoRoot, next);
195873
+ return next;
195874
+ }
195875
+ function undismissGuardClaim(repoRoot, identity) {
195876
+ const decisions = readGuardDecisions(repoRoot);
195877
+ const key4 = dismissedClaimKey(identity.doc, identity.anchor, identity.title);
195878
+ const next = {
195879
+ ...decisions,
195880
+ dismissedClaims: decisions.dismissedClaims.filter((d) => dismissedClaimKey(d.doc, d.anchor, d.title) !== key4)
195881
+ };
195882
+ writeGuardDecisions(repoRoot, next);
195883
+ return next;
195884
+ }
195885
+
195886
+ // packages/core/dist/lib/spec-store.js
195887
+ import fs22 from "node:fs";
195752
195888
  import path20 from "node:path";
195753
195889
  function specPath(repoKey, artifact) {
195754
195890
  return path20.join(repoKey, ".truecourse", "specs", `${artifact}.json`);
@@ -195764,18 +195900,18 @@ var FileSpecStore = class {
195764
195900
  throw new Error(PR_DECISIONS_FILE_ERROR);
195765
195901
  }
195766
195902
  const file = specPath(ref.repoKey, artifact);
195767
- fs21.mkdirSync(path20.dirname(file), { recursive: true });
195768
- fs21.writeFileSync(file, JSON.stringify(json2, null, 2) + "\n", "utf-8");
195903
+ fs22.mkdirSync(path20.dirname(file), { recursive: true });
195904
+ fs22.writeFileSync(file, JSON.stringify(json2, null, 2) + "\n", "utf-8");
195769
195905
  }
195770
195906
  async loadSpec(ref, artifact) {
195771
195907
  if (artifact === "decisions" && isPrDecisionsRef(ref.commitSha)) {
195772
195908
  throw new Error(PR_DECISIONS_FILE_ERROR);
195773
195909
  }
195774
195910
  const file = specPath(ref.repoKey, artifact);
195775
- if (!fs21.existsSync(file))
195911
+ if (!fs22.existsSync(file))
195776
195912
  return null;
195777
195913
  try {
195778
- return JSON.parse(fs21.readFileSync(file, "utf-8"));
195914
+ return JSON.parse(fs22.readFileSync(file, "utf-8"));
195779
195915
  } catch {
195780
195916
  return null;
195781
195917
  }
@@ -195785,8 +195921,8 @@ var FileSpecStore = class {
195785
195921
  throw new Error(PR_DECISIONS_FILE_ERROR);
195786
195922
  }
195787
195923
  const file = specPath(ref.repoKey, artifact);
195788
- if (fs21.existsSync(file))
195789
- fs21.rmSync(file);
195924
+ if (fs22.existsSync(file))
195925
+ fs22.rmSync(file);
195790
195926
  }
195791
195927
  // The file impl is single-document-per-repo, so "latest" === read the file.
195792
195928
  async loadLatest(repoKey, artifact) {
@@ -195814,7 +195950,7 @@ var latestSpecCommit = (repoKey) => active6.latestCommit(repoKey);
195814
195950
  var specsMaterializeInPlace = () => active6.materializesInPlace;
195815
195951
 
195816
195952
  // packages/core/dist/lib/verify-store.js
195817
- import fs22 from "node:fs";
195953
+ import fs23 from "node:fs";
195818
195954
  import path21 from "node:path";
195819
195955
 
195820
195956
  // packages/core/dist/types/verify-snapshot.js
@@ -195913,7 +196049,7 @@ var FileVerifyStore = class {
195913
196049
  const file = verifyLatestPath(repoPath);
195914
196050
  let mtime;
195915
196051
  try {
195916
- mtime = fs22.statSync(file).mtimeMs;
196052
+ mtime = fs23.statSync(file).mtimeMs;
195917
196053
  } catch (err) {
195918
196054
  if (err.code === "ENOENT") {
195919
196055
  latestCache2.delete(repoPath);
@@ -195924,7 +196060,7 @@ var FileVerifyStore = class {
195924
196060
  const cached = latestCache2.get(repoPath);
195925
196061
  if (cached && cached.mtime === mtime)
195926
196062
  return cached.data;
195927
- const data = JSON.parse(fs22.readFileSync(file, "utf-8"));
196063
+ const data = JSON.parse(fs23.readFileSync(file, "utf-8"));
195928
196064
  latestCache2.set(repoPath, { mtime, data });
195929
196065
  return data;
195930
196066
  }
@@ -195934,7 +196070,7 @@ var FileVerifyStore = class {
195934
196070
  }
195935
196071
  async deleteVerifyLatest(repoPath) {
195936
196072
  try {
195937
- fs22.unlinkSync(verifyLatestPath(repoPath));
196073
+ fs23.unlinkSync(verifyLatestPath(repoPath));
195938
196074
  } catch (err) {
195939
196075
  if (err.code !== "ENOENT")
195940
196076
  throw err;
@@ -195948,21 +196084,21 @@ var FileVerifyStore = class {
195948
196084
  }
195949
196085
  async readVerifyRun(repoPath, filename) {
195950
196086
  const file = verifyRunPath(repoPath, filename);
195951
- if (!fs22.existsSync(file))
196087
+ if (!fs23.existsSync(file))
195952
196088
  return null;
195953
- return JSON.parse(fs22.readFileSync(file, "utf-8"));
196089
+ return JSON.parse(fs23.readFileSync(file, "utf-8"));
195954
196090
  }
195955
196091
  async listVerifyRuns(repoPath) {
195956
196092
  const dir = runsDir(repoPath);
195957
- if (!fs22.existsSync(dir))
196093
+ if (!fs23.existsSync(dir))
195958
196094
  return [];
195959
- return fs22.readdirSync(dir).filter((n) => n.endsWith(".json")).sort();
196095
+ return fs23.readdirSync(dir).filter((n) => n.endsWith(".json")).sort();
195960
196096
  }
195961
196097
  async readVerifyHistory(repoPath) {
195962
196098
  const file = verifyHistoryPath(repoPath);
195963
- if (!fs22.existsSync(file))
196099
+ if (!fs23.existsSync(file))
195964
196100
  return { runs: [] };
195965
- return JSON.parse(fs22.readFileSync(file, "utf-8"));
196101
+ return JSON.parse(fs23.readFileSync(file, "utf-8"));
195966
196102
  }
195967
196103
  async appendVerifyHistory(repoPath, entry) {
195968
196104
  const history = await this.readVerifyHistory(repoPath);
@@ -195975,7 +196111,7 @@ var FileVerifyStore = class {
195975
196111
  if (!entry)
195976
196112
  return false;
195977
196113
  try {
195978
- fs22.unlinkSync(verifyRunPath(repoPath, entry.filename));
196114
+ fs23.unlinkSync(verifyRunPath(repoPath, entry.filename));
195979
196115
  } catch (err) {
195980
196116
  if (err.code !== "ENOENT")
195981
196117
  throw err;
@@ -195997,16 +196133,16 @@ var FileVerifyStore = class {
195997
196133
  }
195998
196134
  async readVerifyDiff(repoPath, scope) {
195999
196135
  const file = verifyDiffPath(repoPath, scope);
196000
- if (!fs22.existsSync(file))
196136
+ if (!fs23.existsSync(file))
196001
196137
  return null;
196002
- return JSON.parse(fs22.readFileSync(file, "utf-8"));
196138
+ return JSON.parse(fs23.readFileSync(file, "utf-8"));
196003
196139
  }
196004
196140
  async writeVerifyDiff(repoPath, diff, scope) {
196005
196141
  atomicWriteJson(verifyDiffPath(repoPath, scope), diff);
196006
196142
  }
196007
196143
  async deleteVerifyDiff(repoPath, scope) {
196008
196144
  try {
196009
- fs22.unlinkSync(verifyDiffPath(repoPath, scope));
196145
+ fs23.unlinkSync(verifyDiffPath(repoPath, scope));
196010
196146
  } catch (err) {
196011
196147
  if (err.code !== "ENOENT")
196012
196148
  throw err;
@@ -196257,7 +196393,7 @@ var CuratedCorpusSchema = external_exports.object({
196257
196393
  });
196258
196394
 
196259
196395
  // packages/spec-consolidator/dist/corpus-store.js
196260
- import fs23 from "node:fs";
196396
+ import fs24 from "node:fs";
196261
196397
  import path22 from "node:path";
196262
196398
  var CORPUS_FILE = "corpus.json";
196263
196399
  function corpusFilePath(repoRoot) {
@@ -196265,10 +196401,10 @@ function corpusFilePath(repoRoot) {
196265
196401
  }
196266
196402
  function readCorpus(repoRoot) {
196267
196403
  const file = corpusFilePath(repoRoot);
196268
- if (!fs23.existsSync(file))
196404
+ if (!fs24.existsSync(file))
196269
196405
  return null;
196270
196406
  try {
196271
- const raw = JSON.parse(fs23.readFileSync(file, "utf-8"));
196407
+ const raw = JSON.parse(fs24.readFileSync(file, "utf-8"));
196272
196408
  return CuratedCorpusSchema.parse(raw);
196273
196409
  } catch {
196274
196410
  return null;
@@ -196276,7 +196412,7 @@ function readCorpus(repoRoot) {
196276
196412
  }
196277
196413
  function writeCorpus(repoRoot, input) {
196278
196414
  const file = corpusFilePath(repoRoot);
196279
- fs23.mkdirSync(path22.dirname(file), { recursive: true });
196415
+ fs24.mkdirSync(path22.dirname(file), { recursive: true });
196280
196416
  const payload = {
196281
196417
  version: 3,
196282
196418
  // Caller may pass the timestamp it stamped on the in-memory corpus so the
@@ -196287,16 +196423,16 @@ function writeCorpus(repoRoot, input) {
196287
196423
  relations: input.relations,
196288
196424
  skippedDocs: input.skippedDocs ?? []
196289
196425
  };
196290
- fs23.writeFileSync(file, JSON.stringify(payload, null, 2) + "\n");
196426
+ fs24.writeFileSync(file, JSON.stringify(payload, null, 2) + "\n");
196291
196427
  }
196292
196428
 
196293
196429
  // packages/spec-consolidator/dist/area-tagger.js
196294
196430
  init_zod();
196295
196431
  import { createHash as createHash2 } from "node:crypto";
196296
- import fs26 from "node:fs";
196432
+ import fs27 from "node:fs";
196297
196433
 
196298
196434
  // packages/llm/dist/cache-store.js
196299
- import fs24 from "node:fs";
196435
+ import fs25 from "node:fs";
196300
196436
  import path23 from "node:path";
196301
196437
  var FileKvCacheStore = class {
196302
196438
  file(scope, cacheName, key4) {
@@ -196304,18 +196440,18 @@ var FileKvCacheStore = class {
196304
196440
  }
196305
196441
  async get(scope, cacheName, key4) {
196306
196442
  const file = this.file(scope, cacheName, key4);
196307
- if (!fs24.existsSync(file))
196443
+ if (!fs25.existsSync(file))
196308
196444
  return null;
196309
196445
  try {
196310
- return JSON.parse(fs24.readFileSync(file, "utf-8"));
196446
+ return JSON.parse(fs25.readFileSync(file, "utf-8"));
196311
196447
  } catch {
196312
196448
  return null;
196313
196449
  }
196314
196450
  }
196315
196451
  async set(scope, cacheName, key4, value) {
196316
196452
  const file = this.file(scope, cacheName, key4);
196317
- fs24.mkdirSync(path23.dirname(file), { recursive: true });
196318
- fs24.writeFileSync(file, JSON.stringify(value, null, 2));
196453
+ fs25.mkdirSync(path23.dirname(file), { recursive: true });
196454
+ fs25.writeFileSync(file, JSON.stringify(value, null, 2));
196319
196455
  }
196320
196456
  };
196321
196457
  var active8 = new FileKvCacheStore();
@@ -196397,7 +196533,7 @@ function docBody(doc) {
196397
196533
  return doc.content;
196398
196534
  if (doc.absPath) {
196399
196535
  try {
196400
- return fs26.readFileSync(doc.absPath, "utf-8");
196536
+ return fs27.readFileSync(doc.absPath, "utf-8");
196401
196537
  } catch {
196402
196538
  }
196403
196539
  }
@@ -197002,7 +197138,7 @@ function spawnRelationRunner(opts = {}) {
197002
197138
  // packages/spec-consolidator/dist/overlap-detector.js
197003
197139
  init_zod();
197004
197140
  import { createHash as createHash6 } from "node:crypto";
197005
- import fs27 from "node:fs";
197141
+ import fs28 from "node:fs";
197006
197142
  init_transport();
197007
197143
  var DEFAULT_MAX_PAIRS_PER_AREA = 60;
197008
197144
  async function flagOverlaps(repoRoot, areas, docs, opts = {}) {
@@ -197183,7 +197319,7 @@ function docBody2(doc) {
197183
197319
  return doc.content;
197184
197320
  if (doc.absPath) {
197185
197321
  try {
197186
- return fs27.readFileSync(doc.absPath, "utf-8");
197322
+ return fs28.readFileSync(doc.absPath, "utf-8");
197187
197323
  } catch {
197188
197324
  }
197189
197325
  }
@@ -197275,14 +197411,14 @@ async function writeCache3(scope, cacheKey, verdict) {
197275
197411
 
197276
197412
  // packages/spec-consolidator/dist/curate.js
197277
197413
  init_dist();
197278
- import fs30 from "node:fs";
197414
+ import fs31 from "node:fs";
197279
197415
  import path27 from "node:path";
197280
197416
 
197281
197417
  // packages/spec-consolidator/dist/discovery.js
197282
197418
  init_dist();
197283
197419
  import { execFileSync } from "node:child_process";
197284
197420
  import { createHash as createHash7 } from "node:crypto";
197285
- import fs28 from "node:fs";
197421
+ import fs29 from "node:fs";
197286
197422
  import path26 from "node:path";
197287
197423
  var SKIP_DIR_PROBE = "__tc_skipdir_probe__.md";
197288
197424
  var PREVIEW_LINE_LIMIT = 200;
@@ -197294,7 +197430,7 @@ function discoverDocs(rootDir, opts = {}) {
197294
197430
  const visit = (dir) => {
197295
197431
  let entries;
197296
197432
  try {
197297
- entries = fs28.readdirSync(dir, { withFileTypes: true });
197433
+ entries = fs29.readdirSync(dir, { withFileTypes: true });
197298
197434
  } catch {
197299
197435
  return;
197300
197436
  }
@@ -197333,8 +197469,8 @@ function makeCandidate(absPath, rootDir, previewLines, opts) {
197333
197469
  let content;
197334
197470
  let stat;
197335
197471
  try {
197336
- content = fs28.readFileSync(absPath, "utf-8");
197337
- stat = fs28.statSync(absPath);
197472
+ content = fs29.readFileSync(absPath, "utf-8");
197473
+ stat = fs29.statSync(absPath);
197338
197474
  } catch {
197339
197475
  return null;
197340
197476
  }
@@ -197402,7 +197538,7 @@ function looksLikePrd(content) {
197402
197538
  // packages/spec-consolidator/dist/relevance-filter.js
197403
197539
  init_zod();
197404
197540
  import { createHash as createHash8 } from "node:crypto";
197405
- import fs29 from "node:fs";
197541
+ import fs30 from "node:fs";
197406
197542
  init_transport();
197407
197543
  function prefilterDocs(docs, manualIncludes = []) {
197408
197544
  const manualSet = new Set(manualIncludes);
@@ -197526,7 +197662,7 @@ function docBody3(doc) {
197526
197662
  return doc.content;
197527
197663
  if (doc.absPath) {
197528
197664
  try {
197529
- return fs29.readFileSync(doc.absPath, "utf-8");
197665
+ return fs30.readFileSync(doc.absPath, "utf-8");
197530
197666
  } catch {
197531
197667
  }
197532
197668
  }
@@ -197787,10 +197923,10 @@ var EMPTY_DECISIONS = {
197787
197923
  };
197788
197924
  function readCorpusDecisions(repoRoot) {
197789
197925
  const file = path27.join(repoRoot, ".truecourse", "specs", "decisions.json");
197790
- if (!fs30.existsSync(file))
197926
+ if (!fs31.existsSync(file))
197791
197927
  return EMPTY_DECISIONS;
197792
197928
  try {
197793
- const raw = JSON.parse(fs30.readFileSync(file, "utf-8"));
197929
+ const raw = JSON.parse(fs31.readFileSync(file, "utf-8"));
197794
197930
  return DecisionsFileSchema.parse(raw);
197795
197931
  } catch {
197796
197932
  return EMPTY_DECISIONS;
@@ -197798,7 +197934,7 @@ function readCorpusDecisions(repoRoot) {
197798
197934
  }
197799
197935
 
197800
197936
  // packages/spec-consolidator/dist/orchestrator.js
197801
- import fs31 from "node:fs";
197937
+ import fs32 from "node:fs";
197802
197938
  import path28 from "node:path";
197803
197939
  var EMPTY_DECISIONS2 = {
197804
197940
  version: 1,
@@ -197812,10 +197948,10 @@ function decisionsPath(repoRoot) {
197812
197948
  }
197813
197949
  function readDecisions(repoRoot) {
197814
197950
  const file = decisionsPath(repoRoot);
197815
- if (!fs31.existsSync(file))
197951
+ if (!fs32.existsSync(file))
197816
197952
  return EMPTY_DECISIONS2;
197817
197953
  try {
197818
- const raw = JSON.parse(fs31.readFileSync(file, "utf-8"));
197954
+ const raw = JSON.parse(fs32.readFileSync(file, "utf-8"));
197819
197955
  return DecisionsFileSchema.parse(raw);
197820
197956
  } catch {
197821
197957
  return EMPTY_DECISIONS2;
@@ -197823,8 +197959,8 @@ function readDecisions(repoRoot) {
197823
197959
  }
197824
197960
  function writeDecisions(repoRoot, decisions) {
197825
197961
  const file = decisionsPath(repoRoot);
197826
- fs31.mkdirSync(path28.dirname(file), { recursive: true });
197827
- fs31.writeFileSync(file, JSON.stringify(decisions, null, 2) + "\n");
197962
+ fs32.mkdirSync(path28.dirname(file), { recursive: true });
197963
+ fs32.writeFileSync(file, JSON.stringify(decisions, null, 2) + "\n");
197828
197964
  }
197829
197965
 
197830
197966
  // packages/contract-verifier/dist/parser-ohm/index.js
@@ -199986,13 +200122,13 @@ UnicodeChar.prototype.toFailure = function(grammar2) {
199986
200122
  return new Failure(this, "a Unicode [" + this.categoryOrProp + "] character", "description");
199987
200123
  };
199988
200124
  Alt.prototype.toFailure = function(grammar2) {
199989
- const fs66 = this.terms.map((t) => t.toFailure(grammar2));
199990
- const description = "(" + fs66.join(" or ") + ")";
200125
+ const fs67 = this.terms.map((t) => t.toFailure(grammar2));
200126
+ const description = "(" + fs67.join(" or ") + ")";
199991
200127
  return new Failure(this, description, "description");
199992
200128
  };
199993
200129
  Seq.prototype.toFailure = function(grammar2) {
199994
- const fs66 = this.factors.map((f2) => f2.toFailure(grammar2));
199995
- const description = "(" + fs66.join(" ") + ")";
200130
+ const fs67 = this.factors.map((f2) => f2.toFailure(grammar2));
200131
+ const description = "(" + fs67.join(" ") + ")";
199996
200132
  return new Failure(this, description, "description");
199997
200133
  };
199998
200134
  Iter.prototype.toFailure = function(grammar2) {
@@ -201711,9 +201847,9 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
201711
201847
  decl.withSuperGrammar(namespace[superGrammarName]);
201712
201848
  }
201713
201849
  },
201714
- Rule_define(n, fs66, d, _, b) {
201850
+ Rule_define(n, fs67, d, _, b) {
201715
201851
  currentRuleName = n.visit();
201716
- currentRuleFormals = fs66.children.map((c) => c.visit())[0] || [];
201852
+ currentRuleFormals = fs67.children.map((c) => c.visit())[0] || [];
201717
201853
  if (!decl.defaultStartRule && decl.ensureSuperGrammar() !== Grammar.ProtoBuiltInRules) {
201718
201854
  decl.withDefaultStartRule(currentRuleName);
201719
201855
  }
@@ -201722,9 +201858,9 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
201722
201858
  const source = this.source.trimmed();
201723
201859
  return decl.define(currentRuleName, currentRuleFormals, body, description, source);
201724
201860
  },
201725
- Rule_override(n, fs66, _, b) {
201861
+ Rule_override(n, fs67, _, b) {
201726
201862
  currentRuleName = n.visit();
201727
- currentRuleFormals = fs66.children.map((c) => c.visit())[0] || [];
201863
+ currentRuleFormals = fs67.children.map((c) => c.visit())[0] || [];
201728
201864
  const source = this.source.trimmed();
201729
201865
  decl.ensureSuperGrammarRuleForOverriding(currentRuleName, source);
201730
201866
  overriding = true;
@@ -201732,9 +201868,9 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
201732
201868
  overriding = false;
201733
201869
  return decl.override(currentRuleName, currentRuleFormals, body, null, source);
201734
201870
  },
201735
- Rule_extend(n, fs66, _, b) {
201871
+ Rule_extend(n, fs67, _, b) {
201736
201872
  currentRuleName = n.visit();
201737
- currentRuleFormals = fs66.children.map((c) => c.visit())[0] || [];
201873
+ currentRuleFormals = fs67.children.map((c) => c.visit())[0] || [];
201738
201874
  const body = b.visit();
201739
201875
  const source = this.source.trimmed();
201740
201876
  return decl.extend(currentRuleName, currentRuleFormals, body, null, source);
@@ -201761,8 +201897,8 @@ function buildGrammar2(match4, namespace, optOhmGrammarForTesting, options) {
201761
201897
  return builder.alt(...args).withSource(this.source);
201762
201898
  }
201763
201899
  },
201764
- Formals(opointy, fs66, cpointy) {
201765
- return fs66.visit();
201900
+ Formals(opointy, fs67, cpointy) {
201901
+ return fs67.visit();
201766
201902
  },
201767
201903
  Params(opointy, ps, cpointy) {
201768
201904
  return ps.visit();
@@ -201908,8 +202044,8 @@ function initPrototypeParser(grammar2) {
201908
202044
  formals: optFormals.children.map((c) => c.parse())[0] || []
201909
202045
  };
201910
202046
  },
201911
- Formals(oparen, fs66, cparen) {
201912
- return fs66.asIteration().children.map((c) => c.parse());
202047
+ Formals(oparen, fs67, cparen) {
202048
+ return fs67.asIteration().children.map((c) => c.parse());
201913
202049
  },
201914
202050
  name(first2, rest) {
201915
202051
  return this.sourceString;
@@ -205148,13 +205284,13 @@ function effectGroupRules(c, body) {
205148
205284
  // packages/contract-verifier/dist/extractor/index.js
205149
205285
  init_dist3();
205150
205286
  init_dist();
205151
- import fs42 from "node:fs";
205287
+ import fs43 from "node:fs";
205152
205288
  import path44 from "node:path";
205153
205289
 
205154
205290
  // packages/contract-verifier/dist/extractor/source-walker.js
205155
205291
  init_dist3();
205156
205292
  init_dist();
205157
- import fs33 from "node:fs";
205293
+ import fs34 from "node:fs";
205158
205294
  import path33 from "node:path";
205159
205295
  var EXT_TO_LANG = {
205160
205296
  ".ts": "typescript",
@@ -205203,7 +205339,7 @@ async function eachParsedSource(rootDir, visit) {
205203
205339
  const walk20 = (dir) => {
205204
205340
  let entries;
205205
205341
  try {
205206
- entries = fs33.readdirSync(dir, { withFileTypes: true });
205342
+ entries = fs34.readdirSync(dir, { withFileTypes: true });
205207
205343
  } catch {
205208
205344
  return;
205209
205345
  }
@@ -205226,7 +205362,7 @@ async function eachParsedSource(rootDir, visit) {
205226
205362
  continue;
205227
205363
  let source;
205228
205364
  try {
205229
- source = fs33.readFileSync(full, "utf-8");
205365
+ source = fs34.readFileSync(full, "utf-8");
205230
205366
  } catch {
205231
205367
  continue;
205232
205368
  }
@@ -207237,7 +207373,7 @@ function walk2(node2, visit) {
207237
207373
  // packages/contract-verifier/dist/extractor/file-based-routes.js
207238
207374
  init_dist3();
207239
207375
  init_dist();
207240
- import fs34 from "node:fs";
207376
+ import fs35 from "node:fs";
207241
207377
  import path34 from "node:path";
207242
207378
  var TS_EXT = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx"]);
207243
207379
  var HTTP_METHODS5 = /* @__PURE__ */ new Set(["get", "post", "put", "delete", "patch", "options", "head"]);
@@ -207269,7 +207405,7 @@ function findDirs(rootDir, wantedRel) {
207269
207405
  const visit = (dir) => {
207270
207406
  let entries;
207271
207407
  try {
207272
- entries = fs34.readdirSync(dir, { withFileTypes: true });
207408
+ entries = fs35.readdirSync(dir, { withFileTypes: true });
207273
207409
  } catch {
207274
207410
  return;
207275
207411
  }
@@ -207295,7 +207431,7 @@ function findDirs(rootDir, wantedRel) {
207295
207431
  function walkRoot(rootAbs, root, out) {
207296
207432
  const tcIgnore = loadTcIgnore(rootAbs);
207297
207433
  const visit = (dir) => {
207298
- for (const entry of fs34.readdirSync(dir, { withFileTypes: true })) {
207434
+ for (const entry of fs35.readdirSync(dir, { withFileTypes: true })) {
207299
207435
  if (entry.name === "node_modules" || entry.name === ".git")
207300
207436
  continue;
207301
207437
  const full = path34.join(dir, entry.name);
@@ -207320,7 +207456,7 @@ function walkRoot(rootAbs, root, out) {
207320
207456
  const url = deriveUrl(relUnderRoot, root);
207321
207457
  if (url === null)
207322
207458
  continue;
207323
- const source = fs34.readFileSync(full, "utf-8");
207459
+ const source = fs35.readFileSync(full, "utf-8");
207324
207460
  const lang = ext2 === ".tsx" ? "tsx" : ext2 === ".ts" ? "typescript" : "javascript";
207325
207461
  let tree;
207326
207462
  try {
@@ -207437,7 +207573,7 @@ function collectHttpMethodExports(root, source) {
207437
207573
  }
207438
207574
 
207439
207575
  // packages/contract-verifier/dist/extractor/mount-graph.js
207440
- import fs35 from "node:fs";
207576
+ import fs36 from "node:fs";
207441
207577
  import path35 from "node:path";
207442
207578
  var ROUTER_FACTORIES = /* @__PURE__ */ new Set(["Router", "express"]);
207443
207579
  function analyzeRouterFile(filePath, source, tree) {
@@ -207589,7 +207725,7 @@ function resolveImportPath(fromFile, spec) {
207589
207725
  ];
207590
207726
  for (const c of candidates) {
207591
207727
  const abs = path35.resolve(baseDir, c);
207592
- if (fs35.existsSync(abs) && fs35.statSync(abs).isFile())
207728
+ if (fs36.existsSync(abs) && fs36.statSync(abs).isFile())
207593
207729
  return abs;
207594
207730
  }
207595
207731
  return null;
@@ -207769,7 +207905,7 @@ function joinPath2(prefix, suffix) {
207769
207905
  // packages/contract-verifier/dist/extractor/auth-presence.js
207770
207906
  init_dist3();
207771
207907
  init_dist();
207772
- import fs36 from "node:fs";
207908
+ import fs37 from "node:fs";
207773
207909
  import path36 from "node:path";
207774
207910
  var TS_EXT2 = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx"]);
207775
207911
  var AUTH_MIDDLEWARE_NAMES = /* @__PURE__ */ new Set([
@@ -207790,7 +207926,7 @@ async function detectAuthPresence(rootDir) {
207790
207926
  const scanned = [];
207791
207927
  const tcIgnore = loadTcIgnore(rootDir);
207792
207928
  const visit = (dir) => {
207793
- for (const entry of fs36.readdirSync(dir, { withFileTypes: true })) {
207929
+ for (const entry of fs37.readdirSync(dir, { withFileTypes: true })) {
207794
207930
  if (entry.name === "node_modules" || entry.name === ".git")
207795
207931
  continue;
207796
207932
  const full = path36.join(dir, entry.name);
@@ -207805,7 +207941,7 @@ async function detectAuthPresence(rootDir) {
207805
207941
  const ext2 = path36.extname(entry.name);
207806
207942
  if (!TS_EXT2.has(ext2))
207807
207943
  continue;
207808
- const source = fs36.readFileSync(full, "utf-8");
207944
+ const source = fs37.readFileSync(full, "utf-8");
207809
207945
  const lang = ext2 === ".tsx" ? "tsx" : ext2 === ".ts" ? "typescript" : "javascript";
207810
207946
  let tree;
207811
207947
  try {
@@ -207898,7 +208034,7 @@ function resolveImportPath2(importingFile, sourceStr) {
207898
208034
  candidates.push(path36.join(baseRaw, `index${ext2}`));
207899
208035
  }
207900
208036
  for (const c of candidates) {
207901
- if (fs36.existsSync(c) && fs36.statSync(c).isFile())
208037
+ if (fs37.existsSync(c) && fs37.statSync(c).isFile())
207902
208038
  return c;
207903
208039
  }
207904
208040
  return null;
@@ -207971,7 +208107,7 @@ function slice2(node2, source) {
207971
208107
  // packages/contract-verifier/dist/extractor/idempotency-presence.js
207972
208108
  init_dist3();
207973
208109
  init_dist();
207974
- import fs37 from "node:fs";
208110
+ import fs38 from "node:fs";
207975
208111
  import path37 from "node:path";
207976
208112
  var TS_EXT3 = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx"]);
207977
208113
  var HTTP_METHODS6 = /* @__PURE__ */ new Set(["get", "post", "put", "delete", "patch"]);
@@ -207986,7 +208122,7 @@ async function detectIdempotencyPresence(rootDir, requestHeader) {
207986
208122
  const scanned = [];
207987
208123
  const tcIgnore = loadTcIgnore(rootDir);
207988
208124
  const visit = (dir) => {
207989
- for (const entry of fs37.readdirSync(dir, { withFileTypes: true })) {
208125
+ for (const entry of fs38.readdirSync(dir, { withFileTypes: true })) {
207990
208126
  if (entry.name === "node_modules" || entry.name === ".git")
207991
208127
  continue;
207992
208128
  const full = path37.join(dir, entry.name);
@@ -208001,7 +208137,7 @@ async function detectIdempotencyPresence(rootDir, requestHeader) {
208001
208137
  const ext2 = path37.extname(entry.name);
208002
208138
  if (!TS_EXT3.has(ext2))
208003
208139
  continue;
208004
- const source = fs37.readFileSync(full, "utf-8");
208140
+ const source = fs38.readFileSync(full, "utf-8");
208005
208141
  const lang = ext2 === ".tsx" ? "tsx" : ext2 === ".ts" ? "typescript" : "javascript";
208006
208142
  let tree;
208007
208143
  try {
@@ -208232,7 +208368,7 @@ function resolveImportPath3(importingFile, sourceStr) {
208232
208368
  candidates.push(path37.join(baseRaw, `index${ext2}`));
208233
208369
  }
208234
208370
  for (const c of candidates) {
208235
- if (fs37.existsSync(c) && fs37.statSync(c).isFile())
208371
+ if (fs38.existsSync(c) && fs38.statSync(c).isFile())
208236
208372
  return c;
208237
208373
  }
208238
208374
  return null;
@@ -211478,7 +211614,7 @@ async function extractEnumsFromDir(rootDir) {
211478
211614
  }
211479
211615
 
211480
211616
  // packages/contract-verifier/dist/extractor/forbidden/index.js
211481
- import fs39 from "node:fs";
211617
+ import fs40 from "node:fs";
211482
211618
  import path40 from "node:path";
211483
211619
 
211484
211620
  // packages/contract-verifier/dist/comparator/minimatch.js
@@ -211503,7 +211639,7 @@ function minimatch2(input, pattern) {
211503
211639
 
211504
211640
  // packages/contract-verifier/dist/extractor/manifests.js
211505
211641
  init_dist();
211506
- import fs38 from "node:fs";
211642
+ import fs39 from "node:fs";
211507
211643
  import path39 from "node:path";
211508
211644
  var SKIP_DIRS3 = /* @__PURE__ */ new Set([
211509
211645
  "node_modules",
@@ -211528,7 +211664,7 @@ function collectDependencies(rootDir) {
211528
211664
  const visit = (dir) => {
211529
211665
  let entries;
211530
211666
  try {
211531
- entries = fs38.readdirSync(dir, { withFileTypes: true });
211667
+ entries = fs39.readdirSync(dir, { withFileTypes: true });
211532
211668
  } catch {
211533
211669
  return;
211534
211670
  }
@@ -211567,7 +211703,7 @@ var NPM_FIELDS = ["dependencies", "devDependencies", "peerDependencies", "option
211567
211703
  function readPackageJson(filePath) {
211568
211704
  let pkg;
211569
211705
  try {
211570
- pkg = JSON.parse(fs38.readFileSync(filePath, "utf-8"));
211706
+ pkg = JSON.parse(fs39.readFileSync(filePath, "utf-8"));
211571
211707
  } catch {
211572
211708
  return [];
211573
211709
  }
@@ -211592,7 +211728,7 @@ function pyDistName(spec) {
211592
211728
  function readRequirements(filePath) {
211593
211729
  let text4;
211594
211730
  try {
211595
- text4 = fs38.readFileSync(filePath, "utf-8");
211731
+ text4 = fs39.readFileSync(filePath, "utf-8");
211596
211732
  } catch {
211597
211733
  return [];
211598
211734
  }
@@ -211607,7 +211743,7 @@ function readRequirements(filePath) {
211607
211743
  function readPyproject(filePath) {
211608
211744
  let text4;
211609
211745
  try {
211610
- text4 = fs38.readFileSync(filePath, "utf-8");
211746
+ text4 = fs39.readFileSync(filePath, "utf-8");
211611
211747
  } catch {
211612
211748
  return [];
211613
211749
  }
@@ -211632,7 +211768,7 @@ function readPyproject(filePath) {
211632
211768
  function readSetupPy(filePath) {
211633
211769
  let text4;
211634
211770
  try {
211635
- text4 = fs38.readFileSync(filePath, "utf-8");
211771
+ text4 = fs39.readFileSync(filePath, "utf-8");
211636
211772
  } catch {
211637
211773
  return [];
211638
211774
  }
@@ -211650,7 +211786,7 @@ function readSetupPy(filePath) {
211650
211786
  function readXmlPackageTags(filePath, tag, idAttr, versionAttr, field) {
211651
211787
  let text4;
211652
211788
  try {
211653
- text4 = fs38.readFileSync(filePath, "utf-8");
211789
+ text4 = fs39.readFileSync(filePath, "utf-8");
211654
211790
  } catch {
211655
211791
  return [];
211656
211792
  }
@@ -211685,7 +211821,7 @@ function detectForbiddenFiles(rootDir, pattern) {
211685
211821
  const visit = (dir) => {
211686
211822
  let entries;
211687
211823
  try {
211688
- entries = fs39.readdirSync(dir, { withFileTypes: true });
211824
+ entries = fs40.readdirSync(dir, { withFileTypes: true });
211689
211825
  } catch {
211690
211826
  return;
211691
211827
  }
@@ -211922,7 +212058,7 @@ function detectFlagInConfigFiles(rootDir, name) {
211922
212058
  const visit = (dir) => {
211923
212059
  let entries;
211924
212060
  try {
211925
- entries = fs39.readdirSync(dir, { withFileTypes: true });
212061
+ entries = fs40.readdirSync(dir, { withFileTypes: true });
211926
212062
  } catch {
211927
212063
  return;
211928
212064
  }
@@ -211941,7 +212077,7 @@ function detectFlagInConfigFiles(rootDir, name) {
211941
212077
  continue;
211942
212078
  let source;
211943
212079
  try {
211944
- source = fs39.readFileSync(full, "utf-8");
212080
+ source = fs40.readFileSync(full, "utf-8");
211945
212081
  } catch {
211946
212082
  continue;
211947
212083
  }
@@ -214857,7 +214993,7 @@ function extractEmissionFacts(ops) {
214857
214993
 
214858
214994
  // packages/contract-verifier/dist/extractor/entity-schema/index.js
214859
214995
  init_dist();
214860
- import fs40 from "node:fs";
214996
+ import fs41 from "node:fs";
214861
214997
  import path41 from "node:path";
214862
214998
  var SKIP_DIRS5 = /* @__PURE__ */ new Set([
214863
214999
  "node_modules",
@@ -214878,7 +215014,7 @@ async function extractEntitiesFromDir(rootDir) {
214878
215014
  const walk20 = (dir) => {
214879
215015
  let entries;
214880
215016
  try {
214881
- entries = fs40.readdirSync(dir, { withFileTypes: true });
215017
+ entries = fs41.readdirSync(dir, { withFileTypes: true });
214882
215018
  } catch {
214883
215019
  return;
214884
215020
  }
@@ -214891,7 +215027,7 @@ async function extractEntitiesFromDir(rootDir) {
214891
215027
  if (e.isDirectory())
214892
215028
  walk20(full);
214893
215029
  else if (e.isFile() && e.name.endsWith(".prisma")) {
214894
- out.push(...parsePrismaModels(full, fs40.readFileSync(full, "utf-8")));
215030
+ out.push(...parsePrismaModels(full, fs41.readFileSync(full, "utf-8")));
214895
215031
  }
214896
215032
  }
214897
215033
  };
@@ -216405,7 +216541,7 @@ function importsMatching(scan3, modules) {
216405
216541
  }
216406
216542
 
216407
216543
  // packages/contract-verifier/dist/extractor/architecture/shared/config-files.js
216408
- import fs41 from "node:fs";
216544
+ import fs42 from "node:fs";
216409
216545
  import path42 from "node:path";
216410
216546
  init_dist();
216411
216547
  var SKIP_DIRS6 = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", "build", ".next", "coverage", ".cache", ".truecourse"]);
@@ -216416,7 +216552,7 @@ function collectFileIndex(rootDir) {
216416
216552
  const visit = (dir) => {
216417
216553
  let entries;
216418
216554
  try {
216419
- entries = fs41.readdirSync(dir, { withFileTypes: true });
216555
+ entries = fs42.readdirSync(dir, { withFileTypes: true });
216420
216556
  } catch {
216421
216557
  return;
216422
216558
  }
@@ -216442,7 +216578,7 @@ function collectFileIndex(rootDir) {
216442
216578
  return cache3.get(relPath);
216443
216579
  let text4;
216444
216580
  try {
216445
- text4 = fs41.readFileSync(path42.join(rootDir, relPath), "utf-8");
216581
+ text4 = fs42.readFileSync(path42.join(rootDir, relPath), "utf-8");
216446
216582
  } catch {
216447
216583
  text4 = null;
216448
216584
  }
@@ -216778,7 +216914,7 @@ async function extractOperationsFromDir(rootDir) {
216778
216914
  const fileAnalyses = [];
216779
216915
  const tcIgnore = loadTcIgnore(rootDir);
216780
216916
  const visit = (dir) => {
216781
- for (const entry of fs42.readdirSync(dir, { withFileTypes: true })) {
216917
+ for (const entry of fs43.readdirSync(dir, { withFileTypes: true })) {
216782
216918
  if (entry.name === "node_modules" || entry.name === ".git")
216783
216919
  continue;
216784
216920
  const full = path44.join(dir, entry.name);
@@ -216795,7 +216931,7 @@ async function extractOperationsFromDir(rootDir) {
216795
216931
  continue;
216796
216932
  if (isTestFile3(full))
216797
216933
  continue;
216798
- const source = fs42.readFileSync(full, "utf-8");
216934
+ const source = fs43.readFileSync(full, "utf-8");
216799
216935
  const lang = ext2 === ".ts" || ext2 === ".tsx" ? ext2 === ".tsx" ? "tsx" : "typescript" : "javascript";
216800
216936
  let tree;
216801
216937
  try {
@@ -218820,7 +218956,7 @@ function describeExposure(c) {
218820
218956
  }
218821
218957
 
218822
218958
  // packages/contract-verifier/dist/verify.js
218823
- import fs43 from "node:fs";
218959
+ import fs44 from "node:fs";
218824
218960
  import path46 from "node:path";
218825
218961
 
218826
218962
  // packages/contract-verifier/dist/occurrence.js
@@ -219055,12 +219191,12 @@ function assignEnclosingSymbols(drifts, index) {
219055
219191
  async function verify(opts) {
219056
219192
  const specFiles = [];
219057
219193
  walkTcFiles(opts.contractsDir, (filePath) => {
219058
- specFiles.push({ path: filePath, source: fs43.readFileSync(filePath, "utf-8") });
219194
+ specFiles.push({ path: filePath, source: fs44.readFileSync(filePath, "utf-8") });
219059
219195
  }, opts.includeInferred ?? false);
219060
219196
  const baseFiles = [];
219061
- if (opts.baseContractsDir && fs43.existsSync(opts.baseContractsDir)) {
219197
+ if (opts.baseContractsDir && fs44.existsSync(opts.baseContractsDir)) {
219062
219198
  walkTcFiles(opts.baseContractsDir, (filePath) => {
219063
- const source = fs43.readFileSync(filePath, "utf-8");
219199
+ const source = fs44.readFileSync(filePath, "utf-8");
219064
219200
  baseFiles.push(parseTcFile(filePath, source));
219065
219201
  }, opts.includeInferred ?? false);
219066
219202
  }
@@ -219450,7 +219586,7 @@ async function verify(opts) {
219450
219586
  };
219451
219587
  }
219452
219588
  function walkTcFiles(rootDir, visit, includeInferred) {
219453
- for (const entry of fs43.readdirSync(rootDir, { withFileTypes: true })) {
219589
+ for (const entry of fs44.readdirSync(rootDir, { withFileTypes: true })) {
219454
219590
  const full = path46.join(rootDir, entry.name);
219455
219591
  if (entry.isDirectory()) {
219456
219592
  if (!includeInferred && entry.name === "_inferred")
@@ -219465,7 +219601,7 @@ function cryptoRandomId() {
219465
219601
  }
219466
219602
 
219467
219603
  // packages/contract-verifier/dist/infer/index.js
219468
- import fs44 from "node:fs";
219604
+ import fs45 from "node:fs";
219469
219605
  import path48 from "node:path";
219470
219606
 
219471
219607
  // packages/contract-verifier/dist/infer/serialize.js
@@ -219771,7 +219907,7 @@ async function infer(opts) {
219771
219907
  function loadAuthored(contractsDir) {
219772
219908
  const files = [];
219773
219909
  walkAuthoredTcFiles(contractsDir, (filePath) => {
219774
- files.push({ path: filePath, source: fs44.readFileSync(filePath, "utf-8") });
219910
+ files.push({ path: filePath, source: fs45.readFileSync(filePath, "utf-8") });
219775
219911
  });
219776
219912
  return parseAndResolve(files).index;
219777
219913
  }
@@ -220470,21 +220606,21 @@ function writeInferred(contractsDir, decisions, options = {}) {
220470
220606
  proposed.push(filePath);
220471
220607
  continue;
220472
220608
  }
220473
- fs44.mkdirSync(path48.dirname(filePath), { recursive: true });
220474
- const existing = fs44.existsSync(filePath) ? fs44.readFileSync(filePath, "utf-8") : null;
220609
+ fs45.mkdirSync(path48.dirname(filePath), { recursive: true });
220610
+ const existing = fs45.existsSync(filePath) ? fs45.readFileSync(filePath, "utf-8") : null;
220475
220611
  if (existing === r.tcSource)
220476
220612
  continue;
220477
- fs44.writeFileSync(filePath, r.tcSource);
220613
+ fs45.writeFileSync(filePath, r.tcSource);
220478
220614
  written.push(filePath);
220479
220615
  }
220480
- if (!options.dryRun && fs44.existsSync(root))
220616
+ if (!options.dryRun && fs45.existsSync(root))
220481
220617
  pruneStale(root, live);
220482
220618
  return { written, proposed };
220483
220619
  }
220484
220620
  function walkAuthoredTcFiles(rootDir, visit) {
220485
- if (!fs44.existsSync(rootDir))
220621
+ if (!fs45.existsSync(rootDir))
220486
220622
  return;
220487
- for (const entry of fs44.readdirSync(rootDir, { withFileTypes: true })) {
220623
+ for (const entry of fs45.readdirSync(rootDir, { withFileTypes: true })) {
220488
220624
  if (entry.isDirectory()) {
220489
220625
  if (entry.name === INFERRED_DIR)
220490
220626
  continue;
@@ -220500,22 +220636,22 @@ function toRelCode(codeDir, fp) {
220500
220636
  }
220501
220637
  function pruneStale(root, live) {
220502
220638
  const visit = (dir) => {
220503
- if (!fs44.existsSync(dir))
220639
+ if (!fs45.existsSync(dir))
220504
220640
  return false;
220505
220641
  let dirEmpty = true;
220506
- for (const entry of fs44.readdirSync(dir, { withFileTypes: true })) {
220642
+ for (const entry of fs45.readdirSync(dir, { withFileTypes: true })) {
220507
220643
  const full = path48.join(dir, entry.name);
220508
220644
  if (entry.isDirectory()) {
220509
220645
  if (visit(full)) {
220510
220646
  try {
220511
- fs44.rmdirSync(full);
220647
+ fs45.rmdirSync(full);
220512
220648
  } catch {
220513
220649
  }
220514
220650
  } else {
220515
220651
  dirEmpty = false;
220516
220652
  }
220517
220653
  } else if (entry.isFile() && entry.name.endsWith(".tc") && !live.has(full)) {
220518
- fs44.unlinkSync(full);
220654
+ fs45.unlinkSync(full);
220519
220655
  } else {
220520
220656
  dirEmpty = false;
220521
220657
  }
@@ -220670,7 +220806,7 @@ function validateMerged(artifacts) {
220670
220806
  }
220671
220807
 
220672
220808
  // packages/contract-extractor/dist/writer.js
220673
- import fs45 from "node:fs";
220809
+ import fs46 from "node:fs";
220674
220810
  import path49 from "node:path";
220675
220811
 
220676
220812
  // packages/contract-extractor/dist/identity.js
@@ -220707,14 +220843,14 @@ function writeContracts(repoRoot, artifacts, options = {}) {
220707
220843
  proposed.push(req.filePath);
220708
220844
  continue;
220709
220845
  }
220710
- fs45.mkdirSync(path49.dirname(req.filePath), { recursive: true });
220711
- const existing = fs45.existsSync(req.filePath) ? fs45.readFileSync(req.filePath, "utf-8") : null;
220846
+ fs46.mkdirSync(path49.dirname(req.filePath), { recursive: true });
220847
+ const existing = fs46.existsSync(req.filePath) ? fs46.readFileSync(req.filePath, "utf-8") : null;
220712
220848
  if (existing === req.tcSource)
220713
220849
  continue;
220714
- fs45.writeFileSync(req.filePath, req.tcSource);
220850
+ fs46.writeFileSync(req.filePath, req.tcSource);
220715
220851
  written.push(req.filePath);
220716
220852
  }
220717
- if (options.prune && !options.dryRun && fs45.existsSync(root)) {
220853
+ if (options.prune && !options.dryRun && fs46.existsSync(root)) {
220718
220854
  const live = new Set(requests.map((r) => r.filePath));
220719
220855
  pruneStale2(root, live);
220720
220856
  }
@@ -220780,16 +220916,16 @@ function inferKindDomain2(artifact) {
220780
220916
  }
220781
220917
  function pruneStale2(root, live) {
220782
220918
  const visit = (dir) => {
220783
- if (!fs45.existsSync(dir))
220919
+ if (!fs46.existsSync(dir))
220784
220920
  return false;
220785
220921
  let dirEmpty = true;
220786
- for (const entry of fs45.readdirSync(dir, { withFileTypes: true })) {
220922
+ for (const entry of fs46.readdirSync(dir, { withFileTypes: true })) {
220787
220923
  const full = path49.join(dir, entry.name);
220788
220924
  if (entry.isDirectory()) {
220789
220925
  const childEmpty = visit(full);
220790
220926
  if (childEmpty) {
220791
220927
  try {
220792
- fs45.rmdirSync(full);
220928
+ fs46.rmdirSync(full);
220793
220929
  } catch {
220794
220930
  }
220795
220931
  } else {
@@ -220797,7 +220933,7 @@ function pruneStale2(root, live) {
220797
220933
  }
220798
220934
  } else if (entry.isFile()) {
220799
220935
  if (entry.name.endsWith(".tc") && !live.has(full)) {
220800
- fs45.unlinkSync(full);
220936
+ fs46.unlinkSync(full);
220801
220937
  } else {
220802
220938
  dirEmpty = false;
220803
220939
  }
@@ -223726,7 +223862,7 @@ async function assembleArtifacts(ranked, slices, opts = {}) {
223726
223862
  }
223727
223863
 
223728
223864
  // packages/contract-extractor/dist/corpus-reader.js
223729
- import fs46 from "node:fs";
223865
+ import fs47 from "node:fs";
223730
223866
  import path50 from "node:path";
223731
223867
  function hasCorpusSpec(repoRoot) {
223732
223868
  return readCorpus(repoRoot) !== null;
@@ -223824,7 +223960,7 @@ function orderByPrecedence(docs, areaId, relations) {
223824
223960
  }
223825
223961
  function defaultResolveContent(repoRoot, ref) {
223826
223962
  try {
223827
- return fs46.readFileSync(path50.join(repoRoot, ref), "utf-8");
223963
+ return fs47.readFileSync(path50.join(repoRoot, ref), "utf-8");
223828
223964
  } catch {
223829
223965
  return null;
223830
223966
  }
@@ -223964,7 +224100,7 @@ import { createHash as createHash12 } from "node:crypto";
223964
224100
  init_transport();
223965
224101
 
223966
224102
  // packages/contract-extractor/dist/manifest.js
223967
- import fs47 from "node:fs";
224103
+ import fs48 from "node:fs";
223968
224104
  import path51 from "node:path";
223969
224105
  import { createHash as createHash11 } from "node:crypto";
223970
224106
  var MANIFEST_REL = path51.join(".truecourse", "contracts", "manifest.json");
@@ -223983,7 +224119,7 @@ function manifestPath2(repoRoot) {
223983
224119
  }
223984
224120
  function readManifest2(repoRoot) {
223985
224121
  try {
223986
- const raw = JSON.parse(fs47.readFileSync(manifestPath2(repoRoot), "utf-8"));
224122
+ const raw = JSON.parse(fs48.readFileSync(manifestPath2(repoRoot), "utf-8"));
223987
224123
  if (raw && raw.version === 1 && raw.areas)
223988
224124
  return raw;
223989
224125
  } catch {
@@ -223992,8 +224128,8 @@ function readManifest2(repoRoot) {
223992
224128
  }
223993
224129
  function writeManifest2(repoRoot, manifest) {
223994
224130
  const file = manifestPath2(repoRoot);
223995
- fs47.mkdirSync(path51.dirname(file), { recursive: true });
223996
- fs47.writeFileSync(file, JSON.stringify(manifest, null, 2) + "\n");
224131
+ fs48.mkdirSync(path51.dirname(file), { recursive: true });
224132
+ fs48.writeFileSync(file, JSON.stringify(manifest, null, 2) + "\n");
223997
224133
  }
223998
224134
  function classifyAreas(areas, manifest) {
223999
224135
  const prev = manifest?.areas ?? {};
@@ -224451,7 +224587,7 @@ function spawnGenerateRunner(opts = {}) {
224451
224587
  }
224452
224588
 
224453
224589
  // packages/core/dist/config/llm-models.js
224454
- import fs48 from "node:fs";
224590
+ import fs49 from "node:fs";
224455
224591
  var STAGE_DEFAULTS = {
224456
224592
  "spec.relevance": "haiku",
224457
224593
  // Area tagging is load-bearing (wrong tags → wrong generate inputs) and Haiku
@@ -224499,10 +224635,10 @@ function stageEnvVar(stageId) {
224499
224635
  }
224500
224636
  function readConfigSync(repoDir) {
224501
224637
  const file = getRepoConfigPath(repoDir);
224502
- if (!fs48.existsSync(file))
224638
+ if (!fs49.existsSync(file))
224503
224639
  return {};
224504
224640
  try {
224505
- return JSON.parse(fs48.readFileSync(file, "utf-8"));
224641
+ return JSON.parse(fs49.readFileSync(file, "utf-8"));
224506
224642
  } catch {
224507
224643
  return {};
224508
224644
  }
@@ -224539,7 +224675,7 @@ function resolveFallbackModel(repoDir = resolveRepoDir(process.cwd())) {
224539
224675
  init_transport();
224540
224676
 
224541
224677
  // packages/core/dist/lib/llm-call-log.js
224542
- import fs49 from "node:fs";
224678
+ import fs50 from "node:fs";
224543
224679
  import path52 from "node:path";
224544
224680
  import { randomUUID as randomUUID20 } from "node:crypto";
224545
224681
  function truthyEnv(v) {
@@ -224561,20 +224697,20 @@ function createLlmCallLogger(repoRoot, label = "scan") {
224561
224697
  if (!log2 && !dump2)
224562
224698
  return null;
224563
224699
  const logDir = path52.join(repoRoot, ".truecourse", "logs");
224564
- fs49.mkdirSync(logDir, { recursive: true });
224700
+ fs50.mkdirSync(logDir, { recursive: true });
224565
224701
  const runId = `${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}_${randomUUID20().slice(0, 8)}`;
224566
224702
  const callsPath = path52.join(logDir, `llm-${label}-${runId}.jsonl`);
224567
224703
  const summaryPath = path52.join(logDir, `llm-${label}-${runId}.summary.json`);
224568
224704
  const ioDir = dump2 ? path52.join(logDir, `llm-${label}-${runId}.io`) : null;
224569
224705
  if (ioDir)
224570
- fs49.mkdirSync(ioDir, { recursive: true });
224706
+ fs50.mkdirSync(ioDir, { recursive: true });
224571
224707
  const createdAt = Date.now();
224572
224708
  const records = [];
224573
224709
  let seq2 = 0;
224574
224710
  let finished = false;
224575
224711
  let fd = null;
224576
224712
  try {
224577
- fd = fs49.openSync(callsPath, "a");
224713
+ fd = fs50.openSync(callsPath, "a");
224578
224714
  } catch {
224579
224715
  fd = null;
224580
224716
  }
@@ -224584,14 +224720,14 @@ function createLlmCallLogger(repoRoot, label = "scan") {
224584
224720
  records.push(metrics);
224585
224721
  if (fd !== null) {
224586
224722
  try {
224587
- fs49.writeSync(fd, JSON.stringify(metrics) + "\n");
224723
+ fs50.writeSync(fd, JSON.stringify(metrics) + "\n");
224588
224724
  } catch {
224589
224725
  }
224590
224726
  }
224591
224727
  if (ioDir) {
224592
224728
  const fname = `${String(seq2).padStart(5, "0")}-${sanitize3(rec.id) || rec.stage}.json`;
224593
224729
  try {
224594
- fs49.writeFileSync(path52.join(ioDir, fname), JSON.stringify({
224730
+ fs50.writeFileSync(path52.join(ioDir, fname), JSON.stringify({
224595
224731
  stage: rec.stage,
224596
224732
  model: rec.model,
224597
224733
  ok: rec.ok,
@@ -224621,13 +224757,13 @@ function createLlmCallLogger(repoRoot, label = "scan") {
224621
224757
  process.removeListener(sig, h);
224622
224758
  if (fd !== null) {
224623
224759
  try {
224624
- fs49.closeSync(fd);
224760
+ fs50.closeSync(fd);
224625
224761
  } catch {
224626
224762
  }
224627
224763
  }
224628
224764
  const summary = summarizeLlmCalls(records, elapsedMs);
224629
224765
  try {
224630
- fs49.writeFileSync(summaryPath, JSON.stringify(summary, null, 2));
224766
+ fs50.writeFileSync(summaryPath, JSON.stringify(summary, null, 2));
224631
224767
  } catch {
224632
224768
  }
224633
224769
  printSummary(summary, callsPath, ioDir);
@@ -224753,7 +224889,7 @@ init_dist();
224753
224889
 
224754
224890
  // packages/guard-generator/dist/section-plan.js
224755
224891
  init_zod();
224756
- import fs50 from "node:fs";
224892
+ import fs51 from "node:fs";
224757
224893
  import path53 from "node:path";
224758
224894
  import { createHash as createHash14 } from "node:crypto";
224759
224895
  init_dist();
@@ -225071,10 +225207,10 @@ var CorpusShape2 = external_exports.object({
225071
225207
  function readCorpusAreaTags(repoRoot) {
225072
225208
  const file = path53.join(repoRoot, ".truecourse", "specs", "corpus.json");
225073
225209
  const map2 = /* @__PURE__ */ new Map();
225074
- if (!fs50.existsSync(file))
225210
+ if (!fs51.existsSync(file))
225075
225211
  return map2;
225076
225212
  try {
225077
- const parsed = CorpusShape2.safeParse(JSON.parse(fs50.readFileSync(file, "utf-8")));
225213
+ const parsed = CorpusShape2.safeParse(JSON.parse(fs51.readFileSync(file, "utf-8")));
225078
225214
  if (!parsed.success)
225079
225215
  return map2;
225080
225216
  for (const d of parsed.data.docs ?? [])
@@ -225093,17 +225229,17 @@ function generationInputsHash(fingerprint2, recipeFingerprint) {
225093
225229
  ].join("\0")).digest("hex");
225094
225230
  }
225095
225231
  function hasGuardUniverse(repoRoot) {
225096
- return fs50.existsSync(path53.join(repoRoot, ".truecourse", "specs", "corpus.json"));
225232
+ return fs51.existsSync(path53.join(repoRoot, ".truecourse", "specs", "corpus.json"));
225097
225233
  }
225098
225234
  function planGuardWork(repoRoot, recipeFingerprint) {
225099
225235
  const recipeFp = recipeFingerprint ?? computeRecipeFingerprint(repoRoot);
225100
- const recipeMissing = !fs50.existsSync(recipePath(repoRoot));
225236
+ const recipeMissing = !fs51.existsSync(recipePath(repoRoot));
225101
225237
  const hasUniverse = hasGuardUniverse(repoRoot);
225102
225238
  const { indexes } = indexRepoDocs(repoRoot, []);
225103
225239
  const areaTags = readCorpusAreaTags(repoRoot);
225104
225240
  const sections = [];
225105
225241
  for (const [doc, index] of indexes) {
225106
- const texts = extractSectionTexts(doc, fs50.readFileSync(path53.resolve(repoRoot, doc), "utf-8"));
225242
+ const texts = extractSectionTexts(doc, fs51.readFileSync(path53.resolve(repoRoot, doc), "utf-8"));
225107
225243
  for (const s of index.sections) {
225108
225244
  const t = texts.get(s.anchor);
225109
225245
  sections.push({
@@ -225148,7 +225284,7 @@ function collectWorkDocs(repoRoot, plan) {
225148
225284
  }
225149
225285
  return [...byDoc].map(([doc, sections]) => ({
225150
225286
  doc,
225151
- content: fs50.readFileSync(path53.resolve(repoRoot, doc), "utf-8"),
225287
+ content: fs51.readFileSync(path53.resolve(repoRoot, doc), "utf-8"),
225152
225288
  sections
225153
225289
  }));
225154
225290
  }
@@ -225535,7 +225671,7 @@ function truncate2(text4) {
225535
225671
  }
225536
225672
 
225537
225673
  // packages/guard-generator/dist/recipe-discovery.js
225538
- import fs51 from "node:fs";
225674
+ import fs52 from "node:fs";
225539
225675
  import os7 from "node:os";
225540
225676
  import path55 from "node:path";
225541
225677
  import { createHash as createHash17 } from "node:crypto";
@@ -225591,8 +225727,8 @@ async function discoverRecipe(repoRoot, runner2) {
225591
225727
  ...proposal.env ? { env: proposal.env } : {}
225592
225728
  };
225593
225729
  const target = recipePath(repoRoot);
225594
- fs51.mkdirSync(path55.dirname(target), { recursive: true });
225595
- fs51.writeFileSync(target, JSON.stringify(recipe, null, 2) + "\n");
225730
+ fs52.mkdirSync(path55.dirname(target), { recursive: true });
225731
+ fs52.writeFileSync(target, JSON.stringify(recipe, null, 2) + "\n");
225596
225732
  return {
225597
225733
  status: "discovered",
225598
225734
  recipe,
@@ -225623,13 +225759,13 @@ async function proposeRecipeWithReask(input, runner2) {
225623
225759
  }
225624
225760
  function readDiscoveryInputs(repoRoot) {
225625
225761
  const pkgPath = path55.join(repoRoot, "package.json");
225626
- const packageJson = fs51.existsSync(pkgPath) ? fs51.readFileSync(pkgPath, "utf-8") : "(no package.json)";
225627
- const presentInputs = DISCOVERY_INPUTS.filter((f2) => fs51.existsSync(path55.join(repoRoot, f2)));
225762
+ const packageJson = fs52.existsSync(pkgPath) ? fs52.readFileSync(pkgPath, "utf-8") : "(no package.json)";
225763
+ const presentInputs = DISCOVERY_INPUTS.filter((f2) => fs52.existsSync(path55.join(repoRoot, f2)));
225628
225764
  return { packageJson, presentInputs };
225629
225765
  }
225630
225766
  async function probeEntry(repoRoot, entry) {
225631
225767
  const resolved = resolveEntry(repoRoot, entry);
225632
- const cwd = fs51.mkdtempSync(path55.join(os7.tmpdir(), "tc-guard-probe-"));
225768
+ const cwd = fs52.mkdtempSync(path55.join(os7.tmpdir(), "tc-guard-probe-"));
225633
225769
  try {
225634
225770
  for (const args of [["--help"], []]) {
225635
225771
  const capture = await executeStep({
@@ -225646,7 +225782,7 @@ async function probeEntry(repoRoot, entry) {
225646
225782
  reason: `entrypoint ${JSON.stringify(entry)} did not answer to \`--help\` or a bare invocation`
225647
225783
  };
225648
225784
  } finally {
225649
- fs51.rmSync(cwd, { recursive: true, force: true });
225785
+ fs52.rmSync(cwd, { recursive: true, force: true });
225650
225786
  }
225651
225787
  }
225652
225788
 
@@ -225693,7 +225829,7 @@ async function birthValidate(repoRoot, candidates, opts = {}) {
225693
225829
  }
225694
225830
 
225695
225831
  // packages/guard-generator/dist/serialize.js
225696
- import fs52 from "node:fs";
225832
+ import fs53 from "node:fs";
225697
225833
  import path56 from "node:path";
225698
225834
  init_dist();
225699
225835
  function anchorLeaf(anchor) {
@@ -225736,15 +225872,15 @@ function scenarioFileIndex(repoRoot) {
225736
225872
  const root = scenariosDir(repoRoot);
225737
225873
  const map2 = /* @__PURE__ */ new Map();
225738
225874
  const walk20 = (dir) => {
225739
- if (!fs52.existsSync(dir))
225875
+ if (!fs53.existsSync(dir))
225740
225876
  return;
225741
- for (const entry of fs52.readdirSync(dir, { withFileTypes: true })) {
225877
+ for (const entry of fs53.readdirSync(dir, { withFileTypes: true })) {
225742
225878
  const full = path56.join(dir, entry.name);
225743
225879
  if (entry.isDirectory())
225744
225880
  walk20(full);
225745
225881
  else if (entry.isFile() && /\.ya?ml$/i.test(entry.name)) {
225746
225882
  try {
225747
- const doc = jsYaml.load(fs52.readFileSync(full, "utf-8"));
225883
+ const doc = jsYaml.load(fs53.readFileSync(full, "utf-8"));
225748
225884
  if (doc && typeof doc.id === "string")
225749
225885
  map2.set(doc.id, full);
225750
225886
  } catch {
@@ -225758,19 +225894,22 @@ function scenarioFileIndex(repoRoot) {
225758
225894
  function existingScenarioIds(repoRoot) {
225759
225895
  return new Set(loadScenarios(repoRoot).scenarios.map((s) => s.id));
225760
225896
  }
225897
+ function serializeScenarioYaml(scenario) {
225898
+ return jsYaml.dump(scenario, { lineWidth: -1, noRefs: true });
225899
+ }
225761
225900
  function writeScenarioFile(repoRoot, slug2, scenario) {
225762
225901
  const dir = path56.join(scenariosDir(repoRoot), slug2);
225763
- fs52.mkdirSync(dir, { recursive: true });
225902
+ fs53.mkdirSync(dir, { recursive: true });
225764
225903
  const file = path56.join(dir, `${scenario.id}.yaml`);
225765
- fs52.writeFileSync(file, jsYaml.dump(scenario, { lineWidth: -1, noRefs: true }));
225904
+ fs53.writeFileSync(file, serializeScenarioYaml(scenario));
225766
225905
  return path56.relative(repoRoot, file);
225767
225906
  }
225768
225907
  function deleteScenarioFiles(repoRoot, ids) {
225769
225908
  const index = scenarioFileIndex(repoRoot);
225770
225909
  for (const id of ids) {
225771
225910
  const file = index.get(id);
225772
- if (file && fs52.existsSync(file))
225773
- fs52.rmSync(file);
225911
+ if (file && fs53.existsSync(file))
225912
+ fs53.rmSync(file);
225774
225913
  }
225775
225914
  }
225776
225915
 
@@ -225840,7 +225979,9 @@ async function generateGuards(options) {
225840
225979
  errors: [],
225841
225980
  extractionFailures: [],
225842
225981
  orphaned,
225843
- birthPassed: 0
225982
+ birthPassed: 0,
225983
+ heldSections: [],
225984
+ orphanedDismissals: []
225844
225985
  };
225845
225986
  }
225846
225987
  const limit = pLimit(Math.max(1, options.concurrency ?? defaultConcurrency3()));
@@ -225855,6 +225996,10 @@ async function generateGuards(options) {
225855
225996
  const coverageGaps = [];
225856
225997
  const errors = [];
225857
225998
  const extractionFailures = [];
225999
+ const decisions = readGuardDecisions(repoRoot);
226000
+ const dismissalByKey = new Map(decisions.dismissedClaims.map((d) => [dismissedClaimKey(d.doc, d.anchor, d.title), d]));
226001
+ const extractedClaimKeys = /* @__PURE__ */ new Set();
226002
+ const extractedDocs = /* @__PURE__ */ new Set();
225858
226003
  const workDocs = collectWorkDocs(repoRoot, plan);
225859
226004
  const workKeys = new Set(plan.work.map(key2));
225860
226005
  const workDocByPath = new Map(workDocs.map((d) => [d.doc, d]));
@@ -225884,34 +226029,47 @@ async function generateGuards(options) {
225884
226029
  reason: `${result.failedViews} extraction view(s) failed \u2014 re-run to complete coverage for affected sections`
225885
226030
  });
225886
226031
  }
226032
+ extractedDocs.add(doc.doc);
226033
+ for (const c of result.data.claims) {
226034
+ extractedClaimKeys.add(dismissedClaimKey(doc.doc, c.sectionAnchor, c.claim));
226035
+ }
225887
226036
  const { claimsByAnchor, noteByAnchor } = groupExtraction(result.data);
225888
226037
  for (const s of doc.sections) {
225889
226038
  if (!workKeys.has(key2(s)))
225890
226039
  continue;
225891
226040
  const claims = claimsByAnchor.get(s.anchor) ?? [];
225892
- const cli = claims.filter((c) => isRunnableDriver(c.driver));
226041
+ const cliAll = claims.filter((c) => isRunnableDriver(c.driver));
225893
226042
  const others = claims.filter((c) => !isRunnableDriver(c.driver));
225894
226043
  const note = noteByAnchor.get(s.anchor);
226044
+ const cli = cliAll.filter((c) => !dismissalByKey.has(dismissedClaimKey(s.doc, s.anchor, c.claim)));
226045
+ const dismissed = cliAll.filter((c) => dismissalByKey.has(dismissedClaimKey(s.doc, s.anchor, c.claim)));
226046
+ for (const d of dismissed) {
226047
+ const entry = dismissalByKey.get(dismissedClaimKey(s.doc, s.anchor, d.claim));
226048
+ coverageGaps.push({ doc: s.doc, anchor: s.anchor, kind: "dismissed", reason: dismissedReason(d.claim, entry?.note) });
226049
+ }
225895
226050
  for (const o of others) {
225896
226051
  coverageGaps.push({ doc: s.doc, anchor: s.anchor, kind: "awaiting-driver", driver: o.driver, reason: o.reason });
225897
226052
  }
225898
226053
  if (cli.length === 0 && others.length === 0) {
225899
- if (!result.complete && !note) {
225900
- extractFailedKeys.add(key2(s));
225901
- continue;
226054
+ if (dismissed.length === 0) {
226055
+ if (!result.complete && !note) {
226056
+ extractFailedKeys.add(key2(s));
226057
+ continue;
226058
+ }
226059
+ coverageGaps.push({
226060
+ doc: s.doc,
226061
+ anchor: s.anchor,
226062
+ kind: note ? "untestable" : "no-claim",
226063
+ reason: note?.reason ?? "the section states no CLI-assertable claim"
226064
+ });
225902
226065
  }
225903
- coverageGaps.push({
225904
- doc: s.doc,
225905
- anchor: s.anchor,
225906
- kind: note ? "untestable" : "no-claim",
225907
- reason: note?.reason ?? "the section states no CLI-assertable claim"
225908
- });
225909
226066
  }
225910
226067
  classificationByKey.set(key2(s), deriveClassification(cli, others, note));
225911
226068
  for (const c of cli)
225912
226069
  authTasks.push({ ref: `c${refSeq++}`, section: s, claim: c });
225913
226070
  }
225914
226071
  }
226072
+ const orphanedDismissals = decisions.dismissedClaims.filter((d) => extractedDocs.has(d.doc) && !extractedClaimKeys.has(dismissedClaimKey(d.doc, d.anchor, d.title))).map((d) => ({ doc: d.doc, anchor: d.anchor, title: d.title }));
225915
226073
  const buildPromise = runBuild(repoRoot, recipe.build, recipe.env);
225916
226074
  let buildAnnounced = false;
225917
226075
  const awaitBuild = async () => {
@@ -225980,6 +226138,7 @@ async function generateGuards(options) {
225980
226138
  };
225981
226139
  const written = [];
225982
226140
  const birthFindings = [];
226141
+ const heldSections = [];
225983
226142
  let entryPreflightFailure = null;
225984
226143
  let birthTotal = 0;
225985
226144
  let birthSettled = 0;
@@ -226087,9 +226246,9 @@ async function generateGuards(options) {
226087
226246
  pushInto(r1ByRef, o.candidate.ref, o);
226088
226247
  const retryEntries = [];
226089
226248
  for (const [ref, outcomes] of r1ByRef) {
226090
- const fail = outcomes.find((o) => o.result.outcome === "fail");
226091
- if (fail) {
226092
- retryEntries.push({ task: taskByRef.get(ref), evidence: toFinding(fail) });
226249
+ const retriable2 = outcomes.find((o) => o.result.outcome === "fail" || isSetupDefectResult(o.result));
226250
+ if (retriable2) {
226251
+ retryEntries.push({ task: taskByRef.get(ref), evidence: toFinding(retriable2) });
226093
226252
  continue;
226094
226253
  }
226095
226254
  for (const o of outcomes) {
@@ -226148,6 +226307,16 @@ async function generateGuards(options) {
226148
226307
  ids.push(c.scenario.id);
226149
226308
  }
226150
226309
  upsertSection(section, ids);
226310
+ } else if (persistedHere.length > 0) {
226311
+ heldSections.push({
226312
+ doc: section.doc,
226313
+ anchor: section.anchor,
226314
+ readyScenarios: persistedHere.map((c) => ({
226315
+ id: c.scenario.id,
226316
+ title: c.scenario.title,
226317
+ yaml: serializeScenarioYaml(c.scenario)
226318
+ }))
226319
+ });
226151
226320
  }
226152
226321
  }
226153
226322
  const authorTotal = authTasks.length;
@@ -226226,6 +226395,8 @@ async function generateGuards(options) {
226226
226395
  extractionFailures,
226227
226396
  orphaned,
226228
226397
  birthPassed,
226398
+ heldSections,
226399
+ orphanedDismissals,
226229
226400
  manifestPath: manifestPath(repoRoot),
226230
226401
  ...entryPreflightFailure ? { entryPreflight: entryPreflightFailure } : {}
226231
226402
  };
@@ -226272,7 +226443,9 @@ function emptyResult(status, extra) {
226272
226443
  errors: [],
226273
226444
  extractionFailures: [],
226274
226445
  orphaned: [],
226275
- birthPassed: 0
226446
+ birthPassed: 0,
226447
+ heldSections: [],
226448
+ orphanedDismissals: []
226276
226449
  };
226277
226450
  }
226278
226451
  function readPriorManifest(repoRoot) {
@@ -226367,9 +226540,18 @@ function toFinding(o) {
226367
226540
  step: f2?.step ?? 1,
226368
226541
  expected: f2?.expected ?? "",
226369
226542
  actual: f2?.actual ?? "",
226370
- ...o.result.evidencePath ? { evidencePath: o.result.evidencePath } : {}
226543
+ ...o.result.evidencePath ? { evidencePath: o.result.evidencePath } : {},
226544
+ // Judge-on-one-screen (item 19): the failed candidate's exact YAML rides inline
226545
+ // so the finding detail shows the commands it ran; `claim` is the dismissal
226546
+ // identity (item 20) so the detail's Dismiss action can key on it.
226547
+ yaml: serializeScenarioYaml(o.candidate.scenario),
226548
+ claim: o.candidate.claim.claim
226371
226549
  };
226372
226550
  }
226551
+ function dismissedReason(claim, note) {
226552
+ const base = `dismissed: ${oneLine(claim)}`;
226553
+ return note ? `${base} \u2014 ${oneLine(note)}` : base;
226554
+ }
226373
226555
  function errorFrom(o) {
226374
226556
  return {
226375
226557
  doc: o.candidate.section.doc,
@@ -226854,7 +227036,7 @@ function routeContextInner(rules, fileAnalyses, fileContents) {
226854
227036
  }
226855
227037
 
226856
227038
  // packages/core/dist/services/llm/model-prices.js
226857
- import fs53 from "node:fs";
227039
+ import fs54 from "node:fs";
226858
227040
  import path57 from "node:path";
226859
227041
  var OPENROUTER_URL = "https://openrouter.ai/api/v1/models";
226860
227042
  var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
@@ -226875,7 +227057,7 @@ function cacheFilePath() {
226875
227057
  }
226876
227058
  function readCache7() {
226877
227059
  try {
226878
- const t = JSON.parse(fs53.readFileSync(cacheFilePath(), "utf-8"));
227060
+ const t = JSON.parse(fs54.readFileSync(cacheFilePath(), "utf-8"));
226879
227061
  if (t && t.tiers && t.byId && typeof t.fetchedAt === "number")
226880
227062
  return t;
226881
227063
  } catch {
@@ -226884,8 +227066,8 @@ function readCache7() {
226884
227066
  }
226885
227067
  function writeCache7(t) {
226886
227068
  try {
226887
- fs53.mkdirSync(path57.dirname(cacheFilePath()), { recursive: true });
226888
- fs53.writeFileSync(cacheFilePath(), JSON.stringify(t));
227069
+ fs54.mkdirSync(path57.dirname(cacheFilePath()), { recursive: true });
227070
+ fs54.writeFileSync(cacheFilePath(), JSON.stringify(t));
226889
227071
  } catch {
226890
227072
  }
226891
227073
  }
@@ -227263,7 +227445,7 @@ function changedSubject(total, changed, noun) {
227263
227445
  }
227264
227446
 
227265
227447
  // packages/core/dist/commands/spec-in-process.js
227266
- import fs58 from "node:fs";
227448
+ import fs59 from "node:fs";
227267
227449
  import path62 from "node:path";
227268
227450
  import { createHash as createHash19, randomUUID as randomUUID21 } from "node:crypto";
227269
227451
 
@@ -227284,7 +227466,7 @@ async function repoRef(repoRoot, commitOverride) {
227284
227466
  }
227285
227467
 
227286
227468
  // packages/core/dist/lib/contract-store.js
227287
- import fs54 from "node:fs";
227469
+ import fs55 from "node:fs";
227288
227470
  import path58 from "node:path";
227289
227471
  var KIND_REL = {
227290
227472
  contracts: [".truecourse", "contracts"],
@@ -227295,7 +227477,7 @@ function countTcFiles(dir) {
227295
227477
  let n = 0;
227296
227478
  let entries;
227297
227479
  try {
227298
- entries = fs54.readdirSync(dir, { withFileTypes: true });
227480
+ entries = fs55.readdirSync(dir, { withFileTypes: true });
227299
227481
  } catch {
227300
227482
  return 0;
227301
227483
  }
@@ -227312,7 +227494,7 @@ function walkTcRel(dir, excludeInferred) {
227312
227494
  const walk20 = (rel) => {
227313
227495
  let entries;
227314
227496
  try {
227315
- entries = fs54.readdirSync(path58.join(dir, rel), { withFileTypes: true });
227497
+ entries = fs55.readdirSync(path58.join(dir, rel), { withFileTypes: true });
227316
227498
  } catch {
227317
227499
  return;
227318
227500
  }
@@ -227350,13 +227532,13 @@ var FileContractStore = class {
227350
227532
  }
227351
227533
  async loadContracts(ref, kind) {
227352
227534
  const dir = path58.join(ref.repoKey, ...KIND_REL[kind]);
227353
- if (!fs54.existsSync(dir))
227535
+ if (!fs55.existsSync(dir))
227354
227536
  return null;
227355
227537
  return { dir, cleanup: async () => {
227356
227538
  } };
227357
227539
  }
227358
227540
  async hasContracts(ref, kind) {
227359
- return fs54.existsSync(path58.join(ref.repoKey, ...KIND_REL[kind]));
227541
+ return fs55.existsSync(path58.join(ref.repoKey, ...KIND_REL[kind]));
227360
227542
  }
227361
227543
  // The file impl reads the live repo tree, which is whatever is checked out —
227362
227544
  // there is no per-commit history, so `commitSha` is ignored (OSS is latest).
@@ -227365,21 +227547,21 @@ var FileContractStore = class {
227365
227547
  }
227366
227548
  async readContractFile(repoKey, kind, relPath, _commitSha) {
227367
227549
  const dest = safeResolve(path58.join(repoKey, ...KIND_REL[kind]), relPath);
227368
- if (!dest || !fs54.existsSync(dest) || !fs54.statSync(dest).isFile())
227550
+ if (!dest || !fs55.existsSync(dest) || !fs55.statSync(dest).isFile())
227369
227551
  return null;
227370
- return fs54.readFileSync(dest, "utf-8");
227552
+ return fs55.readFileSync(dest, "utf-8");
227371
227553
  }
227372
227554
  async putContractFile(ref, kind, relPath, content) {
227373
227555
  const dest = safeResolve(path58.join(ref.repoKey, ...KIND_REL[kind]), relPath);
227374
227556
  if (!dest)
227375
227557
  throw new Error(`[contract-store] unsafe contract path: ${relPath}`);
227376
- fs54.mkdirSync(path58.dirname(dest), { recursive: true });
227377
- fs54.writeFileSync(dest, content);
227558
+ fs55.mkdirSync(path58.dirname(dest), { recursive: true });
227559
+ fs55.writeFileSync(dest, content);
227378
227560
  }
227379
227561
  async deleteContractFile(ref, kind, relPath) {
227380
227562
  const dest = safeResolve(path58.join(ref.repoKey, ...KIND_REL[kind]), relPath);
227381
227563
  if (dest)
227382
- fs54.rmSync(dest, { force: true });
227564
+ fs55.rmSync(dest, { force: true });
227383
227565
  }
227384
227566
  // OSS/local has no workspace concept (mirrors the spec store). Writing throws
227385
227567
  // (fail loud — a caller that reached here is mis-wired); reads are empty so an
@@ -227409,16 +227591,16 @@ var readWorkspaceContractFile = (ref, kind, relPath) => active9.readWorkspaceCon
227409
227591
  var contractsMaterializeInPlace = () => active9.materializesInPlace;
227410
227592
 
227411
227593
  // packages/core/dist/lib/repo-doc-reader.js
227412
- import fs55 from "node:fs";
227594
+ import fs56 from "node:fs";
227413
227595
  import path59 from "node:path";
227414
227596
  var fileRepoDocReader = async (repoKey, docPath) => {
227415
227597
  const root = path59.resolve(repoKey);
227416
227598
  const full = path59.resolve(root, docPath);
227417
227599
  if (full !== root && !full.startsWith(root + path59.sep))
227418
227600
  return null;
227419
- if (!fs55.existsSync(full) || !fs55.statSync(full).isFile())
227601
+ if (!fs56.existsSync(full) || !fs56.statSync(full).isFile())
227420
227602
  return null;
227421
- return fs55.readFileSync(full, "utf-8");
227603
+ return fs56.readFileSync(full, "utf-8");
227422
227604
  };
227423
227605
  var reader = fileRepoDocReader;
227424
227606
  function readRepoDoc(repoKey, docPath, opts) {
@@ -227426,7 +227608,7 @@ function readRepoDoc(repoKey, docPath, opts) {
227426
227608
  }
227427
227609
 
227428
227610
  // packages/core/dist/lib/inferred-action-store.js
227429
- import fs56 from "node:fs";
227611
+ import fs57 from "node:fs";
227430
227612
  import path60 from "node:path";
227431
227613
  function actionsFile(repoKey) {
227432
227614
  return path60.join(repoKey, ".truecourse", "specs", "inferred-actions.json");
@@ -227434,15 +227616,15 @@ function actionsFile(repoKey) {
227434
227616
  var FileInferredActionStore = class {
227435
227617
  read(repoKey) {
227436
227618
  try {
227437
- return JSON.parse(fs56.readFileSync(actionsFile(repoKey), "utf-8"));
227619
+ return JSON.parse(fs57.readFileSync(actionsFile(repoKey), "utf-8"));
227438
227620
  } catch {
227439
227621
  return [];
227440
227622
  }
227441
227623
  }
227442
227624
  write(repoKey, actions) {
227443
227625
  const file = actionsFile(repoKey);
227444
- fs56.mkdirSync(path60.dirname(file), { recursive: true });
227445
- fs56.writeFileSync(file, JSON.stringify(actions, null, 2) + "\n", "utf-8");
227626
+ fs57.mkdirSync(path60.dirname(file), { recursive: true });
227627
+ fs57.writeFileSync(file, JSON.stringify(actions, null, 2) + "\n", "utf-8");
227446
227628
  }
227447
227629
  async setAction(repoKey, action) {
227448
227630
  const next = this.read(repoKey).filter((a) => !(a.kind === action.kind && a.identity === action.identity));
@@ -227565,7 +227747,7 @@ async function reapplyPromoted(ref, decisions) {
227565
227747
  }
227566
227748
 
227567
227749
  // packages/core/dist/services/telemetry.service.js
227568
- import fs57 from "node:fs";
227750
+ import fs58 from "node:fs";
227569
227751
  import path61 from "node:path";
227570
227752
  import os9 from "node:os";
227571
227753
  import crypto5 from "node:crypto";
@@ -231361,7 +231543,7 @@ function getTelemetryConfigPath() {
231361
231543
  function readTelemetryConfig() {
231362
231544
  const configPath = getTelemetryConfigPath();
231363
231545
  try {
231364
- const raw = fs57.readFileSync(configPath, "utf-8");
231546
+ const raw = fs58.readFileSync(configPath, "utf-8");
231365
231547
  const parsed = JSON.parse(raw);
231366
231548
  const config2 = { ...DEFAULT_CONFIG, ...parsed };
231367
231549
  if (!config2.anonymousId) {
@@ -231382,16 +231564,16 @@ function readTelemetryConfig() {
231382
231564
  function writeTelemetryConfig(partial) {
231383
231565
  const configPath = getTelemetryConfigPath();
231384
231566
  const dir = path61.dirname(configPath);
231385
- fs57.mkdirSync(dir, { recursive: true });
231567
+ fs58.mkdirSync(dir, { recursive: true });
231386
231568
  let current;
231387
231569
  try {
231388
- const raw = fs57.readFileSync(configPath, "utf-8");
231570
+ const raw = fs58.readFileSync(configPath, "utf-8");
231389
231571
  current = { ...DEFAULT_CONFIG, ...JSON.parse(raw) };
231390
231572
  } catch {
231391
231573
  current = { ...DEFAULT_CONFIG };
231392
231574
  }
231393
231575
  const merged = { ...current, ...partial };
231394
- fs57.writeFileSync(configPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
231576
+ fs58.writeFileSync(configPath, JSON.stringify(merged, null, 2) + "\n", "utf-8");
231395
231577
  }
231396
231578
  var posthogClient = null;
231397
231579
  function isTelemetryEnabled() {
@@ -231463,13 +231645,13 @@ function readToolVersion() {
231463
231645
  if (cachedVersion)
231464
231646
  return cachedVersion;
231465
231647
  if (true) {
231466
- cachedVersion = "0.7.0-next.3";
231648
+ cachedVersion = "0.7.0-next.4";
231467
231649
  return cachedVersion;
231468
231650
  }
231469
231651
  try {
231470
231652
  const here = fileURLToPath5(import.meta.url);
231471
231653
  const pkgPath = path61.resolve(path61.dirname(here), "..", "..", "package.json");
231472
- const pkg = JSON.parse(fs57.readFileSync(pkgPath, "utf-8"));
231654
+ const pkg = JSON.parse(fs58.readFileSync(pkgPath, "utf-8"));
231473
231655
  cachedVersion = String(pkg.version ?? "0.0.0");
231474
231656
  } catch {
231475
231657
  cachedVersion = "0.0.0";
@@ -231615,7 +231797,7 @@ function generatedMarkerPath(repoRoot) {
231615
231797
  }
231616
231798
  function stampGeneratedMarker(repoRoot, summary) {
231617
231799
  const file = generatedMarkerPath(repoRoot);
231618
- fs58.mkdirSync(path62.dirname(file), { recursive: true });
231800
+ fs59.mkdirSync(path62.dirname(file), { recursive: true });
231619
231801
  const body = {
231620
231802
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
231621
231803
  written: summary?.written ?? 0,
@@ -231623,11 +231805,11 @@ function stampGeneratedMarker(repoRoot, summary) {
231623
231805
  validationIssues: summary?.validationIssues ?? [],
231624
231806
  enumerateFailures: summary?.enumerateFailures ?? []
231625
231807
  };
231626
- fs58.writeFileSync(file, JSON.stringify(body, null, 2) + "\n");
231808
+ fs59.writeFileSync(file, JSON.stringify(body, null, 2) + "\n");
231627
231809
  }
231628
231810
  function readGeneratedSummary(repoRoot) {
231629
231811
  try {
231630
- const raw = JSON.parse(fs58.readFileSync(generatedMarkerPath(repoRoot), "utf-8"));
231812
+ const raw = JSON.parse(fs59.readFileSync(generatedMarkerPath(repoRoot), "utf-8"));
231631
231813
  return {
231632
231814
  generatedAt: typeof raw.generatedAt === "string" ? raw.generatedAt : "",
231633
231815
  written: typeof raw.written === "number" ? raw.written : 0,
@@ -231762,19 +231944,19 @@ async function curateInProcess(repoRoot, options = {}) {
231762
231944
  }
231763
231945
  function buildPriorContracts(repoRoot) {
231764
231946
  const dir = path62.join(repoRoot, ".truecourse", "contracts");
231765
- if (!fs58.existsSync(dir))
231947
+ if (!fs59.existsSync(dir))
231766
231948
  return void 0;
231767
231949
  const targets = [];
231768
231950
  const bodyByKey = /* @__PURE__ */ new Map();
231769
231951
  const walk20 = (d) => {
231770
- for (const e of fs58.readdirSync(d, { withFileTypes: true })) {
231952
+ for (const e of fs59.readdirSync(d, { withFileTypes: true })) {
231771
231953
  if (e.isDirectory()) {
231772
231954
  if (e.name === "_inferred")
231773
231955
  continue;
231774
231956
  walk20(path62.join(d, e.name));
231775
231957
  } else if (e.name.endsWith(".tc")) {
231776
231958
  const abs = path62.join(d, e.name);
231777
- const src = fs58.readFileSync(abs, "utf-8");
231959
+ const src = fs59.readFileSync(abs, "utf-8");
231778
231960
  try {
231779
231961
  const file = parser_ohm_exports.parseTcFile(path62.relative(dir, abs), src);
231780
231962
  for (const key4 of resolver_exports.resolve([file]).index.keys()) {
@@ -231982,7 +232164,7 @@ async function withContracts(repoRoot, options, tracker, fn) {
231982
232164
  try {
231983
232165
  let recorded;
231984
232166
  if (options.contractsDir) {
231985
- if (!fs58.existsSync(options.contractsDir)) {
232167
+ if (!fs59.existsSync(options.contractsDir)) {
231986
232168
  const err = new Error(`Contracts directory not found at ${options.contractsDir}. Run \`truecourse contracts generate\` first.`);
231987
232169
  tracker?.error("load", err.message);
231988
232170
  throw err;
@@ -232071,7 +232253,7 @@ async function verifyInProcess(repoRoot, options = {}) {
232071
232253
  bySeverity: summary.bySeverity
232072
232254
  });
232073
232255
  await deleteVerifyDiff(storeKey);
232074
- fs58.rmSync(legacyVerifyStatePath(repoRoot), { force: true });
232256
+ fs59.rmSync(legacyVerifyStatePath(repoRoot), { force: true });
232075
232257
  }
232076
232258
  const state = {
232077
232259
  verifiedAt,
@@ -232297,7 +232479,7 @@ async function inferDiffInProcess(repoRoot, options = {}) {
232297
232479
  }
232298
232480
  function autodetectCodeDir(repoRoot) {
232299
232481
  const codeSubdir = path62.join(repoRoot, "code");
232300
- if (fs58.existsSync(codeSubdir) && fs58.statSync(codeSubdir).isDirectory()) {
232482
+ if (fs59.existsSync(codeSubdir) && fs59.statSync(codeSubdir).isDirectory()) {
232301
232483
  return codeSubdir;
232302
232484
  }
232303
232485
  return repoRoot;
@@ -232652,10 +232834,10 @@ router.post("/", async (req, res, next) => {
232652
232834
  throw createAppError("Invalid request body: path is required", 400);
232653
232835
  }
232654
232836
  const repoPath = parsed.data.path;
232655
- if (!fs59.existsSync(repoPath)) {
232837
+ if (!fs60.existsSync(repoPath)) {
232656
232838
  throw createAppError(`Path does not exist: ${repoPath}`, 400);
232657
232839
  }
232658
- if (!fs59.statSync(repoPath).isDirectory()) {
232840
+ if (!fs60.statSync(repoPath).isDirectory()) {
232659
232841
  throw createAppError(`Path is not a directory: ${repoPath}`, 400);
232660
232842
  }
232661
232843
  const entry = await registerProject(repoPath);
@@ -232738,8 +232920,8 @@ router.delete("/:id", async (req, res, next) => {
232738
232920
  throw createAppError("Project not found", 404);
232739
232921
  }
232740
232922
  const tcDir = getRepoTruecourseDir(entry.path);
232741
- if (fs59.existsSync(tcDir)) {
232742
- fs59.rmSync(tcDir, { recursive: true, force: true });
232923
+ if (fs60.existsSync(tcDir)) {
232924
+ fs60.rmSync(tcDir, { recursive: true, force: true });
232743
232925
  }
232744
232926
  await unregisterProject(slug2);
232745
232927
  res.status(204).send();
@@ -233448,7 +233630,7 @@ async function enrichFlowWithLLM(repoPath, flowId) {
233448
233630
  // packages/core/dist/services/violation-pipeline.service.js
233449
233631
  init_dist3();
233450
233632
  import { randomUUID as randomUUID26 } from "node:crypto";
233451
- import fs60 from "node:fs";
233633
+ import fs61 from "node:fs";
233452
233634
  import path63 from "node:path";
233453
233635
  init_provider();
233454
233636
 
@@ -233851,7 +234033,7 @@ function findCSharpProjectFiles(repoPath) {
233851
234033
  return;
233852
234034
  let entries;
233853
234035
  try {
233854
- entries = fs60.readdirSync(dir, { withFileTypes: true });
234036
+ entries = fs61.readdirSync(dir, { withFileTypes: true });
233855
234037
  } catch {
233856
234038
  return;
233857
234039
  }
@@ -233987,9 +234169,9 @@ async function runViolationPipeline(input) {
233987
234169
  if (!lang)
233988
234170
  continue;
233989
234171
  const absPath = resolve11 ? path63.resolve(repoPath, filePath) : path63.isAbsolute(filePath) ? filePath : path63.join(repoPath, filePath);
233990
- if (!fs60.existsSync(absPath))
234172
+ if (!fs61.existsSync(absPath))
233991
234173
  continue;
233992
- const content = fs60.readFileSync(absPath, "utf-8");
234174
+ const content = fs61.readFileSync(absPath, "utf-8");
233993
234175
  const lineCount = content.split("\n").length;
233994
234176
  fileContents.set(changedFileSet ? absPath : filePath, { content, lineCount });
233995
234177
  } catch {
@@ -234186,7 +234368,7 @@ async function runViolationPipeline(input) {
234186
234368
  let snippet2 = fileContents.get(fileKey)?.content.split("\n")[v.line - 1];
234187
234369
  if (snippet2 === void 0) {
234188
234370
  try {
234189
- snippet2 = fs60.readFileSync(v.path, "utf-8").split("\n")[v.line - 1];
234371
+ snippet2 = fs61.readFileSync(v.path, "utf-8").split("\n")[v.line - 1];
234190
234372
  } catch {
234191
234373
  snippet2 = "";
234192
234374
  }
@@ -234210,10 +234392,10 @@ async function runViolationPipeline(input) {
234210
234392
  log.info(`[Pipeline] Code scan: ${allCodeViolations.length} violations from ${filesToScan.length} files (${enabledCodeRules.length} det rules, ${enabledLlmCodeRules.length} LLM rules)`);
234211
234393
  if (enabledCodeRules.some((r) => r.key === "bugs/deterministic/invalid-pyproject-toml")) {
234212
234394
  const pyprojectPath = path63.join(repoPath, "pyproject.toml");
234213
- if (fs60.existsSync(pyprojectPath)) {
234395
+ if (fs61.existsSync(pyprojectPath)) {
234214
234396
  try {
234215
234397
  const { checkPyprojectToml: checkPyprojectToml2 } = await Promise.resolve().then(() => (init_dist3(), dist_exports));
234216
- const content = fs60.readFileSync(pyprojectPath, "utf-8");
234398
+ const content = fs61.readFileSync(pyprojectPath, "utf-8");
234217
234399
  const tomlViolations = checkPyprojectToml2(pyprojectPath, content);
234218
234400
  allCodeViolations.push(...tomlViolations);
234219
234401
  } catch {
@@ -236117,7 +236299,7 @@ var analyses_default = router2;
236117
236299
  var import_express3 = __toESM(require_express2(), 1);
236118
236300
 
236119
236301
  // packages/core/dist/config/ui-state.js
236120
- import fs61 from "node:fs";
236302
+ import fs62 from "node:fs";
236121
236303
  var EMPTY_STATE = { positions: {}, collapsed: {} };
236122
236304
  function scopeKey(branch, level) {
236123
236305
  return `${branch || "HEAD"}/${level}`;
@@ -236125,10 +236307,10 @@ function scopeKey(branch, level) {
236125
236307
  var FileUiStateStore = class {
236126
236308
  async readUiState(repoDir) {
236127
236309
  const file = getRepoUiStatePath(repoDir);
236128
- if (!fs61.existsSync(file))
236310
+ if (!fs62.existsSync(file))
236129
236311
  return structuredClone(EMPTY_STATE);
236130
236312
  try {
236131
- const parsed = JSON.parse(fs61.readFileSync(file, "utf-8"));
236313
+ const parsed = JSON.parse(fs62.readFileSync(file, "utf-8"));
236132
236314
  return {
236133
236315
  positions: parsed.positions ?? {},
236134
236316
  collapsed: parsed.collapsed ?? {}
@@ -236139,7 +236321,7 @@ var FileUiStateStore = class {
236139
236321
  }
236140
236322
  async writeUiState(repoDir, state) {
236141
236323
  ensureRepoTruecourseDir(repoDir);
236142
- fs61.writeFileSync(getRepoUiStatePath(repoDir), JSON.stringify(state, null, 2), "utf-8");
236324
+ fs62.writeFileSync(getRepoUiStatePath(repoDir), JSON.stringify(state, null, 2), "utf-8");
236143
236325
  }
236144
236326
  };
236145
236327
  var active11 = new FileUiStateStore();
@@ -237022,7 +237204,7 @@ var graph_default = router3;
237022
237204
 
237023
237205
  // apps/dashboard/server/src/routes/files.ts
237024
237206
  var import_express4 = __toESM(require_express2(), 1);
237025
- import fs62 from "node:fs";
237207
+ import fs63 from "node:fs";
237026
237208
  import path67 from "node:path";
237027
237209
  var router4 = (0, import_express4.Router)();
237028
237210
  router4.get("/:id/files", async (req, res, next) => {
@@ -237058,19 +237240,19 @@ router4.get("/:id/file-content", async (req, res, next) => {
237058
237240
  }
237059
237241
  let content;
237060
237242
  if (ref === "working-tree") {
237061
- if (!fs62.existsSync(resolved)) throw createAppError("File not found", 404);
237062
- const stat = fs62.statSync(resolved);
237243
+ if (!fs63.existsSync(resolved)) throw createAppError("File not found", 404);
237244
+ const stat = fs63.statSync(resolved);
237063
237245
  if (!stat.isFile()) throw createAppError("Path is not a file", 400);
237064
- content = fs62.readFileSync(resolved, "utf-8");
237246
+ content = fs63.readFileSync(resolved, "utf-8");
237065
237247
  } else {
237066
237248
  const git = await getGit(repo.path);
237067
237249
  try {
237068
237250
  content = await git.show([`HEAD:${filePath}`]);
237069
237251
  } catch {
237070
- if (!fs62.existsSync(resolved)) throw createAppError("File not found", 404);
237071
- const stat = fs62.statSync(resolved);
237252
+ if (!fs63.existsSync(resolved)) throw createAppError("File not found", 404);
237253
+ const stat = fs63.statSync(resolved);
237072
237254
  if (!stat.isFile()) throw createAppError("Path is not a file", 400);
237073
- content = fs62.readFileSync(resolved, "utf-8");
237255
+ content = fs63.readFileSync(resolved, "utf-8");
237074
237256
  }
237075
237257
  }
237076
237258
  const ext2 = path67.extname(resolved).slice(1).toLowerCase();
@@ -237573,7 +237755,7 @@ var analytics_default = router9;
237573
237755
 
237574
237756
  // apps/dashboard/server/src/routes/spec.ts
237575
237757
  var import_express10 = __toESM(require_express2(), 1);
237576
- import fs63 from "node:fs";
237758
+ import fs64 from "node:fs";
237577
237759
  import path68 from "node:path";
237578
237760
 
237579
237761
  // packages/core/dist/lib/background-tasks.js
@@ -237979,7 +238161,7 @@ router10.get(
237979
238161
  );
237980
238162
  function mtimeIfExists(file) {
237981
238163
  try {
237982
- return fs63.statSync(file).mtimeMs;
238164
+ return fs64.statSync(file).mtimeMs;
237983
238165
  } catch {
237984
238166
  return null;
237985
238167
  }
@@ -237988,7 +238170,7 @@ function hasPendingDecisions(repoPath) {
237988
238170
  const decisionsMtime = mtimeIfExists(decisionsPath(repoPath));
237989
238171
  if (decisionsMtime === null) return false;
237990
238172
  try {
237991
- const corpus = JSON.parse(fs63.readFileSync(corpusFilePath(repoPath), "utf8"));
238173
+ const corpus = JSON.parse(fs64.readFileSync(corpusFilePath(repoPath), "utf8"));
237992
238174
  const generatedAt = Date.parse(corpus.generatedAt ?? "");
237993
238175
  if (Number.isNaN(generatedAt)) return false;
237994
238176
  return decisionsMtime > generatedAt;
@@ -238607,7 +238789,7 @@ import path71 from "node:path";
238607
238789
  init_dist();
238608
238790
 
238609
238791
  // packages/core/dist/commands/guard-read.js
238610
- import fs64 from "node:fs";
238792
+ import fs65 from "node:fs";
238611
238793
  import path70 from "node:path";
238612
238794
  init_dist();
238613
238795
  function composeDocCoverage(doc, content, sources) {
@@ -238780,7 +238962,7 @@ function headingTextIndex(repoRoot, docs) {
238780
238962
  continue;
238781
238963
  let content;
238782
238964
  try {
238783
- content = fs64.readFileSync(path70.join(repoRoot, doc), "utf-8");
238965
+ content = fs65.readFileSync(path70.join(repoRoot, doc), "utf-8");
238784
238966
  } catch {
238785
238967
  continue;
238786
238968
  }
@@ -238792,15 +238974,27 @@ function headingTextIndex(repoRoot, docs) {
238792
238974
  }
238793
238975
  function readGuardReport(repoRoot) {
238794
238976
  const report4 = readGuardResult(repoRoot);
238795
- if (!report4 || report4.birthFindings.length === 0)
238977
+ if (!report4)
238978
+ return report4;
238979
+ const held = report4.heldSections ?? [];
238980
+ if (report4.birthFindings.length === 0 && held.length === 0)
238796
238981
  return report4;
238797
- const headingByDocAnchor = headingTextIndex(repoRoot, report4.birthFindings.map((f2) => f2.doc));
238982
+ const headingByDocAnchor = headingTextIndex(repoRoot, [
238983
+ ...report4.birthFindings.map((f2) => f2.doc),
238984
+ ...held.map((h) => h.doc)
238985
+ ]);
238798
238986
  return {
238799
238987
  ...report4,
238800
238988
  birthFindings: report4.birthFindings.map((f2) => {
238801
238989
  const headingText = headingByDocAnchor.get(`${f2.doc}\0${f2.anchor}`);
238802
238990
  return { ...f2, ...headingText ? { headingText } : {} };
238803
- })
238991
+ }),
238992
+ ...held.length > 0 ? {
238993
+ heldSections: held.map((h) => {
238994
+ const headingText = headingByDocAnchor.get(`${h.doc}\0${h.anchor}`);
238995
+ return { ...h, ...headingText ? { headingText } : {} };
238996
+ })
238997
+ } : {}
238804
238998
  };
238805
238999
  }
238806
239000
  function readGuardRecipeCard(repoRoot) {
@@ -238826,7 +239020,7 @@ function scenarioFilesById(repoRoot) {
238826
239020
  for (const file of collectYamlFiles(scenariosDir(repoRoot)).sort()) {
238827
239021
  let parsed;
238828
239022
  try {
238829
- parsed = jsYaml.load(fs64.readFileSync(file, "utf-8"));
239023
+ parsed = jsYaml.load(fs65.readFileSync(file, "utf-8"));
238830
239024
  } catch {
238831
239025
  continue;
238832
239026
  }
@@ -238849,7 +239043,7 @@ function readGuardScenarioSource(repoRoot, id) {
238849
239043
  for (const file of collectYamlFiles(scenariosDir(repoRoot))) {
238850
239044
  let raw;
238851
239045
  try {
238852
- raw = fs64.readFileSync(file, "utf-8");
239046
+ raw = fs65.readFileSync(file, "utf-8");
238853
239047
  } catch {
238854
239048
  continue;
238855
239049
  }
@@ -238872,9 +239066,23 @@ function readGuardEvidence(repoRoot, runId, scenarioId, file = "transcript.txt")
238872
239066
  const runDir = path70.resolve(evidenceRunDir(repoRoot, runId));
238873
239067
  if (full !== runDir && !full.startsWith(runDir + path70.sep))
238874
239068
  return null;
238875
- if (!fs64.existsSync(full) || !fs64.statSync(full).isFile())
239069
+ if (!fs65.existsSync(full) || !fs65.statSync(full).isFile())
239070
+ return null;
239071
+ return fs65.readFileSync(full, "utf-8");
239072
+ }
239073
+ function readGuardEvidenceAt(repoRoot, evidenceDir, file = "transcript.txt") {
239074
+ if (!SAFE_SEGMENT.test(file))
239075
+ return null;
239076
+ const evidenceRoot = path70.resolve(guardDir(repoRoot), "evidence");
239077
+ const dir = path70.resolve(repoRoot, evidenceDir);
239078
+ if (dir !== evidenceRoot && !dir.startsWith(evidenceRoot + path70.sep))
239079
+ return null;
239080
+ const full = path70.resolve(dir, file);
239081
+ if (!full.startsWith(dir + path70.sep))
239082
+ return null;
239083
+ if (!fs65.existsSync(full) || !fs65.statSync(full).isFile())
238876
239084
  return null;
238877
- return fs64.readFileSync(full, "utf-8");
239085
+ return fs65.readFileSync(full, "utf-8");
238878
239086
  }
238879
239087
  function computeGuardStaleness(repoRoot) {
238880
239088
  const corpusMtime = mtimeIfExists2(corpusFilePath(repoRoot));
@@ -238900,10 +239108,10 @@ function newestScenarioMtime(repoRoot) {
238900
239108
  return newest;
238901
239109
  }
238902
239110
  function collectYamlFiles(dir) {
238903
- if (!fs64.existsSync(dir))
239111
+ if (!fs65.existsSync(dir))
238904
239112
  return [];
238905
239113
  const out = [];
238906
- for (const entry of fs64.readdirSync(dir, { withFileTypes: true })) {
239114
+ for (const entry of fs65.readdirSync(dir, { withFileTypes: true })) {
238907
239115
  const full = path70.join(dir, entry.name);
238908
239116
  if (entry.isDirectory())
238909
239117
  out.push(...collectYamlFiles(full));
@@ -238914,16 +239122,16 @@ function collectYamlFiles(dir) {
238914
239122
  }
238915
239123
  function mtimeIfExists2(file) {
238916
239124
  try {
238917
- return fs64.statSync(file).mtimeMs;
239125
+ return fs65.statSync(file).mtimeMs;
238918
239126
  } catch {
238919
239127
  return null;
238920
239128
  }
238921
239129
  }
238922
239130
  function readJson(file, map2) {
238923
- if (!fs64.existsSync(file))
239131
+ if (!fs65.existsSync(file))
238924
239132
  return null;
238925
239133
  try {
238926
- return map2(JSON.parse(fs64.readFileSync(file, "utf-8")));
239134
+ return map2(JSON.parse(fs65.readFileSync(file, "utf-8")));
238927
239135
  } catch {
238928
239136
  return null;
238929
239137
  }
@@ -239063,6 +239271,33 @@ router13.get("/:id/guard/evidence", async (req, res, next) => {
239063
239271
  next(e);
239064
239272
  }
239065
239273
  });
239274
+ router13.get("/:id/guard/finding-evidence", async (req, res, next) => {
239275
+ try {
239276
+ const repo = await resolveProjectForRequest(req.params.id);
239277
+ const evidencePath = String(req.query.path ?? "");
239278
+ if (!evidencePath) {
239279
+ res.status(400).json({ error: "Missing ?path=<evidence dir>." });
239280
+ return;
239281
+ }
239282
+ const file = req.query.file ? String(req.query.file) : void 0;
239283
+ const content = readGuardEvidenceAt(repo.path, evidencePath, file);
239284
+ if (content == null) {
239285
+ res.status(404).json({ error: "Evidence not found." });
239286
+ return;
239287
+ }
239288
+ res.type("text/plain").send(content);
239289
+ } catch (e) {
239290
+ next(e);
239291
+ }
239292
+ });
239293
+ router13.get("/:id/guard/decisions", async (req, res, next) => {
239294
+ try {
239295
+ const repo = await resolveProjectForRequest(req.params.id);
239296
+ res.json(readGuardDecisions(repo.path));
239297
+ } catch (e) {
239298
+ next(e);
239299
+ }
239300
+ });
239066
239301
  router13.get("/:id/guard/staleness", async (req, res, next) => {
239067
239302
  try {
239068
239303
  const repo = await resolveProjectForRequest(req.params.id);
@@ -239396,6 +239631,40 @@ router14.post("/:id/guard/run", async (req, res, next) => {
239396
239631
  if (held) guardJobs.delete(repoId);
239397
239632
  }
239398
239633
  });
239634
+ router14.post("/:id/guard/dismiss", async (req, res, next) => {
239635
+ try {
239636
+ const repo = await resolveProjectForRequest(req.params.id);
239637
+ const body = req.body ?? {};
239638
+ if (!body.doc || !body.anchor || !body.title) {
239639
+ res.status(400).json({ error: "dismiss requires { doc, anchor, title }." });
239640
+ return;
239641
+ }
239642
+ const decisions = dismissGuardClaim(repo.path, {
239643
+ doc: body.doc,
239644
+ anchor: body.anchor,
239645
+ title: body.title,
239646
+ dismissedAt: (/* @__PURE__ */ new Date()).toISOString(),
239647
+ ...body.note ? { note: body.note } : {}
239648
+ });
239649
+ res.json(decisions);
239650
+ } catch (e) {
239651
+ next(e);
239652
+ }
239653
+ });
239654
+ router14.post("/:id/guard/undismiss", async (req, res, next) => {
239655
+ try {
239656
+ const repo = await resolveProjectForRequest(req.params.id);
239657
+ const body = req.body ?? {};
239658
+ if (!body.doc || !body.anchor || !body.title) {
239659
+ res.status(400).json({ error: "undismiss requires { doc, anchor, title }." });
239660
+ return;
239661
+ }
239662
+ const decisions = undismissGuardClaim(repo.path, { doc: body.doc, anchor: body.anchor, title: body.title });
239663
+ res.json(decisions);
239664
+ } catch (e) {
239665
+ next(e);
239666
+ }
239667
+ });
239399
239668
  function runFailureMessage(result) {
239400
239669
  switch (result.status) {
239401
239670
  case "no-recipe":
@@ -239573,7 +239842,7 @@ function createApp(opts = {}) {
239573
239842
  app.use(errorHandler);
239574
239843
  if (opts.serveStatic !== false) {
239575
239844
  const staticDir = path72.join(__dirname3, "public");
239576
- if (fs65.existsSync(staticDir)) {
239845
+ if (fs66.existsSync(staticDir)) {
239577
239846
  app.use(import_express16.default.static(staticDir));
239578
239847
  app.get("*", (_req, res) => {
239579
239848
  res.sendFile(path72.join(staticDir, "index.html"));