@codacy/verity-cli 0.34.0-experimental.007b74f → 0.34.0-experimental.37a6dcf

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/bin/verity.js +1016 -888
  3. package/package.json +1 -1
package/bin/verity.js CHANGED
@@ -17104,8 +17104,107 @@ async function applyMomentSelection(moments) {
17104
17104
  }
17105
17105
 
17106
17106
  // src/lib/project-config.ts
17107
+ var import_node_fs6 = require("node:fs");
17108
+ var import_node_path8 = require("node:path");
17109
+
17110
+ // src/lib/repo-controlled.ts
17107
17111
  var import_node_fs5 = require("node:fs");
17108
17112
  var import_node_path7 = require("node:path");
17113
+
17114
+ // src/lib/hardened-git.ts
17115
+ var import_node_child_process5 = require("node:child_process");
17116
+ var HARDENED_CONFIG_ARGS = [
17117
+ "-c",
17118
+ "core.fsmonitor=false",
17119
+ "-c",
17120
+ "core.pager=cat",
17121
+ "-c",
17122
+ "log.showSignature=false"
17123
+ ];
17124
+ var DIFF_READ_FLAGS = ["--no-ext-diff", "--no-textconv"];
17125
+ var DEFAULT_GIT_TIMEOUT_MS = 6e4;
17126
+ var DEFAULT_GIT_MAX_BUFFER = 64 * 1024 * 1024;
17127
+ function hardenedGitEnv(base = process.env) {
17128
+ const env = {};
17129
+ for (const [key, value] of Object.entries(base)) {
17130
+ if (key.startsWith("GIT_")) continue;
17131
+ env[key] = value;
17132
+ }
17133
+ env.GIT_OPTIONAL_LOCKS = "0";
17134
+ env.GIT_TERMINAL_PROMPT = "0";
17135
+ return env;
17136
+ }
17137
+ function hardenedGitArgv(args2) {
17138
+ return [...HARDENED_CONFIG_ARGS, ...args2];
17139
+ }
17140
+ function classifyError(err2) {
17141
+ const e = err2;
17142
+ const stderr = typeof e?.stderr === "string" ? e.stderr : e?.stderr ? e.stderr.toString("utf-8") : "";
17143
+ if (e?.code === "ETIMEDOUT" || e?.killed && e?.signal === "SIGTERM") return { ok: false, error: "timeout", stderr };
17144
+ if (e?.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER") return { ok: false, error: "too_large", stderr };
17145
+ return { ok: false, error: "failed", stderr };
17146
+ }
17147
+ function runGitSync(cwd, args2, opts = {}) {
17148
+ try {
17149
+ const stdout = (0, import_node_child_process5.execFileSync)("git", hardenedGitArgv(args2), {
17150
+ cwd,
17151
+ env: hardenedGitEnv(),
17152
+ encoding: "utf-8",
17153
+ stdio: ["ignore", "pipe", "pipe"],
17154
+ timeout: opts.timeoutMs ?? DEFAULT_GIT_TIMEOUT_MS,
17155
+ maxBuffer: opts.maxBuffer ?? DEFAULT_GIT_MAX_BUFFER
17156
+ });
17157
+ return { ok: true, stdout };
17158
+ } catch (err2) {
17159
+ return classifyError(err2);
17160
+ }
17161
+ }
17162
+ function runGit(cwd, args2, opts = {}) {
17163
+ return new Promise((resolvePromise) => {
17164
+ (0, import_node_child_process5.execFile)(
17165
+ "git",
17166
+ hardenedGitArgv(args2),
17167
+ {
17168
+ cwd,
17169
+ env: hardenedGitEnv(),
17170
+ encoding: "utf-8",
17171
+ timeout: opts.timeoutMs ?? DEFAULT_GIT_TIMEOUT_MS,
17172
+ maxBuffer: opts.maxBuffer ?? DEFAULT_GIT_MAX_BUFFER
17173
+ },
17174
+ (err2, stdout, stderr) => {
17175
+ if (err2) {
17176
+ const e = err2;
17177
+ e.stderr = stderr;
17178
+ resolvePromise(classifyError(e));
17179
+ return;
17180
+ }
17181
+ resolvePromise({ ok: true, stdout });
17182
+ }
17183
+ );
17184
+ });
17185
+ }
17186
+
17187
+ // src/lib/repo-controlled.ts
17188
+ function repoControlled(worktree, rel) {
17189
+ const parts2 = rel.split("/").filter(Boolean);
17190
+ for (let i2 = 1; i2 <= parts2.length; i2++) {
17191
+ let st;
17192
+ try {
17193
+ st = (0, import_node_fs5.lstatSync)((0, import_node_path7.join)(worktree, ...parts2.slice(0, i2)));
17194
+ } catch (err2) {
17195
+ const code = err2?.code;
17196
+ if (code === "ENOENT" || code === "ENOTDIR") return null;
17197
+ return "unverified";
17198
+ }
17199
+ if (st.isSymbolicLink()) return "symlink";
17200
+ if (i2 === parts2.length && !st.isFile()) return "symlink";
17201
+ }
17202
+ const r = runGitSync(worktree, ["ls-files", "-z", "--", rel], { timeoutMs: 5e3 });
17203
+ if (!r.ok) return "unverified";
17204
+ return r.stdout.length > 0 ? "tracked" : null;
17205
+ }
17206
+
17207
+ // src/lib/project-config.ts
17109
17208
  var DEFAULTS = { git_moments: [] };
17110
17209
  function isMoment(value) {
17111
17210
  return value === "commit" || value === "push";
@@ -17115,14 +17214,14 @@ function parseMoments(raw) {
17115
17214
  }
17116
17215
  function readConfigFile(path) {
17117
17216
  try {
17118
- if (!(0, import_node_fs5.existsSync)(path)) return null;
17119
- const raw = JSON.parse((0, import_node_fs5.readFileSync)(path, "utf-8"));
17217
+ if (!(0, import_node_fs6.existsSync)(path)) return null;
17218
+ const raw = JSON.parse((0, import_node_fs6.readFileSync)(path, "utf-8"));
17120
17219
  const moments = Array.isArray(raw.git_moments) ? raw.git_moments.filter(isMoment) : [];
17121
17220
  const source2 = raw.git_moments_source === "user" || raw.git_moments_source === "init" ? raw.git_moments_source : void 0;
17122
17221
  return {
17123
17222
  git_moments: [...new Set(moments)],
17124
17223
  ...source2 ? { git_moments_source: source2 } : {},
17125
- ...raw.formal === "push" ? { formal: "push" } : {}
17224
+ ...raw.formal === "push" || raw.formal === "off" ? { formal: raw.formal } : {}
17126
17225
  };
17127
17226
  } catch {
17128
17227
  return DEFAULTS;
@@ -17133,20 +17232,41 @@ function candidates() {
17133
17232
  const out2 = [{ path: local, source: "local" }];
17134
17233
  const main = mainWorktreeRoot();
17135
17234
  if (main) {
17136
- const inherited = (0, import_node_path7.join)(main, PROJECT_CONFIG_FILE);
17235
+ const inherited = (0, import_node_path8.join)(main, PROJECT_CONFIG_FILE);
17137
17236
  if (inherited !== local) out2.push({ path: inherited, source: "main-worktree" });
17138
17237
  }
17139
17238
  return out2;
17140
17239
  }
17141
- function readProjectConfig() {
17240
+ function formalRefusal(path) {
17241
+ return repoControlled((0, import_node_path8.dirname)((0, import_node_path8.dirname)(path)), PROJECT_CONFIG_FILE);
17242
+ }
17243
+ function readProjectConfigRaw() {
17142
17244
  for (const { path, source: source2 } of candidates()) {
17143
17245
  const cfg = readConfigFile(path);
17144
17246
  if (cfg) return { ...cfg, source: source2, path };
17145
17247
  }
17146
17248
  return { ...DEFAULTS, source: "default" };
17147
17249
  }
17250
+ function readProjectConfig() {
17251
+ const cfg = readProjectConfigRaw();
17252
+ if (cfg.formal !== "push" || !cfg.path) return cfg;
17253
+ const refused2 = formalRefusal(cfg.path);
17254
+ if (!refused2) return cfg;
17255
+ const { formal: _dropped, ...rest } = cfg;
17256
+ return { ...rest, formal_refused: refused2 };
17257
+ }
17258
+ function formalRefusalMessage(reason) {
17259
+ switch (reason) {
17260
+ case "tracked":
17261
+ return ".verity/config.json is tracked in git, so its formal setting is ignored (a repository cannot switch formal verification on) \u2014 untrack it with: git rm --cached .verity/config.json";
17262
+ case "symlink":
17263
+ return ".verity/config.json is reached through a symlink, so its formal setting is ignored";
17264
+ case "unverified":
17265
+ return "could not confirm with git that .verity/config.json is untracked, so its formal setting is ignored";
17266
+ }
17267
+ }
17148
17268
  function writeProjectConfig(patch) {
17149
- const { git_moments, git_moments_source, formal } = readProjectConfig();
17269
+ const { git_moments, git_moments_source, formal } = readProjectConfigRaw();
17150
17270
  const next = {
17151
17271
  git_moments,
17152
17272
  ...git_moments_source ? { git_moments_source } : {},
@@ -17154,8 +17274,8 @@ function writeProjectConfig(patch) {
17154
17274
  ...patch
17155
17275
  };
17156
17276
  const target = projectPath(PROJECT_CONFIG_FILE);
17157
- (0, import_node_fs5.mkdirSync)((0, import_node_path7.dirname)(target), { recursive: true });
17158
- (0, import_node_fs5.writeFileSync)(target, JSON.stringify(next, null, 2) + "\n");
17277
+ (0, import_node_fs6.mkdirSync)((0, import_node_path8.dirname)(target), { recursive: true });
17278
+ (0, import_node_fs6.writeFileSync)(target, JSON.stringify(next, null, 2) + "\n");
17159
17279
  return next;
17160
17280
  }
17161
17281
  function resolveGuardMoments(explicit) {
@@ -17164,11 +17284,11 @@ function resolveGuardMoments(explicit) {
17164
17284
  }
17165
17285
 
17166
17286
  // src/lib/plugin-ownership.ts
17167
- var import_node_fs8 = require("node:fs");
17287
+ var import_node_fs9 = require("node:fs");
17168
17288
 
17169
17289
  // src/lib/which.ts
17170
- var import_node_fs6 = require("node:fs");
17171
- var import_node_path8 = require("node:path");
17290
+ var import_node_fs7 = require("node:fs");
17291
+ var import_node_path9 = require("node:path");
17172
17292
  function executableExtensions(platform4, pathext) {
17173
17293
  if (platform4 !== "win32") return [""];
17174
17294
  const raw = (pathext ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean);
@@ -17186,14 +17306,14 @@ function whichSync(bin, opts = {}) {
17186
17306
  if (!rawPath) return null;
17187
17307
  const exts = executableExtensions(platform4, opts.pathext ?? process.env.PATHEXT);
17188
17308
  const real = opts.real ?? true;
17189
- for (const dir of rawPath.split(import_node_path8.delimiter)) {
17309
+ for (const dir of rawPath.split(import_node_path9.delimiter)) {
17190
17310
  if (!dir) continue;
17191
17311
  for (const ext of exts) {
17192
- const candidate = (0, import_node_path8.join)(dir, bin + ext);
17312
+ const candidate = (0, import_node_path9.join)(dir, bin + ext);
17193
17313
  try {
17194
- if (!(0, import_node_fs6.statSync)(candidate).isFile()) continue;
17195
- if (platform4 !== "win32") (0, import_node_fs6.accessSync)(candidate, import_node_fs6.constants.X_OK);
17196
- return real ? (0, import_node_fs6.realpathSync)(candidate) : candidate;
17314
+ if (!(0, import_node_fs7.statSync)(candidate).isFile()) continue;
17315
+ if (platform4 !== "win32") (0, import_node_fs7.accessSync)(candidate, import_node_fs7.constants.X_OK);
17316
+ return real ? (0, import_node_fs7.realpathSync)(candidate) : candidate;
17197
17317
  } catch {
17198
17318
  continue;
17199
17319
  }
@@ -17204,10 +17324,10 @@ function whichSync(bin, opts = {}) {
17204
17324
 
17205
17325
  // src/lib/plugin-ownership.ts
17206
17326
  var import_node_os2 = require("node:os");
17207
- var import_node_path9 = require("node:path");
17327
+ var import_node_path10 = require("node:path");
17208
17328
 
17209
17329
  // src/lib/stderr-log.ts
17210
- var import_node_fs7 = require("node:fs");
17330
+ var import_node_fs8 = require("node:fs");
17211
17331
  var TOKEN_RE2 = /verity_[0-9a-f]{16,}/g;
17212
17332
  var ANSI_RE = /\u001b\[[0-?]*[ -/]*[@-~]/g;
17213
17333
  function scrub(s) {
@@ -17220,9 +17340,9 @@ function append(text) {
17220
17340
  try {
17221
17341
  const dir = projectPath(DEBUG_LOG_DIR);
17222
17342
  const file = projectPath(STDERR_LOG_FILE);
17223
- (0, import_node_fs7.mkdirSync)(dir, { recursive: true });
17343
+ (0, import_node_fs8.mkdirSync)(dir, { recursive: true });
17224
17344
  rotateIfNeeded(file);
17225
- (0, import_node_fs7.appendFileSync)(file, text);
17345
+ (0, import_node_fs8.appendFileSync)(file, text);
17226
17346
  } catch {
17227
17347
  }
17228
17348
  }
@@ -17270,8 +17390,8 @@ function markerPath() {
17270
17390
  }
17271
17391
  function readMarker() {
17272
17392
  try {
17273
- if (!(0, import_node_fs8.existsSync)(markerPath())) return null;
17274
- const raw = JSON.parse((0, import_node_fs8.readFileSync)(markerPath(), "utf-8"));
17393
+ if (!(0, import_node_fs9.existsSync)(markerPath())) return null;
17394
+ const raw = JSON.parse((0, import_node_fs9.readFileSync)(markerPath(), "utf-8"));
17275
17395
  const pluginRoot = typeof raw.plugin_root === "string" ? raw.plugin_root : "";
17276
17396
  if (!pluginRoot || CONTROL_CHARS2.test(pluginRoot)) return null;
17277
17397
  const version = typeof raw.version === "string" && !CONTROL_CHARS2.test(raw.version) ? raw.version : null;
@@ -17289,23 +17409,23 @@ function recordPluginOwnership(sessionId) {
17289
17409
  const pluginRoot = process.env.VERITY_PLUGIN_ROOT;
17290
17410
  if (!pluginRoot) return;
17291
17411
  try {
17292
- (0, import_node_fs8.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
17412
+ (0, import_node_fs9.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
17293
17413
  const marker = {
17294
17414
  session_id: sessionId,
17295
17415
  plugin_root: pluginRoot,
17296
17416
  version: process.env.VERITY_PLUGIN_VERSION || null,
17297
17417
  ts: Math.floor(Date.now() / 1e3)
17298
17418
  };
17299
- (0, import_node_fs8.writeFileSync)(markerPath(), JSON.stringify(marker));
17419
+ (0, import_node_fs9.writeFileSync)(markerPath(), JSON.stringify(marker));
17300
17420
  } catch {
17301
17421
  }
17302
17422
  }
17303
17423
  function claudeConfigDir() {
17304
- return process.env.CLAUDE_CONFIG_DIR || (0, import_node_path9.join)((0, import_node_os2.homedir)(), ".claude");
17424
+ return process.env.CLAUDE_CONFIG_DIR || (0, import_node_path10.join)((0, import_node_os2.homedir)(), ".claude");
17305
17425
  }
17306
17426
  function readJsonFile(path) {
17307
17427
  try {
17308
- const parsed = JSON.parse((0, import_node_fs8.readFileSync)(path, "utf-8"));
17428
+ const parsed = JSON.parse((0, import_node_fs9.readFileSync)(path, "utf-8"));
17309
17429
  return parsed && typeof parsed === "object" ? parsed : null;
17310
17430
  } catch {
17311
17431
  return null;
@@ -17313,9 +17433,9 @@ function readJsonFile(path) {
17313
17433
  }
17314
17434
  function enabledPluginSetting(key) {
17315
17435
  const files = [
17316
- projectPath((0, import_node_path9.join)(".claude", "settings.local.json")),
17317
- projectPath((0, import_node_path9.join)(".claude", "settings.json")),
17318
- (0, import_node_path9.join)(claudeConfigDir(), "settings.json")
17436
+ projectPath((0, import_node_path10.join)(".claude", "settings.local.json")),
17437
+ projectPath((0, import_node_path10.join)(".claude", "settings.json")),
17438
+ (0, import_node_path10.join)(claudeConfigDir(), "settings.json")
17319
17439
  ];
17320
17440
  for (const file of files) {
17321
17441
  const map = readJsonFile(file)?.enabledPlugins;
@@ -17327,11 +17447,11 @@ function enabledPluginSetting(key) {
17327
17447
  }
17328
17448
  function marketplaceLocations() {
17329
17449
  const out2 = /* @__PURE__ */ new Map();
17330
- const known = readJsonFile((0, import_node_path9.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
17450
+ const known = readJsonFile((0, import_node_path10.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
17331
17451
  if (!known) return out2;
17332
17452
  for (const [name2, entry] of Object.entries(known)) {
17333
17453
  const loc2 = entry?.installLocation;
17334
- if (typeof loc2 === "string" && loc2) out2.set(name2, (0, import_node_path9.resolve)(loc2));
17454
+ if (typeof loc2 === "string" && loc2) out2.set(name2, (0, import_node_path10.resolve)(loc2));
17335
17455
  }
17336
17456
  return out2;
17337
17457
  }
@@ -17345,7 +17465,7 @@ function globalVerityVersion() {
17345
17465
  const entry = verityPathEntry();
17346
17466
  if (!entry) return null;
17347
17467
  try {
17348
- const pkg = readJsonFile((0, import_node_path9.join)((0, import_node_path9.dirname)((0, import_node_fs8.realpathSync)(entry)), "..", "package.json"));
17468
+ const pkg = readJsonFile((0, import_node_path10.join)((0, import_node_path10.dirname)((0, import_node_fs9.realpathSync)(entry)), "..", "package.json"));
17349
17469
  if (pkg?.name !== "@codacy/verity-cli" || typeof pkg.version !== "string") return null;
17350
17470
  return pkg.version;
17351
17471
  } catch {
@@ -17362,7 +17482,7 @@ var VERITY_MARKETPLACE_REPO = "codacy/verity";
17362
17482
  function marketplaceConflict() {
17363
17483
  const wanted = VERITY_MARKETPLACE;
17364
17484
  for (const file of ["settings.json", "settings.local.json"]) {
17365
- const path = (0, import_node_path9.join)(claudeConfigDir(), file);
17485
+ const path = (0, import_node_path10.join)(claudeConfigDir(), file);
17366
17486
  const declared = readJsonFile(path)?.extraKnownMarketplaces ?? null;
17367
17487
  const entry2 = declared && typeof declared === "object" ? declared[wanted] : void 0;
17368
17488
  if (entry2 && typeof entry2 === "object") {
@@ -17372,7 +17492,7 @@ function marketplaceConflict() {
17372
17492
  }
17373
17493
  }
17374
17494
  }
17375
- const known = readJsonFile((0, import_node_path9.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
17495
+ const known = readJsonFile((0, import_node_path10.join)(claudeConfigDir(), "plugins", "known_marketplaces.json"));
17376
17496
  const entry = known?.[wanted];
17377
17497
  if (entry && typeof entry === "object" && !pointsAtVerity(entry.source)) {
17378
17498
  return { name: wanted, declaredAs: describeSource(entry.source) };
@@ -17393,7 +17513,7 @@ function describeSource(src) {
17393
17513
  return target ? `${kind} \u2192 ${target}` : kind;
17394
17514
  }
17395
17515
  function legacyMarketplaceInstall() {
17396
- const plugins = readJsonFile((0, import_node_path9.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
17516
+ const plugins = readJsonFile((0, import_node_path10.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
17397
17517
  if (!plugins || typeof plugins !== "object") return null;
17398
17518
  for (const key of Object.keys(plugins)) {
17399
17519
  const at = key.lastIndexOf("@");
@@ -17405,13 +17525,13 @@ function legacyMarketplaceInstall() {
17405
17525
  }
17406
17526
  function realpathOr(p) {
17407
17527
  try {
17408
- return import_node_fs8.realpathSync.native(p);
17528
+ return import_node_fs9.realpathSync.native(p);
17409
17529
  } catch {
17410
- return (0, import_node_path9.resolve)(p);
17530
+ return (0, import_node_path10.resolve)(p);
17411
17531
  }
17412
17532
  }
17413
17533
  function isWithin(want, dir) {
17414
- return want === dir || want.startsWith(dir + import_node_path9.sep);
17534
+ return want === dir || want.startsWith(dir + import_node_path10.sep);
17415
17535
  }
17416
17536
  function entryAppliesHere(entry, here) {
17417
17537
  const e = entry;
@@ -17421,9 +17541,9 @@ function entryAppliesHere(entry, here) {
17421
17541
  return forProject === here;
17422
17542
  }
17423
17543
  function registrySays(pluginRoot) {
17424
- const plugins = readJsonFile((0, import_node_path9.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
17544
+ const plugins = readJsonFile((0, import_node_path10.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
17425
17545
  if (!plugins || typeof plugins !== "object") return "unverified";
17426
- const want = (0, import_node_path9.resolve)(pluginRoot);
17546
+ const want = (0, import_node_path10.resolve)(pluginRoot);
17427
17547
  const here = realpathOr(repoRoot());
17428
17548
  const markets = marketplaceLocations();
17429
17549
  for (const [key, value] of Object.entries(plugins)) {
@@ -17432,15 +17552,15 @@ function registrySays(pluginRoot) {
17432
17552
  const applicable = (Array.isArray(value) ? value : []).filter((entry) => entryAppliesHere(entry, here));
17433
17553
  const claims = applicable.some((entry) => {
17434
17554
  const installPath = entry?.installPath;
17435
- return typeof installPath === "string" && (0, import_node_path9.resolve)(installPath) === want;
17555
+ return typeof installPath === "string" && (0, import_node_path10.resolve)(installPath) === want;
17436
17556
  }) || source2 !== void 0 && applicable.length > 0 && isWithin(want, source2);
17437
17557
  if (claims) {
17438
17558
  if (enabledPluginSetting(key) === false) return "gone";
17439
- return (0, import_node_fs8.existsSync)(pluginRoot) ? "live" : "gone";
17559
+ return (0, import_node_fs9.existsSync)(pluginRoot) ? "live" : "gone";
17440
17560
  }
17441
17561
  }
17442
- const managed = (0, import_node_path9.resolve)((0, import_node_path9.join)(claudeConfigDir(), "plugins", "cache"));
17443
- return want === managed || want.startsWith(managed + import_node_path9.sep) ? "gone" : "unverified";
17562
+ const managed = (0, import_node_path10.resolve)((0, import_node_path10.join)(claudeConfigDir(), "plugins", "cache"));
17563
+ return want === managed || want.startsWith(managed + import_node_path10.sep) ? "gone" : "unverified";
17444
17564
  }
17445
17565
  var _live = /* @__PURE__ */ new Map();
17446
17566
  function pluginLiveness(pluginRoot) {
@@ -17454,7 +17574,7 @@ function clearStalePluginMarker() {
17454
17574
  const marker = readMarker();
17455
17575
  if (!marker || pluginLiveness(marker.plugin_root) !== "gone") return null;
17456
17576
  try {
17457
- (0, import_node_fs8.rmSync)(markerPath(), { force: true });
17577
+ (0, import_node_fs9.rmSync)(markerPath(), { force: true });
17458
17578
  } catch {
17459
17579
  return null;
17460
17580
  }
@@ -17482,7 +17602,7 @@ function pluginActiveHere() {
17482
17602
  return activePluginInstall() !== null;
17483
17603
  }
17484
17604
  function registeredVerityPlugin() {
17485
- const plugins = readJsonFile((0, import_node_path9.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
17605
+ const plugins = readJsonFile((0, import_node_path10.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
17486
17606
  if (!plugins || typeof plugins !== "object") return null;
17487
17607
  const here = realpathOr(repoRoot());
17488
17608
  for (const [key, value] of Object.entries(plugins)) {
@@ -17492,7 +17612,7 @@ function registeredVerityPlugin() {
17492
17612
  for (const entry of Array.isArray(value) ? value : []) {
17493
17613
  const e = entry;
17494
17614
  const installPath = typeof e.installPath === "string" ? e.installPath : "";
17495
- if (!installPath || !(0, import_node_fs8.existsSync)(installPath)) continue;
17615
+ if (!installPath || !(0, import_node_fs9.existsSync)(installPath)) continue;
17496
17616
  if (!entryAppliesHere(entry, here)) continue;
17497
17617
  return { pluginRoot: installPath, version: typeof e.version === "string" ? e.version : null };
17498
17618
  }
@@ -17544,28 +17664,28 @@ async function resolveHookWiring() {
17544
17664
  }
17545
17665
 
17546
17666
  // src/lib/cli-provenance.ts
17547
- var import_node_fs9 = require("node:fs");
17667
+ var import_node_fs10 = require("node:fs");
17548
17668
  var import_node_os3 = require("node:os");
17549
- var import_node_path10 = require("node:path");
17669
+ var import_node_path11 = require("node:path");
17550
17670
  var CLI_PACKAGE = "@codacy/verity-cli";
17551
- var CLI_ENTRY = (0, import_node_path10.join)("node_modules", CLI_PACKAGE, "bin", "verity.js");
17671
+ var CLI_ENTRY = (0, import_node_path11.join)("node_modules", CLI_PACKAGE, "bin", "verity.js");
17552
17672
  function readJson(path) {
17553
17673
  try {
17554
- const parsed = JSON.parse((0, import_node_fs9.readFileSync)(path, "utf-8"));
17674
+ const parsed = JSON.parse((0, import_node_fs10.readFileSync)(path, "utf-8"));
17555
17675
  return parsed && typeof parsed === "object" ? parsed : null;
17556
17676
  } catch {
17557
17677
  return null;
17558
17678
  }
17559
17679
  }
17560
17680
  function versionUnder(base) {
17561
- const entry = (0, import_node_path10.join)(base, CLI_ENTRY);
17562
- if (!(0, import_node_fs9.existsSync)(entry)) return null;
17563
- const pkg = readJson((0, import_node_path10.join)(base, "node_modules", CLI_PACKAGE, "package.json"));
17681
+ const entry = (0, import_node_path11.join)(base, CLI_ENTRY);
17682
+ if (!(0, import_node_fs10.existsSync)(entry)) return null;
17683
+ const pkg = readJson((0, import_node_path11.join)(base, "node_modules", CLI_PACKAGE, "package.json"));
17564
17684
  return typeof pkg?.version === "string" ? pkg.version : null;
17565
17685
  }
17566
17686
  function versionForEntry(entry) {
17567
17687
  try {
17568
- const pkg = readJson((0, import_node_path10.join)((0, import_node_path10.dirname)((0, import_node_fs9.realpathSync)(entry)), "..", "package.json"));
17688
+ const pkg = readJson((0, import_node_path11.join)((0, import_node_path11.dirname)((0, import_node_fs10.realpathSync)(entry)), "..", "package.json"));
17569
17689
  return typeof pkg?.version === "string" ? pkg.version : null;
17570
17690
  } catch {
17571
17691
  return null;
@@ -17573,16 +17693,16 @@ function versionForEntry(entry) {
17573
17693
  }
17574
17694
  function resolveHooksCli(pluginRoot) {
17575
17695
  const override = process.env.VERITY_CLI_PATH;
17576
- if (override && (0, import_node_fs9.existsSync)(override)) {
17696
+ if (override && (0, import_node_fs10.existsSync)(override)) {
17577
17697
  return { version: versionForEntry(override), rung: "override" };
17578
17698
  }
17579
17699
  const fromPlugin = versionUnder(pluginRoot);
17580
17700
  if (fromPlugin !== null) return { version: fromPlugin, rung: "plugin" };
17581
- if ((0, import_node_fs9.existsSync)((0, import_node_path10.join)(pluginRoot, CLI_ENTRY))) return { version: null, rung: "plugin" };
17582
- const dataDir = process.env.CLAUDE_PLUGIN_DATA || (0, import_node_path10.join)((0, import_node_os3.homedir)(), ".verity", "plugin-cli");
17701
+ if ((0, import_node_fs10.existsSync)((0, import_node_path11.join)(pluginRoot, CLI_ENTRY))) return { version: null, rung: "plugin" };
17702
+ const dataDir = process.env.CLAUDE_PLUGIN_DATA || (0, import_node_path11.join)((0, import_node_os3.homedir)(), ".verity", "plugin-cli");
17583
17703
  const fromData = versionUnder(dataDir);
17584
17704
  if (fromData !== null) return { version: fromData, rung: "plugin-data" };
17585
- if ((0, import_node_fs9.existsSync)((0, import_node_path10.join)(dataDir, CLI_ENTRY))) return { version: null, rung: "plugin-data" };
17705
+ if ((0, import_node_fs10.existsSync)((0, import_node_path11.join)(dataDir, CLI_ENTRY))) return { version: null, rung: "plugin-data" };
17586
17706
  const global = globalVerityVersion();
17587
17707
  if (global !== null) return { version: global, rung: "global" };
17588
17708
  return null;
@@ -17684,7 +17804,7 @@ function pluginCliInvocation() {
17684
17804
  return resolverCommand(root);
17685
17805
  }
17686
17806
  function resolverCommand(root) {
17687
- return `node ${JSON.stringify((0, import_node_path10.join)(root, "scripts", "verity.mjs"))}`;
17807
+ return `node ${JSON.stringify((0, import_node_path11.join)(root, "scripts", "verity.mjs"))}`;
17688
17808
  }
17689
17809
 
17690
17810
  // src/commands/hooks.ts
@@ -17824,8 +17944,8 @@ var import_node_crypto9 = require("node:crypto");
17824
17944
 
17825
17945
  // src/lib/conversation-buffer.ts
17826
17946
  var import_promises5 = require("node:fs/promises");
17827
- var import_node_fs10 = require("node:fs");
17828
- var import_node_child_process5 = require("node:child_process");
17947
+ var import_node_fs11 = require("node:fs");
17948
+ var import_node_child_process6 = require("node:child_process");
17829
17949
  var import_node_crypto = require("node:crypto");
17830
17950
  function stripImageReferences(text) {
17831
17951
  return text.replace(/\[Image #\d+\]/g, "[screenshot \u2014 not available for review]");
@@ -17860,7 +17980,7 @@ async function appendToConversationBuffer(prompt, sessionId) {
17860
17980
  }
17861
17981
  async function readAndClearConversationBuffer(currentSessionId) {
17862
17982
  try {
17863
- if ((0, import_node_fs10.existsSync)(CONVERSATION_BUFFER_FILE)) {
17983
+ if ((0, import_node_fs11.existsSync)(CONVERSATION_BUFFER_FILE)) {
17864
17984
  const entries = await readBufferEntries();
17865
17985
  let mine = entries;
17866
17986
  let others = [];
@@ -17884,7 +18004,7 @@ async function readAndClearConversationBuffer(currentSessionId) {
17884
18004
  };
17885
18005
  }
17886
18006
  }
17887
- if ((0, import_node_fs10.existsSync)(INTENT_FILE)) {
18007
+ if ((0, import_node_fs11.existsSync)(INTENT_FILE)) {
17888
18008
  try {
17889
18009
  const content = await (0, import_promises5.readFile)(INTENT_FILE, "utf-8");
17890
18010
  await (0, import_promises5.unlink)(INTENT_FILE).catch(() => {
@@ -17928,7 +18048,7 @@ async function readBufferEntries() {
17928
18048
  }
17929
18049
  function getRecentCommitMessages() {
17930
18050
  try {
17931
- const output = (0, import_node_child_process5.execSync)(
18051
+ const output = (0, import_node_child_process6.execSync)(
17932
18052
  'git log --since="30 minutes ago" --format="%s" -5',
17933
18053
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
17934
18054
  ).trim();
@@ -18177,9 +18297,9 @@ function isCommandOnlyTurn(input) {
18177
18297
 
18178
18298
  // src/lib/context-identity.ts
18179
18299
  var import_node_crypto2 = require("node:crypto");
18180
- var import_node_fs11 = require("node:fs");
18300
+ var import_node_fs12 = require("node:fs");
18181
18301
  var import_node_os4 = require("node:os");
18182
- var import_node_path11 = require("node:path");
18302
+ var import_node_path12 = require("node:path");
18183
18303
  var SHARED_SENTINELS = /* @__PURE__ */ new Set([
18184
18304
  "",
18185
18305
  "-",
@@ -18217,7 +18337,7 @@ function contextIdentity(input) {
18217
18337
  if (rawTree && !isSharedSentinel(rawTree)) {
18218
18338
  let resolved = rawTree;
18219
18339
  try {
18220
- resolved = import_node_fs11.realpathSync.native(rawTree);
18340
+ resolved = import_node_fs12.realpathSync.native(rawTree);
18221
18341
  } catch {
18222
18342
  }
18223
18343
  treeKey = (0, import_node_crypto2.createHash)("sha256").update(resolved).digest("hex").slice(0, 12);
@@ -18233,13 +18353,13 @@ function contextIdentity(input) {
18233
18353
  }
18234
18354
  function verityHome() {
18235
18355
  const override = process.env.VERITY_HOME;
18236
- return override && override.trim() ? (0, import_node_path11.resolve)(override) : (0, import_node_path11.join)((0, import_node_os4.homedir)(), ".verity");
18356
+ return override && override.trim() ? (0, import_node_path12.resolve)(override) : (0, import_node_path12.join)((0, import_node_os4.homedir)(), ".verity");
18237
18357
  }
18238
18358
  function dossierDir(identity) {
18239
- return (0, import_node_path11.join)(verityHome(), "sessions", identity.userKey, identity.treeKey, identity.sessionKey);
18359
+ return (0, import_node_path12.join)(verityHome(), "sessions", identity.userKey, identity.treeKey, identity.sessionKey);
18240
18360
  }
18241
18361
  function treeDir(identity) {
18242
- return (0, import_node_path11.join)(verityHome(), "sessions", identity.userKey, identity.treeKey);
18362
+ return (0, import_node_path12.join)(verityHome(), "sessions", identity.userKey, identity.treeKey);
18243
18363
  }
18244
18364
  function scopeIdentity(token, sessionId) {
18245
18365
  const t = (token ?? "").trim();
@@ -18254,8 +18374,8 @@ function sessionScopeKey(token, sessionId) {
18254
18374
 
18255
18375
  // src/lib/task-context-buffer.ts
18256
18376
  var import_promises6 = require("node:fs/promises");
18257
- var import_node_fs12 = require("node:fs");
18258
- var import_node_path12 = require("node:path");
18377
+ var import_node_fs13 = require("node:fs");
18378
+ var import_node_path13 = require("node:path");
18259
18379
  var TASK_CONTEXT_DIR = `${VERITY_DIR}/.task-context`;
18260
18380
  var MAX_BUFFER_BYTES = 500 * 1024;
18261
18381
  var MAX_PROMPT_CHARS = 2e3;
@@ -18294,7 +18414,7 @@ async function appendResponseToTaskBuffer(taskId, assistantResponse, actionSumma
18294
18414
  }
18295
18415
  async function readTaskContextBuffer(taskId) {
18296
18416
  const filePath = bufferPath(taskId);
18297
- if (!(0, import_node_fs12.existsSync)(filePath)) return null;
18417
+ if (!(0, import_node_fs13.existsSync)(filePath)) return null;
18298
18418
  try {
18299
18419
  const content = await (0, import_promises6.readFile)(filePath, "utf-8");
18300
18420
  if (!content.trim()) return null;
@@ -18328,12 +18448,12 @@ async function readTaskContextBuffer(taskId) {
18328
18448
  }
18329
18449
  async function cleanupTaskContextBuffers() {
18330
18450
  try {
18331
- if (!(0, import_node_fs12.existsSync)(TASK_CONTEXT_DIR)) return;
18451
+ if (!(0, import_node_fs13.existsSync)(TASK_CONTEXT_DIR)) return;
18332
18452
  const files = await (0, import_promises6.readdir)(TASK_CONTEXT_DIR);
18333
18453
  const cutoffMs = Date.now() - RETENTION_DAYS * 24 * 60 * 60 * 1e3;
18334
18454
  for (const file of files) {
18335
18455
  if (!file.endsWith(".jsonl")) continue;
18336
- const filePath = (0, import_node_path12.join)(TASK_CONTEXT_DIR, file);
18456
+ const filePath = (0, import_node_path13.join)(TASK_CONTEXT_DIR, file);
18337
18457
  try {
18338
18458
  const stats = await (0, import_promises6.stat)(filePath);
18339
18459
  if (stats.mtimeMs < cutoffMs) {
@@ -18347,13 +18467,13 @@ async function cleanupTaskContextBuffers() {
18347
18467
  }
18348
18468
  function bufferPath(taskId) {
18349
18469
  const safe = taskId.replace(/[^a-zA-Z0-9_-]/g, "");
18350
- return (0, import_node_path12.join)(TASK_CONTEXT_DIR, `${safe}.jsonl`);
18470
+ return (0, import_node_path13.join)(TASK_CONTEXT_DIR, `${safe}.jsonl`);
18351
18471
  }
18352
18472
  async function appendEntry(taskId, entry) {
18353
18473
  try {
18354
18474
  await (0, import_promises6.mkdir)(TASK_CONTEXT_DIR, { recursive: true });
18355
18475
  const filePath = bufferPath(taskId);
18356
- if ((0, import_node_fs12.existsSync)(filePath)) {
18476
+ if ((0, import_node_fs13.existsSync)(filePath)) {
18357
18477
  const stats = await (0, import_promises6.stat)(filePath);
18358
18478
  if (stats.size >= MAX_BUFFER_BYTES) {
18359
18479
  const content = await (0, import_promises6.readFile)(filePath, "utf-8");
@@ -18364,7 +18484,7 @@ async function appendEntry(taskId, entry) {
18364
18484
  }
18365
18485
  }
18366
18486
  const line2 = JSON.stringify(entry) + "\n";
18367
- const existing = (0, import_node_fs12.existsSync)(filePath) ? await (0, import_promises6.readFile)(filePath, "utf-8") : "";
18487
+ const existing = (0, import_node_fs13.existsSync)(filePath) ? await (0, import_promises6.readFile)(filePath, "utf-8") : "";
18368
18488
  await (0, import_promises6.writeFile)(filePath, existing + line2);
18369
18489
  } catch {
18370
18490
  }
@@ -18372,20 +18492,20 @@ async function appendEntry(taskId, entry) {
18372
18492
 
18373
18493
  // src/lib/memory-retrieval.ts
18374
18494
  var import_promises8 = require("node:fs/promises");
18375
- var import_node_fs15 = require("node:fs");
18376
- var import_node_path15 = require("node:path");
18495
+ var import_node_fs16 = require("node:fs");
18496
+ var import_node_path16 = require("node:path");
18377
18497
 
18378
18498
  // src/lib/org-mirror.ts
18379
- var import_node_fs13 = require("node:fs");
18499
+ var import_node_fs14 = require("node:fs");
18380
18500
  var import_promises7 = require("node:fs/promises");
18381
- var import_node_path13 = require("node:path");
18501
+ var import_node_path14 = require("node:path");
18382
18502
  var ORG_KINDS = ["decision", "security", "gotcha", "pattern", "domain", "integration"];
18383
18503
  var STATE_FILE = ".org-pull-state.json";
18384
18504
  var BODY_MAX = 8192;
18385
18505
  function orgMirrorDir(remote = requestRemote()) {
18386
18506
  const parsed = parseRemote(remote);
18387
18507
  if (!parsed) return null;
18388
- return (0, import_node_path13.join)(verityHome(), "orgs", parsed.host, parsed.owner.toLowerCase(), "memory");
18508
+ return (0, import_node_path14.join)(verityHome(), "orgs", parsed.host, parsed.owner.toLowerCase(), "memory");
18389
18509
  }
18390
18510
  function slugify(s) {
18391
18511
  return s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
@@ -18451,7 +18571,7 @@ function parseOrgNode(content) {
18451
18571
  }
18452
18572
  async function readState(dir) {
18453
18573
  try {
18454
- const parsed = JSON.parse(await (0, import_promises7.readFile)((0, import_node_path13.join)(dir, STATE_FILE), "utf-8"));
18574
+ const parsed = JSON.parse(await (0, import_promises7.readFile)((0, import_node_path14.join)(dir, STATE_FILE), "utf-8"));
18455
18575
  return {
18456
18576
  version: typeof parsed?.version === "string" ? parsed.version : null,
18457
18577
  organization: parsed?.organization && typeof parsed.organization.id === "string" ? parsed.organization : null,
@@ -18463,7 +18583,7 @@ async function readState(dir) {
18463
18583
  }
18464
18584
  async function writeState(dir, state) {
18465
18585
  await (0, import_promises7.mkdir)(dir, { recursive: true });
18466
- await (0, import_promises7.writeFile)((0, import_node_path13.join)(dir, STATE_FILE), JSON.stringify({
18586
+ await (0, import_promises7.writeFile)((0, import_node_path14.join)(dir, STATE_FILE), JSON.stringify({
18467
18587
  ...state.version ? { version: state.version } : {},
18468
18588
  organization: state.organization,
18469
18589
  pulled_at: (/* @__PURE__ */ new Date()).toISOString(),
@@ -18528,24 +18648,24 @@ async function pullOrgKnowledge(opts) {
18528
18648
  for (const n of nodes) {
18529
18649
  const rel = orgNodePath(n);
18530
18650
  if (written.has(rel)) continue;
18531
- await (0, import_promises7.mkdir)((0, import_node_path13.join)(dir, rel.split("/")[0]), { recursive: true });
18532
- await (0, import_promises7.writeFile)((0, import_node_path13.join)(dir, rel), renderOrgNode(n, org?.name ?? ""));
18651
+ await (0, import_promises7.mkdir)((0, import_node_path14.join)(dir, rel.split("/")[0]), { recursive: true });
18652
+ await (0, import_promises7.writeFile)((0, import_node_path14.join)(dir, rel), renderOrgNode(n, org?.name ?? ""));
18533
18653
  written.add(rel);
18534
18654
  }
18535
18655
  for (const rel of state.files) {
18536
- if (!written.has(rel)) await (0, import_promises7.rm)((0, import_node_path13.join)(dir, rel), { force: true });
18656
+ if (!written.has(rel)) await (0, import_promises7.rm)((0, import_node_path14.join)(dir, rel), { force: true });
18537
18657
  }
18538
- await (0, import_promises7.writeFile)((0, import_node_path13.join)(dir, "index.md"), renderIndex(org?.name ?? "no organization", nodes));
18658
+ await (0, import_promises7.writeFile)((0, import_node_path14.join)(dir, "index.md"), renderIndex(org?.name ?? "no organization", nodes));
18539
18659
  await writeState(dir, { version: org ? page.version : null, organization: org, files: [...written].sort() });
18540
18660
  return { ok: true, status: org ? "pulled" : "none", received: nodes.length, dir };
18541
18661
  }
18542
18662
  async function readOrgMirror(remote = requestRemote()) {
18543
18663
  const dir = orgMirrorDir(remote);
18544
- if (!dir || !(0, import_node_fs13.existsSync)(dir)) return [];
18664
+ if (!dir || !(0, import_node_fs14.existsSync)(dir)) return [];
18545
18665
  const out2 = [];
18546
18666
  for (const kind of ORG_KINDS) {
18547
- const kindDir = (0, import_node_path13.join)(dir, kind);
18548
- if (!(0, import_node_fs13.existsSync)(kindDir)) continue;
18667
+ const kindDir = (0, import_node_path14.join)(dir, kind);
18668
+ if (!(0, import_node_fs14.existsSync)(kindDir)) continue;
18549
18669
  let files;
18550
18670
  try {
18551
18671
  files = await (0, import_promises7.readdir)(kindDir);
@@ -18555,7 +18675,7 @@ async function readOrgMirror(remote = requestRemote()) {
18555
18675
  for (const file of files) {
18556
18676
  if (!file.endsWith(".md")) continue;
18557
18677
  try {
18558
- const node = parseOrgNode(await (0, import_promises7.readFile)((0, import_node_path13.join)(kindDir, file), "utf-8"));
18678
+ const node = parseOrgNode(await (0, import_promises7.readFile)((0, import_node_path14.join)(kindDir, file), "utf-8"));
18559
18679
  if (node) out2.push(node);
18560
18680
  } catch {
18561
18681
  }
@@ -18565,29 +18685,29 @@ async function readOrgMirror(remote = requestRemote()) {
18565
18685
  }
18566
18686
 
18567
18687
  // src/lib/safe-read.ts
18568
- var import_node_fs14 = require("node:fs");
18569
- var import_node_path14 = require("node:path");
18570
- var FLAGS = import_node_fs14.constants;
18688
+ var import_node_fs15 = require("node:fs");
18689
+ var import_node_path15 = require("node:path");
18690
+ var FLAGS = import_node_fs15.constants;
18571
18691
  var NOFOLLOW = FLAGS.O_NOFOLLOW;
18572
18692
  var NONBLOCK = FLAGS.O_NONBLOCK;
18573
18693
  function closeOpened(fd) {
18574
18694
  try {
18575
- (0, import_node_fs14.closeSync)(fd);
18695
+ (0, import_node_fs15.closeSync)(fd);
18576
18696
  } catch {
18577
18697
  }
18578
18698
  }
18579
18699
  function isInsideRoot(realRoot, realPath) {
18580
- return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path14.sep) ? realRoot : realRoot + import_node_path14.sep);
18700
+ return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path15.sep) ? realRoot : realRoot + import_node_path15.sep);
18581
18701
  }
18582
18702
  function sameOpenedFile(opened, current, nofollowAvailable) {
18583
18703
  if (!nofollowAvailable && (opened.ino === 0n || current.ino === 0n)) return false;
18584
18704
  return opened.ino === current.ino && opened.dev === current.dev;
18585
18705
  }
18586
18706
  function openRegularInRoot(root, path) {
18587
- const full = (0, import_node_path14.isAbsolute)(path) ? path : (0, import_node_path14.join)(root, path);
18707
+ const full = (0, import_node_path15.isAbsolute)(path) ? path : (0, import_node_path15.join)(root, path);
18588
18708
  let fd;
18589
18709
  try {
18590
- fd = (0, import_node_fs14.openSync)(full, import_node_fs14.constants.O_RDONLY | (NOFOLLOW ?? 0) | (NONBLOCK ?? 0));
18710
+ fd = (0, import_node_fs15.openSync)(full, import_node_fs15.constants.O_RDONLY | (NOFOLLOW ?? 0) | (NONBLOCK ?? 0));
18591
18711
  } catch (err2) {
18592
18712
  const code = err2.code;
18593
18713
  if (code === "ELOOP" || code === "EMLINK" || code === "EFTYPE") return { ok: false, reason: "symlink" };
@@ -18595,18 +18715,18 @@ function openRegularInRoot(root, path) {
18595
18715
  return { ok: false, reason: "unreadable" };
18596
18716
  }
18597
18717
  try {
18598
- const opened = (0, import_node_fs14.fstatSync)(fd, { bigint: true });
18718
+ const opened = (0, import_node_fs15.fstatSync)(fd, { bigint: true });
18599
18719
  if (!opened.isFile()) {
18600
18720
  closeOpened(fd);
18601
18721
  return { ok: false, reason: "not-regular" };
18602
18722
  }
18603
- const realRoot = import_node_fs14.realpathSync.native(root);
18604
- const realPath = import_node_fs14.realpathSync.native(full);
18723
+ const realRoot = import_node_fs15.realpathSync.native(root);
18724
+ const realPath = import_node_fs15.realpathSync.native(full);
18605
18725
  if (!isInsideRoot(realRoot, realPath)) {
18606
18726
  closeOpened(fd);
18607
18727
  return { ok: false, reason: "outside-root" };
18608
18728
  }
18609
- const current = (0, import_node_fs14.statSync)(realPath, { bigint: true });
18729
+ const current = (0, import_node_fs15.statSync)(realPath, { bigint: true });
18610
18730
  if (!sameOpenedFile(opened, current, NOFOLLOW !== void 0)) {
18611
18731
  closeOpened(fd);
18612
18732
  return { ok: false, reason: NOFOLLOW === void 0 ? "unreadable" : "outside-root" };
@@ -18628,7 +18748,7 @@ function readOpened(fd, size) {
18628
18748
  const buffer = Buffer.alloc(size);
18629
18749
  let offset = 0;
18630
18750
  while (offset < size) {
18631
- const n = (0, import_node_fs14.readSync)(fd, buffer, offset, size - offset, offset);
18751
+ const n = (0, import_node_fs15.readSync)(fd, buffer, offset, size - offset, offset);
18632
18752
  if (n === 0) break;
18633
18753
  offset += n;
18634
18754
  }
@@ -18943,14 +19063,14 @@ function parseFrontmatter(content) {
18943
19063
  return { fm, body: match[2].trim() };
18944
19064
  }
18945
19065
  async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = DEFAULT_BUDGET_TOKENS) {
18946
- const hasRepoGraph = (0, import_node_fs15.existsSync)(memoryDir());
19066
+ const hasRepoGraph = (0, import_node_fs16.existsSync)(memoryDir());
18947
19067
  const budget = Math.min(budgetTokens, MAX_BUDGET_TOKENS);
18948
19068
  const promptTokens = tokenize(promptText);
18949
19069
  const orgPromptTerms = orgTerms(promptText);
18950
19070
  const nodes = [];
18951
19071
  for (const domain of hasRepoGraph ? DOMAINS : []) {
18952
- const domainDir = (0, import_node_path15.join)(memoryDir(), domain);
18953
- if (!(0, import_node_fs15.existsSync)(domainDir)) continue;
19072
+ const domainDir = (0, import_node_path16.join)(memoryDir(), domain);
19073
+ if (!(0, import_node_fs16.existsSync)(domainDir)) continue;
18954
19074
  try {
18955
19075
  const files = await (0, import_promises8.readdir)(domainDir);
18956
19076
  for (const file of files) {
@@ -19024,27 +19144,27 @@ async function retrieveForInjection(promptText, taskFiles = [], budgetTokens = D
19024
19144
  }
19025
19145
 
19026
19146
  // src/lib/injection-record.ts
19027
- var import_node_fs17 = require("node:fs");
19147
+ var import_node_fs18 = require("node:fs");
19028
19148
  var import_node_crypto3 = require("node:crypto");
19029
19149
 
19030
19150
  // src/lib/safe-write.ts
19031
- var import_node_fs16 = require("node:fs");
19032
- var import_node_path16 = require("node:path");
19033
- var FLAGS2 = import_node_fs16.constants;
19151
+ var import_node_fs17 = require("node:fs");
19152
+ var import_node_path17 = require("node:path");
19153
+ var FLAGS2 = import_node_fs17.constants;
19034
19154
  var O_NOFOLLOW = FLAGS2.O_NOFOLLOW ?? 0;
19035
19155
  var NOFOLLOW_AVAILABLE = O_NOFOLLOW !== 0;
19036
19156
  function validateRoot(root) {
19037
19157
  try {
19038
- const parentReal = (0, import_node_fs16.realpathSync)((0, import_node_path16.dirname)(root));
19039
- const expected = (0, import_node_path16.join)(parentReal, (0, import_node_path16.basename)(root));
19158
+ const parentReal = (0, import_node_fs17.realpathSync)((0, import_node_path17.dirname)(root));
19159
+ const expected = (0, import_node_path17.join)(parentReal, (0, import_node_path17.basename)(root));
19040
19160
  try {
19041
- (0, import_node_fs16.mkdirSync)(expected);
19161
+ (0, import_node_fs17.mkdirSync)(expected);
19042
19162
  } catch (e) {
19043
19163
  if (e.code !== "EEXIST") return null;
19044
19164
  }
19045
- const st = (0, import_node_fs16.lstatSync)(expected, { bigint: true });
19165
+ const st = (0, import_node_fs17.lstatSync)(expected, { bigint: true });
19046
19166
  if (st.isSymbolicLink() || !st.isDirectory()) return null;
19047
- if ((0, import_node_fs16.realpathSync)(expected) !== expected) return null;
19167
+ if ((0, import_node_fs17.realpathSync)(expected) !== expected) return null;
19048
19168
  return { real: expected, dev: st.dev, ino: st.ino };
19049
19169
  } catch {
19050
19170
  return null;
@@ -19052,18 +19172,18 @@ function validateRoot(root) {
19052
19172
  }
19053
19173
  function rootUnchanged(root) {
19054
19174
  try {
19055
- const st = (0, import_node_fs16.lstatSync)(root.real, { bigint: true });
19175
+ const st = (0, import_node_fs17.lstatSync)(root.real, { bigint: true });
19056
19176
  return !st.isSymbolicLink() && st.isDirectory() && st.dev === root.dev && st.ino === root.ino;
19057
19177
  } catch {
19058
19178
  return false;
19059
19179
  }
19060
19180
  }
19061
19181
  function bareName(name2) {
19062
- return !!name2 && name2 === (0, import_node_path16.basename)(name2) && name2 !== "." && name2 !== ".." && !name2.includes("\0");
19182
+ return !!name2 && name2 === (0, import_node_path17.basename)(name2) && name2 !== "." && name2 !== ".." && !name2.includes("\0");
19063
19183
  }
19064
19184
  function absentOrRegular(path) {
19065
19185
  try {
19066
- const st = (0, import_node_fs16.lstatSync)(path);
19186
+ const st = (0, import_node_fs17.lstatSync)(path);
19067
19187
  return st.isFile() && !st.isSymbolicLink();
19068
19188
  } catch (e) {
19069
19189
  return e.code === "ENOENT";
@@ -19071,11 +19191,11 @@ function absentOrRegular(path) {
19071
19191
  }
19072
19192
  function verifyOpened(fd, path, root) {
19073
19193
  try {
19074
- const opened = (0, import_node_fs16.fstatSync)(fd, { bigint: true });
19194
+ const opened = (0, import_node_fs17.fstatSync)(fd, { bigint: true });
19075
19195
  if (!opened.isFile() || opened.nlink !== 1n) return false;
19076
- const real = (0, import_node_fs16.realpathSync)(path);
19196
+ const real = (0, import_node_fs17.realpathSync)(path);
19077
19197
  if (!isInsideRoot(root.real, real)) return false;
19078
- const current = (0, import_node_fs16.statSync)(real, { bigint: true });
19198
+ const current = (0, import_node_fs17.statSync)(real, { bigint: true });
19079
19199
  if (!sameOpenedFile(opened, current, NOFOLLOW_AVAILABLE)) return false;
19080
19200
  return rootUnchanged(root);
19081
19201
  } catch {
@@ -19084,21 +19204,21 @@ function verifyOpened(fd, path, root) {
19084
19204
  }
19085
19205
  function removeIfOurs(fd, path) {
19086
19206
  try {
19087
- const opened = (0, import_node_fs16.fstatSync)(fd, { bigint: true });
19088
- const at = (0, import_node_fs16.lstatSync)(path, { bigint: true });
19089
- if (!at.isSymbolicLink() && at.dev === opened.dev && at.ino === opened.ino) (0, import_node_fs16.unlinkSync)(path);
19207
+ const opened = (0, import_node_fs17.fstatSync)(fd, { bigint: true });
19208
+ const at = (0, import_node_fs17.lstatSync)(path, { bigint: true });
19209
+ if (!at.isSymbolicLink() && at.dev === opened.dev && at.ino === opened.ino) (0, import_node_fs17.unlinkSync)(path);
19090
19210
  } catch {
19091
19211
  }
19092
19212
  }
19093
19213
  function openTarget(path, append2) {
19094
- const base = import_node_fs16.constants.O_WRONLY | (append2 ? import_node_fs16.constants.O_APPEND : 0) | O_NOFOLLOW;
19214
+ const base = import_node_fs17.constants.O_WRONLY | (append2 ? import_node_fs17.constants.O_APPEND : 0) | O_NOFOLLOW;
19095
19215
  try {
19096
- return { fd: (0, import_node_fs16.openSync)(path, base), created: false };
19216
+ return { fd: (0, import_node_fs17.openSync)(path, base), created: false };
19097
19217
  } catch (e) {
19098
19218
  if (e.code !== "ENOENT") return null;
19099
19219
  }
19100
19220
  try {
19101
- return { fd: (0, import_node_fs16.openSync)(path, base | import_node_fs16.constants.O_CREAT | import_node_fs16.constants.O_EXCL, 384), created: true };
19221
+ return { fd: (0, import_node_fs17.openSync)(path, base | import_node_fs17.constants.O_CREAT | import_node_fs17.constants.O_EXCL, 384), created: true };
19102
19222
  } catch {
19103
19223
  return null;
19104
19224
  }
@@ -19106,7 +19226,7 @@ function openTarget(path, append2) {
19106
19226
  function writeVerified(root, name2, hooks, append2, write) {
19107
19227
  const r = validateRoot(root);
19108
19228
  if (!r || !bareName(name2)) return false;
19109
- const path = (0, import_node_path16.join)(r.real, name2);
19229
+ const path = (0, import_node_path17.join)(r.real, name2);
19110
19230
  if (!absentOrRegular(path)) return false;
19111
19231
  if (!runHook(hooks)) return false;
19112
19232
  const opened = openTarget(path, append2);
@@ -19122,7 +19242,7 @@ function writeVerified(root, name2, hooks, append2, write) {
19122
19242
  return false;
19123
19243
  } finally {
19124
19244
  try {
19125
- (0, import_node_fs16.closeSync)(opened.fd);
19245
+ (0, import_node_fs17.closeSync)(opened.fd);
19126
19246
  } catch {
19127
19247
  }
19128
19248
  }
@@ -19137,13 +19257,13 @@ function runHook(hooks) {
19137
19257
  }
19138
19258
  function appendInRoot(root, name2, text, hooks = {}) {
19139
19259
  return writeVerified(root, name2, hooks, true, (fd) => {
19140
- (0, import_node_fs16.writeSync)(fd, text);
19260
+ (0, import_node_fs17.writeSync)(fd, text);
19141
19261
  });
19142
19262
  }
19143
19263
  function replaceInRoot(root, name2, text, hooks = {}) {
19144
19264
  return writeVerified(root, name2, hooks, false, (fd) => {
19145
- (0, import_node_fs16.ftruncateSync)(fd, 0);
19146
- (0, import_node_fs16.writeSync)(fd, text, 0);
19265
+ (0, import_node_fs17.ftruncateSync)(fd, 0);
19266
+ (0, import_node_fs17.writeSync)(fd, text, 0);
19147
19267
  });
19148
19268
  }
19149
19269
 
@@ -19191,7 +19311,7 @@ function hashPrompt(prompt) {
19191
19311
  function recordInjection(event) {
19192
19312
  if (!appendInRoot(projectPath(VERITY_DIR), "injections.jsonl", JSON.stringify(event) + "\n")) return;
19193
19313
  try {
19194
- if ((0, import_node_fs17.lstatSync)(recordPath()).size > COMPACT_AT_BYTES) writeEvents(readPendingInjections());
19314
+ if ((0, import_node_fs18.lstatSync)(recordPath()).size > COMPACT_AT_BYTES) writeEvents(readPendingInjections());
19195
19315
  } catch {
19196
19316
  }
19197
19317
  }
@@ -19201,7 +19321,7 @@ function writeEvents(events) {
19201
19321
  function readPendingInjections() {
19202
19322
  try {
19203
19323
  const p = recordPath();
19204
- if (!(0, import_node_fs17.existsSync)(p)) return [];
19324
+ if (!(0, import_node_fs18.existsSync)(p)) return [];
19205
19325
  const read2 = readRegularFileInRoot(projectPath(VERITY_DIR), "injections.jsonl", MAX_RECORD_BYTES);
19206
19326
  if (!read2.ok) return [];
19207
19327
  const out2 = [];
@@ -19221,13 +19341,13 @@ function readPendingInjections() {
19221
19341
 
19222
19342
  // src/lib/memory-sync.ts
19223
19343
  var import_promises9 = require("node:fs/promises");
19224
- var import_node_fs20 = require("node:fs");
19225
- var import_node_path18 = require("node:path");
19344
+ var import_node_fs21 = require("node:fs");
19345
+ var import_node_path19 = require("node:path");
19226
19346
  var import_node_crypto4 = require("node:crypto");
19227
19347
 
19228
19348
  // src/lib/gitignore.ts
19229
- var import_node_child_process6 = require("node:child_process");
19230
- var import_node_fs18 = require("node:fs");
19349
+ var import_node_child_process7 = require("node:child_process");
19350
+ var import_node_fs19 = require("node:fs");
19231
19351
  var VERITY_GITIGNORE_MARKER = "# Verity \u2014 machine-local state.";
19232
19352
  var SETTINGS_LOCAL_IGNORE_ENTRY = ".claude/settings.local.json";
19233
19353
  var VERITY_GITIGNORE_BLOCK = [
@@ -19263,7 +19383,7 @@ var SUPERSEDED_MEMORY_LINES = /* @__PURE__ */ new Set([
19263
19383
  ]);
19264
19384
  function isIgnored(path) {
19265
19385
  try {
19266
- (0, import_node_child_process6.execSync)(`git check-ignore -q -- "${path}"`, { stdio: "pipe" });
19386
+ (0, import_node_child_process7.execSync)(`git check-ignore -q -- "${path}"`, { stdio: "pipe" });
19267
19387
  return true;
19268
19388
  } catch (err2) {
19269
19389
  return err2.status === 1 ? false : null;
@@ -19283,7 +19403,7 @@ function memoryPosture() {
19283
19403
  }
19284
19404
  function committedMemoryFiles() {
19285
19405
  try {
19286
- return (0, import_node_child_process6.execSync)("git ls-files -z -- .verity/memory", {
19406
+ return (0, import_node_child_process7.execSync)("git ls-files -z -- .verity/memory", {
19287
19407
  encoding: "utf-8",
19288
19408
  stdio: ["pipe", "pipe", "pipe"]
19289
19409
  }).split("\0").filter(Boolean);
@@ -19311,7 +19431,7 @@ function fenceMemoryLines(lines) {
19311
19431
  function ensureVerityGitignore() {
19312
19432
  let content = "";
19313
19433
  try {
19314
- content = (0, import_node_fs18.readFileSync)(".gitignore", "utf-8");
19434
+ content = (0, import_node_fs19.readFileSync)(".gitignore", "utf-8");
19315
19435
  } catch {
19316
19436
  }
19317
19437
  const hasMarker = content.includes(VERITY_GITIGNORE_MARKER);
@@ -19338,7 +19458,7 @@ function ensureVerityGitignore() {
19338
19458
  const sep5 = text === "" ? "" : text.endsWith("\n") ? "\n" : "\n\n";
19339
19459
  text = text + sep5 + VERITY_GITIGNORE_BLOCK;
19340
19460
  }
19341
- if (text !== content) (0, import_node_fs18.writeFileSync)(".gitignore", text);
19461
+ if (text !== content) (0, import_node_fs19.writeFileSync)(".gitignore", text);
19342
19462
  return verified(
19343
19463
  memoryIsCommitted ? "memory-tracked" : hasSupersededMemory ? "memory-fenced" : needsRepair ? "repaired" : "added"
19344
19464
  );
@@ -19349,7 +19469,7 @@ function ensureVerityGitignore() {
19349
19469
  function untrackMemory() {
19350
19470
  if (committedMemoryFiles().length === 0) return "none";
19351
19471
  try {
19352
- (0, import_node_child_process6.execSync)("git rm -r --cached --quiet -- .verity/memory", { stdio: "pipe" });
19472
+ (0, import_node_child_process7.execSync)("git rm -r --cached --quiet -- .verity/memory", { stdio: "pipe" });
19353
19473
  return "untracked";
19354
19474
  } catch {
19355
19475
  return "failed";
@@ -19358,7 +19478,7 @@ function untrackMemory() {
19358
19478
  function writeFencedBlock() {
19359
19479
  let content = "";
19360
19480
  try {
19361
- content = (0, import_node_fs18.readFileSync)(".gitignore", "utf-8");
19481
+ content = (0, import_node_fs19.readFileSync)(".gitignore", "utf-8");
19362
19482
  } catch {
19363
19483
  }
19364
19484
  const hasMarker = content.includes(VERITY_GITIGNORE_MARKER);
@@ -19370,7 +19490,7 @@ function writeFencedBlock() {
19370
19490
  text = text + sep5 + VERITY_GITIGNORE_BLOCK;
19371
19491
  }
19372
19492
  try {
19373
- (0, import_node_fs18.writeFileSync)(".gitignore", text);
19493
+ (0, import_node_fs19.writeFileSync)(".gitignore", text);
19374
19494
  return true;
19375
19495
  } catch {
19376
19496
  return false;
@@ -19379,14 +19499,14 @@ function writeFencedBlock() {
19379
19499
  function fenceMemory() {
19380
19500
  let original = null;
19381
19501
  try {
19382
- original = (0, import_node_fs18.readFileSync)(".gitignore", "utf-8");
19502
+ original = (0, import_node_fs19.readFileSync)(".gitignore", "utf-8");
19383
19503
  } catch {
19384
19504
  original = null;
19385
19505
  }
19386
19506
  const restore = () => {
19387
19507
  try {
19388
- if (original === null) (0, import_node_fs18.rmSync)(".gitignore", { force: true });
19389
- else (0, import_node_fs18.writeFileSync)(".gitignore", original);
19508
+ if (original === null) (0, import_node_fs19.rmSync)(".gitignore", { force: true });
19509
+ else (0, import_node_fs19.writeFileSync)(".gitignore", original);
19390
19510
  } catch {
19391
19511
  }
19392
19512
  };
@@ -19404,7 +19524,7 @@ function fenceMemory() {
19404
19524
  }
19405
19525
  function memoryOptOut() {
19406
19526
  try {
19407
- return (0, import_node_fs18.readFileSync)(".gitignore", "utf-8").includes(MEMORY_OPT_OUT_MARKER);
19527
+ return (0, import_node_fs19.readFileSync)(".gitignore", "utf-8").includes(MEMORY_OPT_OUT_MARKER);
19408
19528
  } catch {
19409
19529
  return false;
19410
19530
  }
@@ -19412,13 +19532,13 @@ function memoryOptOut() {
19412
19532
  function keepMemoryTracked() {
19413
19533
  let content = "";
19414
19534
  try {
19415
- content = (0, import_node_fs18.readFileSync)(".gitignore", "utf-8");
19535
+ content = (0, import_node_fs19.readFileSync)(".gitignore", "utf-8");
19416
19536
  } catch {
19417
19537
  }
19418
19538
  if (content.includes(MEMORY_OPT_OUT_MARKER)) return "already";
19419
19539
  try {
19420
19540
  const sep5 = content === "" ? "" : content.endsWith("\n") ? "\n" : "\n\n";
19421
- (0, import_node_fs18.writeFileSync)(".gitignore", content + sep5 + MEMORY_OPT_OUT_STANZA);
19541
+ (0, import_node_fs19.writeFileSync)(".gitignore", content + sep5 + MEMORY_OPT_OUT_STANZA);
19422
19542
  } catch {
19423
19543
  return "failed";
19424
19544
  }
@@ -19427,7 +19547,7 @@ function keepMemoryTracked() {
19427
19547
  function committedVerityState() {
19428
19548
  let out2 = "";
19429
19549
  try {
19430
- out2 = (0, import_node_child_process6.execSync)("git ls-files -z -- .verity", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
19550
+ out2 = (0, import_node_child_process7.execSync)("git ls-files -z -- .verity", { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
19431
19551
  } catch {
19432
19552
  return [];
19433
19553
  }
@@ -19437,12 +19557,12 @@ function untrackVerityState() {
19437
19557
  const tracked = committedVerityState();
19438
19558
  if (tracked.length === 0) return "none";
19439
19559
  try {
19440
- (0, import_node_child_process6.execSync)("git rm -r --cached --quiet -- .verity", { stdio: "pipe" });
19560
+ (0, import_node_child_process7.execSync)("git rm -r --cached --quiet -- .verity", { stdio: "pipe" });
19441
19561
  const keeps = [".verity/standard.yaml"];
19442
19562
  if (memoryPosture() === "committable") keeps.push(".verity/memory");
19443
19563
  for (const keep of keeps) {
19444
19564
  try {
19445
- (0, import_node_child_process6.execSync)(`git add -- "${keep}"`, { stdio: "pipe" });
19565
+ (0, import_node_child_process7.execSync)(`git add -- "${keep}"`, { stdio: "pipe" });
19446
19566
  } catch {
19447
19567
  }
19448
19568
  }
@@ -19453,26 +19573,26 @@ function untrackVerityState() {
19453
19573
  }
19454
19574
 
19455
19575
  // src/lib/safe-path.ts
19456
- var import_node_fs19 = require("node:fs");
19457
- var import_node_path17 = require("node:path");
19576
+ var import_node_fs20 = require("node:fs");
19577
+ var import_node_path18 = require("node:path");
19458
19578
  function resolveInside(baseDir, candidate) {
19459
19579
  if (typeof candidate !== "string" || candidate.length === 0) return null;
19460
- if ((0, import_node_path17.isAbsolute)(candidate)) return null;
19461
- const baseAbs = (0, import_node_path17.resolve)(baseDir);
19462
- const full = (0, import_node_path17.resolve)(baseAbs, candidate);
19463
- const baseSep = baseAbs.endsWith(import_node_path17.sep) ? baseAbs : baseAbs + import_node_path17.sep;
19580
+ if ((0, import_node_path18.isAbsolute)(candidate)) return null;
19581
+ const baseAbs = (0, import_node_path18.resolve)(baseDir);
19582
+ const full = (0, import_node_path18.resolve)(baseAbs, candidate);
19583
+ const baseSep = baseAbs.endsWith(import_node_path18.sep) ? baseAbs : baseAbs + import_node_path18.sep;
19464
19584
  if (full !== baseAbs && !full.startsWith(baseSep)) return null;
19465
19585
  try {
19466
- if ((0, import_node_fs19.existsSync)(baseAbs)) {
19467
- const realBase = (0, import_node_fs19.realpathSync)(baseAbs);
19468
- const realBaseSep = realBase.endsWith(import_node_path17.sep) ? realBase : realBase + import_node_path17.sep;
19586
+ if ((0, import_node_fs20.existsSync)(baseAbs)) {
19587
+ const realBase = (0, import_node_fs20.realpathSync)(baseAbs);
19588
+ const realBaseSep = realBase.endsWith(import_node_path18.sep) ? realBase : realBase + import_node_path18.sep;
19469
19589
  let probe = full;
19470
- while (!(0, import_node_fs19.existsSync)(probe)) {
19471
- const parent = (0, import_node_path17.dirname)(probe);
19590
+ while (!(0, import_node_fs20.existsSync)(probe)) {
19591
+ const parent = (0, import_node_path18.dirname)(probe);
19472
19592
  if (parent === probe) break;
19473
19593
  probe = parent;
19474
19594
  }
19475
- const realProbe = (0, import_node_fs19.realpathSync)(probe);
19595
+ const realProbe = (0, import_node_fs20.realpathSync)(probe);
19476
19596
  if (realProbe !== realBase && !realProbe.startsWith(realBaseSep)) return null;
19477
19597
  }
19478
19598
  } catch {
@@ -19480,37 +19600,37 @@ function resolveInside(baseDir, candidate) {
19480
19600
  }
19481
19601
  return full;
19482
19602
  }
19483
- var O_NOFOLLOW2 = typeof import_node_fs19.constants.O_NOFOLLOW === "number" ? import_node_fs19.constants.O_NOFOLLOW : 0;
19603
+ var O_NOFOLLOW2 = typeof import_node_fs20.constants.O_NOFOLLOW === "number" ? import_node_fs20.constants.O_NOFOLLOW : 0;
19484
19604
  function readFileInside(baseDir, candidate, maxBytes) {
19485
19605
  const full = resolveInside(baseDir, candidate);
19486
19606
  if (!full) return null;
19487
19607
  let realParent;
19488
19608
  let realBase;
19489
19609
  try {
19490
- realParent = (0, import_node_fs19.realpathSync)((0, import_node_path17.dirname)(full));
19491
- realBase = (0, import_node_fs19.realpathSync)((0, import_node_path17.resolve)(baseDir));
19610
+ realParent = (0, import_node_fs20.realpathSync)((0, import_node_path18.dirname)(full));
19611
+ realBase = (0, import_node_fs20.realpathSync)((0, import_node_path18.resolve)(baseDir));
19492
19612
  } catch {
19493
19613
  return null;
19494
19614
  }
19495
- const realBaseSep = realBase.endsWith(import_node_path17.sep) ? realBase : realBase + import_node_path17.sep;
19615
+ const realBaseSep = realBase.endsWith(import_node_path18.sep) ? realBase : realBase + import_node_path18.sep;
19496
19616
  if (realParent !== realBase && !realParent.startsWith(realBaseSep)) return null;
19497
- const target = (0, import_node_path17.join)(realParent, (0, import_node_path17.basename)(full));
19617
+ const target = (0, import_node_path18.join)(realParent, (0, import_node_path18.basename)(full));
19498
19618
  let fd = null;
19499
19619
  try {
19500
- fd = (0, import_node_fs19.openSync)(target, import_node_fs19.constants.O_RDONLY | O_NOFOLLOW2);
19501
- const st = (0, import_node_fs19.fstatSync)(fd);
19620
+ fd = (0, import_node_fs20.openSync)(target, import_node_fs20.constants.O_RDONLY | O_NOFOLLOW2);
19621
+ const st = (0, import_node_fs20.fstatSync)(fd);
19502
19622
  if (!st.isFile()) return null;
19503
19623
  const cap2 = Math.min(maxBytes, st.size);
19504
19624
  if (cap2 <= 0) return "";
19505
19625
  const buf = Buffer.alloc(cap2);
19506
- const bytesRead = (0, import_node_fs19.readSync)(fd, buf, 0, cap2, 0);
19626
+ const bytesRead = (0, import_node_fs20.readSync)(fd, buf, 0, cap2, 0);
19507
19627
  return buf.subarray(0, bytesRead).toString("utf-8");
19508
19628
  } catch {
19509
19629
  return null;
19510
19630
  } finally {
19511
19631
  if (fd !== null) {
19512
19632
  try {
19513
- (0, import_node_fs19.closeSync)(fd);
19633
+ (0, import_node_fs20.closeSync)(fd);
19514
19634
  } catch {
19515
19635
  }
19516
19636
  }
@@ -19593,32 +19713,32 @@ var syncStateFile = () => projectPath(`${VERITY_DIR}/.memory-sync-state.json`);
19593
19713
  async function ensureMemoryDir() {
19594
19714
  await (0, import_promises9.mkdir)(memoryDir2(), { recursive: true });
19595
19715
  for (const domain of DOMAINS2) {
19596
- await (0, import_promises9.mkdir)((0, import_node_path18.join)(memoryDir2(), domain), { recursive: true });
19716
+ await (0, import_promises9.mkdir)((0, import_node_path19.join)(memoryDir2(), domain), { recursive: true });
19597
19717
  }
19598
- if (!(0, import_node_fs20.existsSync)((0, import_node_path18.join)(memoryDir2(), "SCHEMA.md"))) {
19599
- await (0, import_promises9.writeFile)((0, import_node_path18.join)(memoryDir2(), "SCHEMA.md"), SCHEMA_TEMPLATE);
19718
+ if (!(0, import_node_fs21.existsSync)((0, import_node_path19.join)(memoryDir2(), "SCHEMA.md"))) {
19719
+ await (0, import_promises9.writeFile)((0, import_node_path19.join)(memoryDir2(), "SCHEMA.md"), SCHEMA_TEMPLATE);
19600
19720
  }
19601
- if (!(0, import_node_fs20.existsSync)((0, import_node_path18.join)(memoryDir2(), "index.md"))) {
19602
- await (0, import_promises9.writeFile)((0, import_node_path18.join)(memoryDir2(), "index.md"), "# Project Memory Index\n\nNo nodes yet. Run an analysis to start building the knowledge graph.\n");
19721
+ if (!(0, import_node_fs21.existsSync)((0, import_node_path19.join)(memoryDir2(), "index.md"))) {
19722
+ await (0, import_promises9.writeFile)((0, import_node_path19.join)(memoryDir2(), "index.md"), "# Project Memory Index\n\nNo nodes yet. Run an analysis to start building the knowledge graph.\n");
19603
19723
  }
19604
- if (!(0, import_node_fs20.existsSync)((0, import_node_path18.join)(memoryDir2(), "log.md"))) {
19605
- await (0, import_promises9.writeFile)((0, import_node_path18.join)(memoryDir2(), "log.md"), "# Memory Log\n\n");
19724
+ if (!(0, import_node_fs21.existsSync)((0, import_node_path19.join)(memoryDir2(), "log.md"))) {
19725
+ await (0, import_promises9.writeFile)((0, import_node_path19.join)(memoryDir2(), "log.md"), "# Memory Log\n\n");
19606
19726
  }
19607
19727
  }
19608
19728
  async function buildManifest() {
19609
- if (!(0, import_node_fs20.existsSync)(memoryDir2())) {
19729
+ if (!(0, import_node_fs21.existsSync)(memoryDir2())) {
19610
19730
  return { schema_version: 1, nodes: [], index_hash: null, log_length: 0 };
19611
19731
  }
19612
19732
  const nodes = [];
19613
19733
  for (const domain of DOMAINS2) {
19614
- const domainDir = (0, import_node_path18.join)(memoryDir2(), domain);
19615
- if (!(0, import_node_fs20.existsSync)(domainDir)) continue;
19734
+ const domainDir = (0, import_node_path19.join)(memoryDir2(), domain);
19735
+ if (!(0, import_node_fs21.existsSync)(domainDir)) continue;
19616
19736
  try {
19617
19737
  const files = await (0, import_promises9.readdir)(domainDir);
19618
19738
  for (const file of files) {
19619
19739
  if (!file.endsWith(".md")) continue;
19620
19740
  const filePath = `${domain}/${file}`;
19621
- const fullPath = (0, import_node_path18.join)(memoryDir2(), filePath);
19741
+ const fullPath = (0, import_node_path19.join)(memoryDir2(), filePath);
19622
19742
  try {
19623
19743
  const content = await (0, import_promises9.readFile)(fullPath, "utf-8");
19624
19744
  const hash = (0, import_node_crypto4.createHash)("sha256").update(content).digest("hex").slice(0, 16);
@@ -19631,13 +19751,13 @@ async function buildManifest() {
19631
19751
  }
19632
19752
  let indexHash = null;
19633
19753
  try {
19634
- const indexContent = await (0, import_promises9.readFile)((0, import_node_path18.join)(memoryDir2(), "index.md"), "utf-8");
19754
+ const indexContent = await (0, import_promises9.readFile)((0, import_node_path19.join)(memoryDir2(), "index.md"), "utf-8");
19635
19755
  indexHash = `sha256:${(0, import_node_crypto4.createHash)("sha256").update(indexContent).digest("hex").slice(0, 16)}`;
19636
19756
  } catch {
19637
19757
  }
19638
19758
  let logLength = 0;
19639
19759
  try {
19640
- const logContent = await (0, import_promises9.readFile)((0, import_node_path18.join)(memoryDir2(), "log.md"), "utf-8");
19760
+ const logContent = await (0, import_promises9.readFile)((0, import_node_path19.join)(memoryDir2(), "log.md"), "utf-8");
19641
19761
  logLength = logContent.split("\n").length;
19642
19762
  } catch {
19643
19763
  }
@@ -19648,15 +19768,15 @@ function hashContent(content) {
19648
19768
  }
19649
19769
  async function readOnDiskNodes() {
19650
19770
  const out2 = /* @__PURE__ */ new Map();
19651
- if (!(0, import_node_fs20.existsSync)(memoryDir2())) return out2;
19771
+ if (!(0, import_node_fs21.existsSync)(memoryDir2())) return out2;
19652
19772
  for (const domain of DOMAINS2) {
19653
- const domainDir = (0, import_node_path18.join)(memoryDir2(), domain);
19654
- if (!(0, import_node_fs20.existsSync)(domainDir)) continue;
19773
+ const domainDir = (0, import_node_path19.join)(memoryDir2(), domain);
19774
+ if (!(0, import_node_fs21.existsSync)(domainDir)) continue;
19655
19775
  try {
19656
19776
  for (const file of await (0, import_promises9.readdir)(domainDir)) {
19657
19777
  if (!file.endsWith(".md")) continue;
19658
19778
  try {
19659
- out2.set(`${domain}/${file}`, hashContent(await (0, import_promises9.readFile)((0, import_node_path18.join)(domainDir, file), "utf-8")));
19779
+ out2.set(`${domain}/${file}`, hashContent(await (0, import_promises9.readFile)((0, import_node_path19.join)(domainDir, file), "utf-8")));
19660
19780
  } catch {
19661
19781
  }
19662
19782
  }
@@ -19693,7 +19813,7 @@ async function recordSyncedNodePaths() {
19693
19813
  }
19694
19814
  }
19695
19815
  async function writeFileAtomic(path, content) {
19696
- await (0, import_promises9.mkdir)((0, import_node_path18.dirname)(path), { recursive: true });
19816
+ await (0, import_promises9.mkdir)((0, import_node_path19.dirname)(path), { recursive: true });
19697
19817
  const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
19698
19818
  await (0, import_promises9.writeFile)(tmp, content);
19699
19819
  await (0, import_promises9.rename)(tmp, path);
@@ -19707,8 +19827,8 @@ async function computeEditedNodeUploads() {
19707
19827
  const uploads = [];
19708
19828
  for (const [path, prevHash] of prev) {
19709
19829
  if (prevHash == null) continue;
19710
- const full = (0, import_node_path18.join)(memoryDir2(), path);
19711
- if (!(0, import_node_fs20.existsSync)(full)) continue;
19830
+ const full = (0, import_node_path19.join)(memoryDir2(), path);
19831
+ if (!(0, import_node_fs21.existsSync)(full)) continue;
19712
19832
  let content;
19713
19833
  try {
19714
19834
  content = await (0, import_promises9.readFile)(full, "utf-8");
@@ -19752,8 +19872,8 @@ async function applyMemoryWrites(writes, opts = {}) {
19752
19872
  const logLines = [`- ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 16)} \u2014 Applied ${count} write(s) from server`];
19753
19873
  for (const n of notes) logLines.push(` - ${n}`);
19754
19874
  try {
19755
- const existing = (0, import_node_fs20.existsSync)((0, import_node_path18.join)(memoryDir2(), "log.md")) ? await (0, import_promises9.readFile)((0, import_node_path18.join)(memoryDir2(), "log.md"), "utf-8") : "# Memory Log\n\n";
19756
- await (0, import_promises9.writeFile)((0, import_node_path18.join)(memoryDir2(), "log.md"), existing + logLines.join("\n") + "\n");
19875
+ const existing = (0, import_node_fs21.existsSync)((0, import_node_path19.join)(memoryDir2(), "log.md")) ? await (0, import_promises9.readFile)((0, import_node_path19.join)(memoryDir2(), "log.md"), "utf-8") : "# Memory Log\n\n";
19876
+ await (0, import_promises9.writeFile)((0, import_node_path19.join)(memoryDir2(), "log.md"), existing + logLines.join("\n") + "\n");
19757
19877
  } catch {
19758
19878
  }
19759
19879
  if (opts.baseline === "written") await mergeSyncBaseline(synced);
@@ -19763,7 +19883,7 @@ async function applyMemoryWrites(writes, opts = {}) {
19763
19883
  async function mergeSyncBaseline(entries) {
19764
19884
  if (entries.size === 0) return;
19765
19885
  try {
19766
- if ((0, import_node_fs20.existsSync)(syncStateFile())) {
19886
+ if ((0, import_node_fs21.existsSync)(syncStateFile())) {
19767
19887
  try {
19768
19888
  JSON.parse(await (0, import_promises9.readFile)(syncStateFile(), "utf-8"));
19769
19889
  } catch {
@@ -19791,7 +19911,7 @@ async function applyOneWrite(write, treePaths, lastServed) {
19791
19911
  notes.push(`${write.path}: dropped unmatched file_globs [${grounded.dropped.join(", ")}]`);
19792
19912
  }
19793
19913
  }
19794
- if ((0, import_node_fs20.existsSync)(fullPath)) {
19914
+ if ((0, import_node_fs21.existsSync)(fullPath)) {
19795
19915
  let existing = "";
19796
19916
  try {
19797
19917
  existing = await (0, import_promises9.readFile)(fullPath, "utf-8");
@@ -19807,7 +19927,7 @@ async function applyOneWrite(write, treePaths, lastServed) {
19807
19927
  notes.push(`${write.path}: updated from server (untouched here since the server delivered it)`);
19808
19928
  }
19809
19929
  }
19810
- await (0, import_promises9.mkdir)((0, import_node_path18.dirname)(fullPath), { recursive: true });
19930
+ await (0, import_promises9.mkdir)((0, import_node_path19.dirname)(fullPath), { recursive: true });
19811
19931
  await (0, import_promises9.writeFile)(fullPath, content);
19812
19932
  return { written: true, syncedHash: hashContent(content), notes };
19813
19933
  }
@@ -19848,8 +19968,8 @@ async function regenerateIndex() {
19848
19968
  ];
19849
19969
  let totalNodes = 0;
19850
19970
  for (const domain of DOMAINS2.filter((d) => d !== "_archive")) {
19851
- const domainDir = (0, import_node_path18.join)(memoryDir2(), domain);
19852
- if (!(0, import_node_fs20.existsSync)(domainDir)) continue;
19971
+ const domainDir = (0, import_node_path19.join)(memoryDir2(), domain);
19972
+ if (!(0, import_node_fs21.existsSync)(domainDir)) continue;
19853
19973
  try {
19854
19974
  const files = await (0, import_promises9.readdir)(domainDir);
19855
19975
  const mdFiles = files.filter((f) => f.endsWith(".md"));
@@ -19859,7 +19979,7 @@ async function regenerateIndex() {
19859
19979
  for (const file of mdFiles.sort()) {
19860
19980
  const slug = file.replace(/\.md$/, "");
19861
19981
  try {
19862
- const content = await (0, import_promises9.readFile)((0, import_node_path18.join)(domainDir, file), "utf-8");
19982
+ const content = await (0, import_promises9.readFile)((0, import_node_path19.join)(domainDir, file), "utf-8");
19863
19983
  const title = pickFrontmatter(content, "title") ?? slug;
19864
19984
  const kind = pickFrontmatter(content, "kind") ?? "-";
19865
19985
  const confidence = pickFrontmatter(content, "confidence");
@@ -19883,7 +20003,7 @@ async function regenerateIndex() {
19883
20003
  lines.push("No nodes yet. Run an analysis to start building the knowledge graph.");
19884
20004
  }
19885
20005
  const next = lines.join("\n") + "\n";
19886
- const indexPath = (0, import_node_path18.join)(memoryDir2(), "index.md");
20006
+ const indexPath = (0, import_node_path19.join)(memoryDir2(), "index.md");
19887
20007
  let existing = null;
19888
20008
  try {
19889
20009
  existing = await (0, import_promises9.readFile)(indexPath, "utf-8");
@@ -20280,9 +20400,9 @@ function hasLegacyMemoryBlock(text) {
20280
20400
  return findMarker(text, LEGACY_MD_START) !== -1;
20281
20401
  }
20282
20402
  async function ensureClaudeMdPointer(cwd = repoRoot()) {
20283
- const claudeMdPath = (0, import_node_path18.join)(cwd, "CLAUDE.md");
20403
+ const claudeMdPath = (0, import_node_path19.join)(cwd, "CLAUDE.md");
20284
20404
  let existing = "";
20285
- if ((0, import_node_fs20.existsSync)(claudeMdPath)) {
20405
+ if ((0, import_node_fs21.existsSync)(claudeMdPath)) {
20286
20406
  existing = await (0, import_promises9.readFile)(claudeMdPath, "utf-8");
20287
20407
  }
20288
20408
  let startTag = CLAUDE_MD_START;
@@ -20423,9 +20543,9 @@ Body content (\u22648KB). Use [[node-id]] wikilinks for cross-references.
20423
20543
  `;
20424
20544
 
20425
20545
  // src/lib/dossier-session.ts
20426
- var import_node_fs25 = require("node:fs");
20546
+ var import_node_fs26 = require("node:fs");
20427
20547
  var import_node_crypto8 = require("node:crypto");
20428
- var import_node_path21 = require("node:path");
20548
+ var import_node_path22 = require("node:path");
20429
20549
 
20430
20550
  // src/lib/pending-repeat.ts
20431
20551
  var STOP = /* @__PURE__ */ new Set([
@@ -20530,8 +20650,8 @@ function statementAnchorKey(file, patternId) {
20530
20650
 
20531
20651
  // src/lib/dossier/log.ts
20532
20652
  var import_node_crypto5 = require("node:crypto");
20533
- var import_node_fs21 = require("node:fs");
20534
- var import_node_path19 = require("node:path");
20653
+ var import_node_fs22 = require("node:fs");
20654
+ var import_node_path20 = require("node:path");
20535
20655
  var CRC_TABLE = (() => {
20536
20656
  const t = new Int32Array(256);
20537
20657
  for (let i2 = 0; i2 < 256; i2++) {
@@ -20550,13 +20670,13 @@ function crc32(s) {
20550
20670
  function openDossier(identity) {
20551
20671
  try {
20552
20672
  const dir = dossierDir(identity);
20553
- (0, import_node_fs21.mkdirSync)(dir, { recursive: true, mode: 448 });
20673
+ (0, import_node_fs22.mkdirSync)(dir, { recursive: true, mode: 448 });
20554
20674
  return {
20555
20675
  dir,
20556
20676
  identity,
20557
- eventsPath: (0, import_node_path19.join)(dir, "events.jsonl"),
20558
- foldPath: (0, import_node_path19.join)(dir, "fold.json"),
20559
- rotatedDir: (0, import_node_path19.join)(dir, "rotated")
20677
+ eventsPath: (0, import_node_path20.join)(dir, "events.jsonl"),
20678
+ foldPath: (0, import_node_path20.join)(dir, "fold.json"),
20679
+ rotatedDir: (0, import_node_path20.join)(dir, "rotated")
20560
20680
  };
20561
20681
  } catch {
20562
20682
  return null;
@@ -20618,7 +20738,7 @@ function appendEvent(d, ev) {
20618
20738
  at: ev.at ?? (/* @__PURE__ */ new Date()).toISOString(),
20619
20739
  ...ev
20620
20740
  });
20621
- (0, import_node_fs21.appendFileSync)(d.eventsPath, line2, { mode: 384 });
20741
+ (0, import_node_fs22.appendFileSync)(d.eventsPath, line2, { mode: 384 });
20622
20742
  return true;
20623
20743
  } catch {
20624
20744
  return false;
@@ -20626,14 +20746,14 @@ function appendEvent(d, ev) {
20626
20746
  }
20627
20747
  function rotateIfNeeded2(d) {
20628
20748
  try {
20629
- if (!(0, import_node_fs21.existsSync)(d.eventsPath)) return;
20630
- if ((0, import_node_fs21.statSync)(d.eventsPath).size < ROTATE_BYTES) return;
20631
- (0, import_node_fs21.mkdirSync)(d.rotatedDir, { recursive: true, mode: 448 });
20632
- (0, import_node_fs21.renameSync)(d.eventsPath, (0, import_node_path19.join)(d.rotatedDir, `events.${Date.now()}.jsonl`));
20633
- const kept = (0, import_node_fs21.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
20749
+ if (!(0, import_node_fs22.existsSync)(d.eventsPath)) return;
20750
+ if ((0, import_node_fs22.statSync)(d.eventsPath).size < ROTATE_BYTES) return;
20751
+ (0, import_node_fs22.mkdirSync)(d.rotatedDir, { recursive: true, mode: 448 });
20752
+ (0, import_node_fs22.renameSync)(d.eventsPath, (0, import_node_path20.join)(d.rotatedDir, `events.${Date.now()}.jsonl`));
20753
+ const kept = (0, import_node_fs22.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
20634
20754
  for (const stale of kept.slice(0, Math.max(0, kept.length - ROTATE_KEEP))) {
20635
20755
  try {
20636
- (0, import_node_fs21.renameSync)((0, import_node_path19.join)(d.rotatedDir, stale), (0, import_node_path19.join)(d.rotatedDir, `${stale}.pruned`));
20756
+ (0, import_node_fs22.renameSync)((0, import_node_path20.join)(d.rotatedDir, stale), (0, import_node_path20.join)(d.rotatedDir, `${stale}.pruned`));
20637
20757
  } catch {
20638
20758
  }
20639
20759
  }
@@ -20643,8 +20763,8 @@ function rotateIfNeeded2(d) {
20643
20763
 
20644
20764
  // src/lib/dossier/fold-dossier.ts
20645
20765
  var import_node_crypto6 = require("node:crypto");
20646
- var import_node_fs22 = require("node:fs");
20647
- var import_node_path20 = require("node:path");
20766
+ var import_node_fs23 = require("node:fs");
20767
+ var import_node_path21 = require("node:path");
20648
20768
  var EMPTY_CAPABILITIES = () => ({
20649
20769
  human_reachable: { value: "unknown", tier: "unknown" },
20650
20770
  authorship_observability: { value: "unknown", tier: "unknown" },
@@ -20695,12 +20815,12 @@ function foldDossier(d, opts = {}) {
20695
20815
  }
20696
20816
  };
20697
20817
  try {
20698
- if ((0, import_node_fs22.existsSync)(d.rotatedDir)) {
20699
- const files = (0, import_node_fs22.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
20818
+ if ((0, import_node_fs23.existsSync)(d.rotatedDir)) {
20819
+ const files = (0, import_node_fs23.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).sort();
20700
20820
  state.meta.rotations = files.length;
20701
20821
  for (const f of files) {
20702
20822
  try {
20703
- ingest((0, import_node_fs22.readFileSync)((0, import_node_path20.join)(d.rotatedDir, f), "utf8"));
20823
+ ingest((0, import_node_fs23.readFileSync)((0, import_node_path21.join)(d.rotatedDir, f), "utf8"));
20704
20824
  } catch {
20705
20825
  state.meta.dropped_lines++;
20706
20826
  }
@@ -20709,9 +20829,9 @@ function foldDossier(d, opts = {}) {
20709
20829
  } catch {
20710
20830
  }
20711
20831
  try {
20712
- if ((0, import_node_fs22.existsSync)(d.eventsPath)) {
20713
- state.meta.upto_offset = (0, import_node_fs22.statSync)(d.eventsPath).size;
20714
- ingest((0, import_node_fs22.readFileSync)(d.eventsPath, "utf8"));
20832
+ if ((0, import_node_fs23.existsSync)(d.eventsPath)) {
20833
+ state.meta.upto_offset = (0, import_node_fs23.statSync)(d.eventsPath).size;
20834
+ ingest((0, import_node_fs23.readFileSync)(d.eventsPath, "utf8"));
20715
20835
  }
20716
20836
  } catch {
20717
20837
  }
@@ -20982,7 +21102,7 @@ function applyBounds(state, input) {
20982
21102
  }
20983
21103
 
20984
21104
  // src/lib/dossier/cache.ts
20985
- var import_node_fs23 = require("node:fs");
21105
+ var import_node_fs24 = require("node:fs");
20986
21106
  function compactState(s) {
20987
21107
  const ms = (iso) => Date.parse(iso) || 0;
20988
21108
  return {
@@ -21111,20 +21231,20 @@ function encodeState(s) {
21111
21231
  function writeFoldCache(d, state) {
21112
21232
  try {
21113
21233
  const tmp = `${d.foldPath}.${process.pid}.tmp`;
21114
- (0, import_node_fs23.writeFileSync)(tmp, encodeState(state), { mode: 384 });
21115
- (0, import_node_fs23.renameSync)(tmp, d.foldPath);
21234
+ (0, import_node_fs24.writeFileSync)(tmp, encodeState(state), { mode: 384 });
21235
+ (0, import_node_fs24.renameSync)(tmp, d.foldPath);
21116
21236
  } catch {
21117
21237
  }
21118
21238
  }
21119
21239
  function readFoldCache(d) {
21120
21240
  try {
21121
- if (!(0, import_node_fs23.existsSync)(d.foldPath)) return null;
21122
- const raw = JSON.parse((0, import_node_fs23.readFileSync)(d.foldPath, "utf8"));
21241
+ if (!(0, import_node_fs24.existsSync)(d.foldPath)) return null;
21242
+ const raw = JSON.parse((0, import_node_fs24.readFileSync)(d.foldPath, "utf8"));
21123
21243
  if (raw?.v !== 1) return null;
21124
21244
  const cached2 = expandState(raw);
21125
21245
  if (!cached2?.meta) return null;
21126
- const size = (0, import_node_fs23.existsSync)(d.eventsPath) ? (0, import_node_fs23.statSync)(d.eventsPath).size : 0;
21127
- const rotations = (0, import_node_fs23.existsSync)(d.rotatedDir) ? (0, import_node_fs23.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).length : 0;
21246
+ const size = (0, import_node_fs24.existsSync)(d.eventsPath) ? (0, import_node_fs24.statSync)(d.eventsPath).size : 0;
21247
+ const rotations = (0, import_node_fs24.existsSync)(d.rotatedDir) ? (0, import_node_fs24.readdirSync)(d.rotatedDir).filter((f) => f.endsWith(".jsonl")).length : 0;
21128
21248
  if (cached2.meta.upto_offset !== size || cached2.meta.rotations !== rotations) return null;
21129
21249
  return cached2;
21130
21250
  } catch {
@@ -21175,13 +21295,13 @@ function assessContinuity(i2) {
21175
21295
 
21176
21296
  // src/lib/dossier/reanchor.ts
21177
21297
  var import_node_crypto7 = require("node:crypto");
21178
- var import_node_fs24 = require("node:fs");
21298
+ var import_node_fs25 = require("node:fs");
21179
21299
  function lineSha(text) {
21180
21300
  return (0, import_node_crypto7.createHash)("sha256").update(text.trim()).digest("hex").slice(0, HASH_WIDTH);
21181
21301
  }
21182
21302
  function fileHash(path) {
21183
21303
  try {
21184
- return (0, import_node_crypto7.createHash)("sha256").update((0, import_node_fs24.readFileSync)(path)).digest("hex").slice(0, HASH_WIDTH);
21304
+ return (0, import_node_crypto7.createHash)("sha256").update((0, import_node_fs25.readFileSync)(path)).digest("hex").slice(0, HASH_WIDTH);
21185
21305
  } catch {
21186
21306
  return null;
21187
21307
  }
@@ -21553,20 +21673,20 @@ function foreignAuthoredPaths(identity, opts = {}) {
21553
21673
  let sessions = 0;
21554
21674
  try {
21555
21675
  const dir = treeDir(identity);
21556
- if (!(0, import_node_fs25.existsSync)(dir)) return { paths: [], sessions: 0 };
21557
- for (const entry of (0, import_node_fs25.readdirSync)(dir, { withFileTypes: true })) {
21676
+ if (!(0, import_node_fs26.existsSync)(dir)) return { paths: [], sessions: 0 };
21677
+ for (const entry of (0, import_node_fs26.readdirSync)(dir, { withFileTypes: true })) {
21558
21678
  if (!entry.isDirectory()) continue;
21559
21679
  if (entry.name === identity.sessionKey) continue;
21560
- const log = (0, import_node_path21.join)(dir, entry.name, "events.jsonl");
21680
+ const log = (0, import_node_path22.join)(dir, entry.name, "events.jsonl");
21561
21681
  try {
21562
- if (!(0, import_node_fs25.existsSync)(log)) continue;
21563
- if (now - (0, import_node_fs25.statSync)(log).mtimeMs > windowMs) continue;
21682
+ if (!(0, import_node_fs26.existsSync)(log)) continue;
21683
+ if (now - (0, import_node_fs26.statSync)(log).mtimeMs > windowMs) continue;
21564
21684
  const sib = {
21565
- dir: (0, import_node_path21.join)(dir, entry.name),
21685
+ dir: (0, import_node_path22.join)(dir, entry.name),
21566
21686
  identity,
21567
21687
  eventsPath: log,
21568
- foldPath: (0, import_node_path21.join)(dir, entry.name, "fold.json"),
21569
- rotatedDir: (0, import_node_path21.join)(dir, entry.name, "rotated")
21688
+ foldPath: (0, import_node_path22.join)(dir, entry.name, "fold.json"),
21689
+ rotatedDir: (0, import_node_path22.join)(dir, entry.name, "rotated")
21570
21690
  };
21571
21691
  const state = readFoldCache(sib) ?? foldDossier(sib);
21572
21692
  sessions++;
@@ -21594,25 +21714,25 @@ function pruneOldDossiers(identity, maxAgeMs = 7 * 24 * 60 * 60 * 1e3) {
21594
21714
  let removed = 0;
21595
21715
  try {
21596
21716
  const mine = dossierDir(identity);
21597
- const userDir = (0, import_node_path21.dirname)((0, import_node_path21.dirname)(mine));
21598
- if (!(0, import_node_fs25.existsSync)(userDir)) return 0;
21717
+ const userDir = (0, import_node_path22.dirname)((0, import_node_path22.dirname)(mine));
21718
+ if (!(0, import_node_fs26.existsSync)(userDir)) return 0;
21599
21719
  const cutoff = Date.now() - maxAgeMs;
21600
- for (const tree of (0, import_node_fs25.readdirSync)(userDir, { withFileTypes: true })) {
21720
+ for (const tree of (0, import_node_fs26.readdirSync)(userDir, { withFileTypes: true })) {
21601
21721
  if (!tree.isDirectory()) continue;
21602
- const treePath = (0, import_node_path21.join)(userDir, tree.name);
21722
+ const treePath = (0, import_node_path22.join)(userDir, tree.name);
21603
21723
  let live = 0;
21604
- for (const entry of (0, import_node_fs25.readdirSync)(treePath, { withFileTypes: true })) {
21724
+ for (const entry of (0, import_node_fs26.readdirSync)(treePath, { withFileTypes: true })) {
21605
21725
  if (!entry.isDirectory()) continue;
21606
- const dir = (0, import_node_path21.join)(treePath, entry.name);
21726
+ const dir = (0, import_node_path22.join)(treePath, entry.name);
21607
21727
  if (dir === mine) {
21608
21728
  live++;
21609
21729
  continue;
21610
21730
  }
21611
21731
  try {
21612
- const log = (0, import_node_path21.join)(dir, "events.jsonl");
21613
- const at = (0, import_node_fs25.existsSync)(log) ? (0, import_node_fs25.statSync)(log).mtimeMs : (0, import_node_fs25.statSync)(dir).mtimeMs;
21732
+ const log = (0, import_node_path22.join)(dir, "events.jsonl");
21733
+ const at = (0, import_node_fs26.existsSync)(log) ? (0, import_node_fs26.statSync)(log).mtimeMs : (0, import_node_fs26.statSync)(dir).mtimeMs;
21614
21734
  if (at < cutoff) {
21615
- (0, import_node_fs25.rmSync)(dir, { recursive: true, force: true });
21735
+ (0, import_node_fs26.rmSync)(dir, { recursive: true, force: true });
21616
21736
  removed++;
21617
21737
  } else {
21618
21738
  live++;
@@ -21622,7 +21742,7 @@ function pruneOldDossiers(identity, maxAgeMs = 7 * 24 * 60 * 60 * 1e3) {
21622
21742
  }
21623
21743
  if (live === 0) {
21624
21744
  try {
21625
- (0, import_node_fs25.rmSync)(treePath, { recursive: false, force: false });
21745
+ (0, import_node_fs26.rmSync)(treePath, { recursive: false, force: false });
21626
21746
  } catch {
21627
21747
  }
21628
21748
  }
@@ -21639,8 +21759,8 @@ function sessionDossier(token, sessionId) {
21639
21759
  }
21640
21760
  function hasActiveGoal(d) {
21641
21761
  try {
21642
- if (!(0, import_node_fs25.existsSync)(d.eventsPath)) return false;
21643
- return (0, import_node_fs25.readFileSync)(d.eventsPath, "utf8").includes('"k":"goal"');
21762
+ if (!(0, import_node_fs26.existsSync)(d.eventsPath)) return false;
21763
+ return (0, import_node_fs26.readFileSync)(d.eventsPath, "utf8").includes('"k":"goal"');
21644
21764
  } catch {
21645
21765
  return false;
21646
21766
  }
@@ -21664,7 +21784,7 @@ function recordTurn(d, t) {
21664
21784
  for (const a of t.authored) {
21665
21785
  const origin = a.owner === "subagent" ? "subagent" : "edit_tool";
21666
21786
  const prior = t.known?.authored?.get(a.p);
21667
- const hash = fileHash((0, import_node_path21.join)(root, a.p));
21787
+ const hash = fileHash((0, import_node_path22.join)(root, a.p));
21668
21788
  const hunks = Math.max(0, a.h - (prior?.hunks ?? 0));
21669
21789
  const adds = Math.max(0, a.a - (prior?.adds ?? 0));
21670
21790
  const dels = Math.max(0, a.d - (prior?.dels ?? 0));
@@ -21697,7 +21817,7 @@ function recordTurn(d, t) {
21697
21817
  }
21698
21818
  const seenDivergence = t.known?.divergence ?? /* @__PURE__ */ new Set();
21699
21819
  for (const u of t.unobserved) {
21700
- const hash = fileHash((0, import_node_path21.join)(root, u.p));
21820
+ const hash = fileHash((0, import_node_path22.join)(root, u.p));
21701
21821
  if (seenDivergence.has(divergenceKey(u.p, hash))) continue;
21702
21822
  appendEvent(d, { k: "divergence", kind: "external_mutation", path: u.p, hash });
21703
21823
  }
@@ -21732,8 +21852,8 @@ function recordVerdict(d, v) {
21732
21852
  if (!sent.has(f.file)) continue;
21733
21853
  if (!lines.has(f.file)) {
21734
21854
  try {
21735
- const abs = (0, import_node_path21.join)(root, f.file);
21736
- lines.set(f.file, (0, import_node_fs25.existsSync)(abs) ? (0, import_node_fs25.readFileSync)(abs, "utf8").split("\n") : null);
21855
+ const abs = (0, import_node_path22.join)(root, f.file);
21856
+ lines.set(f.file, (0, import_node_fs26.existsSync)(abs) ? (0, import_node_fs26.readFileSync)(abs, "utf8").split("\n") : null);
21737
21857
  } catch {
21738
21858
  lines.set(f.file, null);
21739
21859
  }
@@ -21833,8 +21953,8 @@ function recallMemory(d, identity, opts) {
21833
21953
  budgetBytes: opts.budgetBytes,
21834
21954
  readFileLines: (file) => {
21835
21955
  try {
21836
- const abs = (0, import_node_path21.join)(root, file);
21837
- return (0, import_node_fs25.existsSync)(abs) ? (0, import_node_fs25.readFileSync)(abs, "utf8").split("\n") : null;
21956
+ const abs = (0, import_node_path22.join)(root, file);
21957
+ return (0, import_node_fs26.existsSync)(abs) ? (0, import_node_fs26.readFileSync)(abs, "utf8").split("\n") : null;
21838
21958
  } catch {
21839
21959
  return null;
21840
21960
  }
@@ -22002,21 +22122,21 @@ async function fireClassify(prompt, sessionId, globals) {
22002
22122
  }
22003
22123
 
22004
22124
  // src/commands/lifecycle.ts
22005
- var import_node_fs28 = require("node:fs");
22006
- var import_node_path25 = require("node:path");
22125
+ var import_node_fs29 = require("node:fs");
22126
+ var import_node_path26 = require("node:path");
22007
22127
 
22008
22128
  // src/lib/baseline.ts
22009
- var import_node_fs27 = require("node:fs");
22010
- var import_node_path24 = require("node:path");
22129
+ var import_node_fs28 = require("node:fs");
22130
+ var import_node_path25 = require("node:path");
22011
22131
  var import_node_crypto10 = require("node:crypto");
22012
22132
 
22013
22133
  // src/lib/snapshot.ts
22014
- var import_node_fs26 = require("node:fs");
22015
- var import_node_path23 = require("node:path");
22016
- var import_node_child_process7 = require("node:child_process");
22134
+ var import_node_fs27 = require("node:fs");
22135
+ var import_node_path24 = require("node:path");
22136
+ var import_node_child_process8 = require("node:child_process");
22017
22137
 
22018
22138
  // src/lib/files.ts
22019
- var import_node_path22 = require("node:path");
22139
+ var import_node_path23 = require("node:path");
22020
22140
  var LANG_MAP = {
22021
22141
  // Analyzable (static analysis + Gemini)
22022
22142
  ts: "typescript",
@@ -22084,7 +22204,7 @@ var LANG_MAP = {
22084
22204
  mk: "make"
22085
22205
  };
22086
22206
  function detectLanguage(filepath) {
22087
- const ext = (0, import_node_path22.extname)(filepath).slice(1);
22207
+ const ext = (0, import_node_path23.extname)(filepath).slice(1);
22088
22208
  return LANG_MAP[ext] ?? ext;
22089
22209
  }
22090
22210
  function sortByMtime(files) {
@@ -22175,16 +22295,16 @@ function collectCodeDelta(files, opts) {
22175
22295
 
22176
22296
  // src/lib/snapshot.ts
22177
22297
  function generateSnapshotDiffs(files) {
22178
- if (!(0, import_node_fs26.existsSync)(SNAPSHOT_DIR)) {
22298
+ if (!(0, import_node_fs27.existsSync)(SNAPSHOT_DIR)) {
22179
22299
  return { diffs: [], has_snapshots: false };
22180
22300
  }
22181
22301
  const diffs = [];
22182
22302
  for (const file of files) {
22183
22303
  if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
22184
- const snapshotPath = (0, import_node_path23.join)(SNAPSHOT_DIR, file.path);
22304
+ const snapshotPath = (0, import_node_path24.join)(SNAPSHOT_DIR, file.path);
22185
22305
  const language = file.language ?? detectLanguage(file.path);
22186
- if ((0, import_node_fs26.existsSync)(snapshotPath)) {
22187
- const oldContent = (0, import_node_fs26.readFileSync)(snapshotPath, "utf-8");
22306
+ if ((0, import_node_fs27.existsSync)(snapshotPath)) {
22307
+ const oldContent = (0, import_node_fs27.readFileSync)(snapshotPath, "utf-8");
22188
22308
  if (oldContent === file.content) continue;
22189
22309
  const diff = computeDiff(oldContent, file.content, file.path);
22190
22310
  if (diff) {
@@ -22209,21 +22329,21 @@ function saveSnapshots(files) {
22209
22329
  const snapshotPaths = /* @__PURE__ */ new Set();
22210
22330
  for (const file of files) {
22211
22331
  if (!resolveInside(SNAPSHOT_DIR, file.path)) continue;
22212
- const snapshotPath = (0, import_node_path23.join)(SNAPSHOT_DIR, file.path);
22332
+ const snapshotPath = (0, import_node_path24.join)(SNAPSHOT_DIR, file.path);
22213
22333
  snapshotPaths.add(snapshotPath);
22214
- (0, import_node_fs26.mkdirSync)((0, import_node_path23.dirname)(snapshotPath), { recursive: true });
22215
- (0, import_node_fs26.writeFileSync)(snapshotPath, file.content);
22334
+ (0, import_node_fs27.mkdirSync)((0, import_node_path24.dirname)(snapshotPath), { recursive: true });
22335
+ (0, import_node_fs27.writeFileSync)(snapshotPath, file.content);
22216
22336
  }
22217
22337
  cleanStaleSnapshots(SNAPSHOT_DIR, snapshotPaths);
22218
22338
  }
22219
22339
  function computeDiff(oldContent, newContent, filePath) {
22220
- const tmpOld = (0, import_node_path23.join)(SNAPSHOT_DIR, ".diff-old.tmp");
22221
- const tmpNew = (0, import_node_path23.join)(SNAPSHOT_DIR, ".diff-new.tmp");
22340
+ const tmpOld = (0, import_node_path24.join)(SNAPSHOT_DIR, ".diff-old.tmp");
22341
+ const tmpNew = (0, import_node_path24.join)(SNAPSHOT_DIR, ".diff-new.tmp");
22222
22342
  try {
22223
- (0, import_node_fs26.mkdirSync)(SNAPSHOT_DIR, { recursive: true });
22224
- (0, import_node_fs26.writeFileSync)(tmpOld, oldContent);
22225
- (0, import_node_fs26.writeFileSync)(tmpNew, newContent);
22226
- const result = (0, import_node_child_process7.execSync)(
22343
+ (0, import_node_fs27.mkdirSync)(SNAPSHOT_DIR, { recursive: true });
22344
+ (0, import_node_fs27.writeFileSync)(tmpOld, oldContent);
22345
+ (0, import_node_fs27.writeFileSync)(tmpNew, newContent);
22346
+ const result = (0, import_node_child_process8.execSync)(
22227
22347
  `git diff --no-index --unified=10 -- "${tmpOld}" "${tmpNew}"`,
22228
22348
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
22229
22349
  );
@@ -22236,32 +22356,32 @@ function computeDiff(oldContent, newContent, filePath) {
22236
22356
  return null;
22237
22357
  } finally {
22238
22358
  try {
22239
- (0, import_node_fs26.unlinkSync)(tmpOld);
22359
+ (0, import_node_fs27.unlinkSync)(tmpOld);
22240
22360
  } catch {
22241
22361
  }
22242
22362
  try {
22243
- (0, import_node_fs26.unlinkSync)(tmpNew);
22363
+ (0, import_node_fs27.unlinkSync)(tmpNew);
22244
22364
  } catch {
22245
22365
  }
22246
22366
  }
22247
22367
  }
22248
22368
  function cleanStaleSnapshots(dir, keepSet) {
22249
- if (!(0, import_node_fs26.existsSync)(dir)) return;
22369
+ if (!(0, import_node_fs27.existsSync)(dir)) return;
22250
22370
  try {
22251
- const entries = (0, import_node_fs26.readdirSync)(dir, { withFileTypes: true });
22371
+ const entries = (0, import_node_fs27.readdirSync)(dir, { withFileTypes: true });
22252
22372
  for (const entry of entries) {
22253
22373
  if (dir === SNAPSHOT_DIR && (entry.name === ".diff-old.tmp" || entry.name === ".diff-new.tmp")) continue;
22254
- const fullPath = (0, import_node_path23.join)(dir, entry.name);
22374
+ const fullPath = (0, import_node_path24.join)(dir, entry.name);
22255
22375
  if (entry.isDirectory()) {
22256
22376
  cleanStaleSnapshots(fullPath, keepSet);
22257
22377
  try {
22258
- const remaining = (0, import_node_fs26.readdirSync)(fullPath);
22259
- if (remaining.length === 0) (0, import_node_fs26.rmdirSync)(fullPath);
22378
+ const remaining = (0, import_node_fs27.readdirSync)(fullPath);
22379
+ if (remaining.length === 0) (0, import_node_fs27.rmdirSync)(fullPath);
22260
22380
  } catch {
22261
22381
  }
22262
22382
  } else if (!keepSet.has(fullPath)) {
22263
22383
  try {
22264
- (0, import_node_fs26.unlinkSync)(fullPath);
22384
+ (0, import_node_fs27.unlinkSync)(fullPath);
22265
22385
  } catch {
22266
22386
  }
22267
22387
  }
@@ -22280,20 +22400,20 @@ function sessionKey(sessionId) {
22280
22400
  return (0, import_node_crypto10.createHash)("sha256").update(sessionId).digest("hex").slice(0, 16);
22281
22401
  }
22282
22402
  function sessionDir(key) {
22283
- return (0, import_node_path24.join)(projectPath(BASELINE_DIR), key);
22403
+ return (0, import_node_path25.join)(projectPath(BASELINE_DIR), key);
22284
22404
  }
22285
22405
  function manifestPath(dir) {
22286
- return (0, import_node_path24.join)(dir, "manifest.json");
22406
+ return (0, import_node_path25.join)(dir, "manifest.json");
22287
22407
  }
22288
22408
  function mirrorPath(dir, repoRelPath) {
22289
- return (0, import_node_path24.join)(dir, "files", repoRelPath);
22409
+ return (0, import_node_path25.join)(dir, "files", repoRelPath);
22290
22410
  }
22291
22411
  var CARRY_FILE = `${BASELINE_DIR}/.carry`;
22292
22412
  var CARRY_WINDOW_MS = 12e4;
22293
22413
  function writeCarry(sessionId, headSha) {
22294
22414
  try {
22295
- (0, import_node_fs27.mkdirSync)(projectPath(BASELINE_DIR), { recursive: true });
22296
- (0, import_node_fs27.writeFileSync)(
22415
+ (0, import_node_fs28.mkdirSync)(projectPath(BASELINE_DIR), { recursive: true });
22416
+ (0, import_node_fs28.writeFileSync)(
22297
22417
  projectPath(CARRY_FILE),
22298
22418
  JSON.stringify({ from_key: sessionKey(sessionId), head_sha: headSha, ts: Date.now() })
22299
22419
  );
@@ -22303,10 +22423,10 @@ function writeCarry(sessionId, headSha) {
22303
22423
  function claimCarry(newKey) {
22304
22424
  const carryPath = projectPath(CARRY_FILE);
22305
22425
  try {
22306
- if (!(0, import_node_fs27.existsSync)(carryPath)) return null;
22307
- const carry = JSON.parse((0, import_node_fs27.readFileSync)(carryPath, "utf-8"));
22426
+ if (!(0, import_node_fs28.existsSync)(carryPath)) return null;
22427
+ const carry = JSON.parse((0, import_node_fs28.readFileSync)(carryPath, "utf-8"));
22308
22428
  try {
22309
- (0, import_node_fs27.rmSync)(carryPath, { force: true });
22429
+ (0, import_node_fs28.rmSync)(carryPath, { force: true });
22310
22430
  } catch {
22311
22431
  }
22312
22432
  if (!carry?.from_key || typeof carry.ts !== "number") return null;
@@ -22317,11 +22437,11 @@ function claimCarry(newKey) {
22317
22437
  if (!prior) return null;
22318
22438
  const toDir = sessionDir(newKey);
22319
22439
  try {
22320
- (0, import_node_fs27.rmSync)(toDir, { recursive: true, force: true });
22440
+ (0, import_node_fs28.rmSync)(toDir, { recursive: true, force: true });
22321
22441
  } catch {
22322
22442
  }
22323
- (0, import_node_fs27.renameSync)(fromDir, toDir);
22324
- (0, import_node_fs27.writeFileSync)(manifestPath(toDir), JSON.stringify({ ...prior, session_id: newKey }) + "\n");
22443
+ (0, import_node_fs28.renameSync)(fromDir, toDir);
22444
+ (0, import_node_fs28.writeFileSync)(manifestPath(toDir), JSON.stringify({ ...prior, session_id: newKey }) + "\n");
22325
22445
  return readManifest(toDir);
22326
22446
  } catch {
22327
22447
  return null;
@@ -22345,21 +22465,21 @@ function captureBaseline(opts = {}) {
22345
22465
  const head_sha = getCurrentCommit();
22346
22466
  const dirty = getDirtyFiles();
22347
22467
  try {
22348
- (0, import_node_fs27.rmSync)(dir, { recursive: true, force: true });
22468
+ (0, import_node_fs28.rmSync)(dir, { recursive: true, force: true });
22349
22469
  } catch {
22350
22470
  }
22351
- const filesDir = (0, import_node_path24.join)(dir, "files");
22471
+ const filesDir = (0, import_node_path25.join)(dir, "files");
22352
22472
  const mirrored = [];
22353
22473
  try {
22354
- (0, import_node_fs27.mkdirSync)(filesDir, { recursive: true });
22474
+ (0, import_node_fs28.mkdirSync)(filesDir, { recursive: true });
22355
22475
  for (const p of dirty) {
22356
22476
  if (p.includes("..")) continue;
22357
22477
  const content = safeReadForMirror(projectPath(p));
22358
22478
  if (content === null) continue;
22359
22479
  const dest = mirrorPath(dir, p);
22360
22480
  try {
22361
- (0, import_node_fs27.mkdirSync)((0, import_node_path24.dirname)(dest), { recursive: true });
22362
- (0, import_node_fs27.writeFileSync)(dest, content);
22481
+ (0, import_node_fs28.mkdirSync)((0, import_node_path25.dirname)(dest), { recursive: true });
22482
+ (0, import_node_fs28.writeFileSync)(dest, content);
22363
22483
  mirrored.push(p);
22364
22484
  } catch {
22365
22485
  }
@@ -22374,8 +22494,8 @@ function captureBaseline(opts = {}) {
22374
22494
  version: BASELINE_VERSION
22375
22495
  };
22376
22496
  try {
22377
- (0, import_node_fs27.mkdirSync)(dir, { recursive: true });
22378
- (0, import_node_fs27.writeFileSync)(manifestPath(dir), JSON.stringify(baseline));
22497
+ (0, import_node_fs28.mkdirSync)(dir, { recursive: true });
22498
+ (0, import_node_fs28.writeFileSync)(manifestPath(dir), JSON.stringify(baseline));
22379
22499
  } catch {
22380
22500
  }
22381
22501
  pruneOldBaselines();
@@ -22386,9 +22506,9 @@ function readBaseline(sessionId) {
22386
22506
  }
22387
22507
  function readManifest(dir) {
22388
22508
  const mp = manifestPath(dir);
22389
- if (!(0, import_node_fs27.existsSync)(mp)) return null;
22509
+ if (!(0, import_node_fs28.existsSync)(mp)) return null;
22390
22510
  try {
22391
- const parsed = JSON.parse((0, import_node_fs27.readFileSync)(mp, "utf-8"));
22511
+ const parsed = JSON.parse((0, import_node_fs28.readFileSync)(mp, "utf-8"));
22392
22512
  if (typeof parsed.head_sha !== "string" || typeof parsed.captured_at !== "number" || !Array.isArray(parsed.dirty_paths) || parsed.version !== BASELINE_VERSION) {
22393
22513
  return null;
22394
22514
  }
@@ -22419,9 +22539,9 @@ function preImage(repoRelPath, baseline) {
22419
22539
  function resolvePreImage(repoRelPath, baseline) {
22420
22540
  if (baseline.dirty_paths.includes(repoRelPath)) {
22421
22541
  const mp = mirrorPath(sessionDir(sessionKey(baseline.session_id)), repoRelPath);
22422
- if ((0, import_node_fs27.existsSync)(mp)) {
22542
+ if ((0, import_node_fs28.existsSync)(mp)) {
22423
22543
  try {
22424
- return { content: (0, import_node_fs27.readFileSync)(mp, "utf-8"), existed: true };
22544
+ return { content: (0, import_node_fs28.readFileSync)(mp, "utf-8"), existed: true };
22425
22545
  } catch {
22426
22546
  }
22427
22547
  }
@@ -22466,8 +22586,8 @@ function absorbIntoBaseline(paths, sessionId) {
22466
22586
  const content = safeReadForMirror(projectPath(p));
22467
22587
  if (content === null) continue;
22468
22588
  const dest = mirrorPath(dir, p);
22469
- (0, import_node_fs27.mkdirSync)((0, import_node_path24.dirname)(dest), { recursive: true });
22470
- (0, import_node_fs27.writeFileSync)(dest, content);
22589
+ (0, import_node_fs28.mkdirSync)((0, import_node_path25.dirname)(dest), { recursive: true });
22590
+ (0, import_node_fs28.writeFileSync)(dest, content);
22471
22591
  dirty.add(p);
22472
22592
  adopted++;
22473
22593
  } catch {
@@ -22476,7 +22596,7 @@ function absorbIntoBaseline(paths, sessionId) {
22476
22596
  if (adopted === 0) return 0;
22477
22597
  try {
22478
22598
  const updated = { ...baseline, dirty_paths: [...dirty] };
22479
- (0, import_node_fs27.writeFileSync)(manifestPath(dir), JSON.stringify(updated));
22599
+ (0, import_node_fs28.writeFileSync)(manifestPath(dir), JSON.stringify(updated));
22480
22600
  preImageCache.delete(baseline);
22481
22601
  } catch {
22482
22602
  return 0;
@@ -22487,7 +22607,7 @@ function changedSinceBaseline(repoRelPath, baseline) {
22487
22607
  const pre = preImage(repoRelPath, baseline);
22488
22608
  let current;
22489
22609
  try {
22490
- current = (0, import_node_fs27.readFileSync)(projectPath(repoRelPath), "utf-8");
22610
+ current = (0, import_node_fs28.readFileSync)(projectPath(repoRelPath), "utf-8");
22491
22611
  } catch {
22492
22612
  return pre.existed;
22493
22613
  }
@@ -22496,8 +22616,8 @@ function changedSinceBaseline(repoRelPath, baseline) {
22496
22616
  }
22497
22617
  function safeReadForMirror(absPath) {
22498
22618
  try {
22499
- if ((0, import_node_fs27.statSync)(absPath).size > MIRROR_MAX_BYTES) return null;
22500
- const buf = (0, import_node_fs27.readFileSync)(absPath);
22619
+ if ((0, import_node_fs28.statSync)(absPath).size > MIRROR_MAX_BYTES) return null;
22620
+ const buf = (0, import_node_fs28.readFileSync)(absPath);
22501
22621
  if (buf.includes(0)) return null;
22502
22622
  return buf.toString("utf-8");
22503
22623
  } catch {
@@ -22508,18 +22628,18 @@ function pruneOldBaselines() {
22508
22628
  const root = projectPath(BASELINE_DIR);
22509
22629
  let entries;
22510
22630
  try {
22511
- entries = (0, import_node_fs27.readdirSync)(root);
22631
+ entries = (0, import_node_fs28.readdirSync)(root);
22512
22632
  } catch {
22513
22633
  return;
22514
22634
  }
22515
22635
  const now = Date.now();
22516
22636
  for (const name2 of entries) {
22517
- const dir = (0, import_node_path24.join)(root, name2);
22637
+ const dir = (0, import_node_path25.join)(root, name2);
22518
22638
  const manifest = readManifest(dir);
22519
22639
  if (!manifest) {
22520
22640
  try {
22521
- if (now - (0, import_node_fs27.statSync)(dir).mtimeMs > BASELINE_TTL_MS) {
22522
- (0, import_node_fs27.rmSync)(dir, { recursive: true, force: true });
22641
+ if (now - (0, import_node_fs28.statSync)(dir).mtimeMs > BASELINE_TTL_MS) {
22642
+ (0, import_node_fs28.rmSync)(dir, { recursive: true, force: true });
22523
22643
  }
22524
22644
  } catch {
22525
22645
  }
@@ -22527,7 +22647,7 @@ function pruneOldBaselines() {
22527
22647
  }
22528
22648
  if (now - manifest.captured_at <= BASELINE_TTL_MS) continue;
22529
22649
  try {
22530
- (0, import_node_fs27.rmSync)(dir, { recursive: true, force: true });
22650
+ (0, import_node_fs28.rmSync)(dir, { recursive: true, force: true });
22531
22651
  } catch {
22532
22652
  }
22533
22653
  }
@@ -22702,8 +22822,8 @@ function buildCompactionContext(session) {
22702
22822
  commitsSince: commitsSincePaths(watermark, (state.authored ?? []).map((a) => a.path)),
22703
22823
  readFileLines: (file) => {
22704
22824
  try {
22705
- const abs = (0, import_node_path25.join)(root, file);
22706
- return (0, import_node_fs28.existsSync)(abs) ? (0, import_node_fs28.readFileSync)(abs, "utf8").split("\n") : null;
22825
+ const abs = (0, import_node_path26.join)(root, file);
22826
+ return (0, import_node_fs29.existsSync)(abs) ? (0, import_node_fs29.readFileSync)(abs, "utf8").split("\n") : null;
22707
22827
  } catch {
22708
22828
  return null;
22709
22829
  }
@@ -22760,24 +22880,24 @@ async function readHookStdin() {
22760
22880
 
22761
22881
  // src/commands/standard.ts
22762
22882
  var import_promises13 = require("node:fs/promises");
22763
- var import_node_fs35 = require("node:fs");
22883
+ var import_node_fs36 = require("node:fs");
22764
22884
  var import_yaml3 = __toESM2(require_dist());
22765
22885
 
22766
22886
  // src/lib/synthesize.ts
22767
- var import_node_child_process9 = require("node:child_process");
22768
- var import_node_fs31 = require("node:fs");
22887
+ var import_node_child_process10 = require("node:child_process");
22888
+ var import_node_fs32 = require("node:fs");
22769
22889
  var import_promises10 = require("node:fs/promises");
22770
- var import_node_path28 = require("node:path");
22890
+ var import_node_path29 = require("node:path");
22771
22891
  var import_yaml = __toESM2(require_dist());
22772
22892
 
22773
22893
  // src/lib/data-dir.ts
22774
- var import_node_fs29 = require("node:fs");
22775
- var import_node_path26 = require("node:path");
22894
+ var import_node_fs30 = require("node:fs");
22895
+ var import_node_path27 = require("node:path");
22776
22896
  function resolveDataDir() {
22777
22897
  const candidates2 = [
22778
- (0, import_node_path26.join)(__dirname, "..", "data"),
22898
+ (0, import_node_path27.join)(__dirname, "..", "data"),
22779
22899
  // installed: node_modules/@codacy/verity-cli/data
22780
- (0, import_node_path26.join)(__dirname, "..", "..", "data"),
22900
+ (0, import_node_path27.join)(__dirname, "..", "..", "data"),
22781
22901
  // edge case: nested resolution
22782
22902
  // THE COMMITTED SOURCE, for a source checkout that has not been built.
22783
22903
  // cli/data/skills/ is a BUILD ARTIFACT (scripts/build.js copies client/skills
@@ -22786,14 +22906,14 @@ function resolveDataDir() {
22786
22906
  // without this the synthesizer throws "Could not find Verity skill data"
22787
22907
  // for every test and every `verity` run from source. Resolved from this
22788
22908
  // module's own location, never the cwd: see the warning below.
22789
- (0, import_node_path26.join)(__dirname, "..", "..", "client"),
22909
+ (0, import_node_path27.join)(__dirname, "..", "..", "client"),
22790
22910
  // bundled: cli/bin/ → ../../client
22791
- (0, import_node_path26.join)(__dirname, "..", "..", "..", "client"),
22911
+ (0, import_node_path27.join)(__dirname, "..", "..", "..", "client"),
22792
22912
  // tsx: cli/src/lib/ → ../../../client
22793
22913
  ...process.env.VERITY_DEV_DATA_DIR ? [process.env.VERITY_DEV_DATA_DIR] : []
22794
22914
  ];
22795
22915
  for (const candidate of candidates2) {
22796
- if ((0, import_node_fs29.existsSync)((0, import_node_path26.join)(candidate, "skills"))) {
22916
+ if ((0, import_node_fs30.existsSync)((0, import_node_path27.join)(candidate, "skills"))) {
22797
22917
  return candidate;
22798
22918
  }
22799
22919
  }
@@ -22802,13 +22922,13 @@ function resolveDataDir() {
22802
22922
  );
22803
22923
  }
22804
22924
  function setupDataPath(file) {
22805
- return (0, import_node_path26.join)(resolveDataDir(), "skills", "verity-setup", file);
22925
+ return (0, import_node_path27.join)(resolveDataDir(), "skills", "verity-setup", file);
22806
22926
  }
22807
22927
 
22808
22928
  // src/lib/detect.ts
22809
- var import_node_child_process8 = require("node:child_process");
22810
- var import_node_fs30 = require("node:fs");
22811
- var import_node_path27 = require("node:path");
22929
+ var import_node_child_process9 = require("node:child_process");
22930
+ var import_node_fs31 = require("node:fs");
22931
+ var import_node_path28 = require("node:path");
22812
22932
  var TOOLED_LANGUAGES = /* @__PURE__ */ new Set([
22813
22933
  "typescript",
22814
22934
  "javascript",
@@ -22845,7 +22965,7 @@ function isIgnored2(path) {
22845
22965
  }
22846
22966
  function listProjectFiles(root) {
22847
22967
  try {
22848
- const out2 = (0, import_node_child_process8.execSync)("git ls-files -z", {
22968
+ const out2 = (0, import_node_child_process9.execSync)("git ls-files -z", {
22849
22969
  cwd: root,
22850
22970
  encoding: "utf-8",
22851
22971
  maxBuffer: 32 * 1024 * 1024,
@@ -22865,25 +22985,25 @@ function walk(root) {
22865
22985
  if (depth > WALK_MAX_DEPTH || found.length >= WALK_MAX_FILES) return;
22866
22986
  let entries;
22867
22987
  try {
22868
- entries = (0, import_node_fs30.readdirSync)(dir, { withFileTypes: true });
22988
+ entries = (0, import_node_fs31.readdirSync)(dir, { withFileTypes: true });
22869
22989
  } catch {
22870
22990
  return;
22871
22991
  }
22872
22992
  for (const entry of entries) {
22873
22993
  if (found.length >= WALK_MAX_FILES) return;
22874
22994
  if (IGNORED_SEGMENTS.includes(entry.name)) continue;
22875
- const full = (0, import_node_path27.join)(dir, entry.name);
22995
+ const full = (0, import_node_path28.join)(dir, entry.name);
22876
22996
  if (entry.isDirectory()) visit(full, depth + 1);
22877
- else if (entry.isFile()) found.push((0, import_node_path27.relative)(root, full));
22997
+ else if (entry.isFile()) found.push((0, import_node_path28.relative)(root, full));
22878
22998
  }
22879
22999
  };
22880
23000
  visit(root, 0);
22881
23001
  return found;
22882
23002
  }
22883
23003
  function languageOf(path) {
22884
- const name2 = (0, import_node_path27.basename)(path);
23004
+ const name2 = (0, import_node_path28.basename)(path);
22885
23005
  if (/^Dockerfile(\..+)?$/i.test(name2)) return "dockerfile";
22886
- if (!(0, import_node_path27.extname)(name2)) return null;
23006
+ if (!(0, import_node_path28.extname)(name2)) return null;
22887
23007
  const lang = detectLanguage(path);
22888
23008
  return lang || null;
22889
23009
  }
@@ -22940,7 +23060,7 @@ var TOOL_CONFIG_MARKERS = [
22940
23060
  ];
22941
23061
  function readJson2(path) {
22942
23062
  try {
22943
- return JSON.parse((0, import_node_fs30.readFileSync)(path, "utf-8"));
23063
+ return JSON.parse((0, import_node_fs31.readFileSync)(path, "utf-8"));
22944
23064
  } catch {
22945
23065
  return null;
22946
23066
  }
@@ -22965,17 +23085,17 @@ function declaredDependencies(root, files) {
22965
23085
  if (deps && typeof deps === "object") names2.push(...Object.keys(deps));
22966
23086
  }
22967
23087
  };
22968
- readPackageJson((0, import_node_path27.join)(root, "package.json"));
22969
- const nested = files.filter((f) => f.includes("/") && (0, import_node_path27.basename)(f) === "package.json").slice(0, NESTED_MANIFEST_LIMIT);
22970
- for (const rel of nested) readPackageJson((0, import_node_path27.join)(root, rel));
23088
+ readPackageJson((0, import_node_path28.join)(root, "package.json"));
23089
+ const nested = files.filter((f) => f.includes("/") && (0, import_node_path28.basename)(f) === "package.json").slice(0, NESTED_MANIFEST_LIMIT);
23090
+ for (const rel of nested) readPackageJson((0, import_node_path28.join)(root, rel));
22971
23091
  const pythonManifests = [
22972
- ...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0, import_node_path27.join)(root, f)),
22973
- ...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path27.join)(root, f))
23092
+ ...["pyproject.toml", "requirements.txt", "Pipfile", "setup.py"].map((f) => (0, import_node_path28.join)(root, f)),
23093
+ ...files.filter((f) => f.includes("/") && /(^|\/)(pyproject\.toml|requirements\.txt)$/.test(f)).slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path28.join)(root, f))
22974
23094
  ];
22975
23095
  for (const path of pythonManifests) {
22976
- if (!(0, import_node_fs30.existsSync)(path)) continue;
23096
+ if (!(0, import_node_fs31.existsSync)(path)) continue;
22977
23097
  try {
22978
- const text = (0, import_node_fs30.readFileSync)(path, "utf-8");
23098
+ const text = (0, import_node_fs31.readFileSync)(path, "utf-8");
22979
23099
  for (const m of text.matchAll(/^\s*["']?([A-Za-z][A-Za-z0-9._-]+)/gm)) names2.push(m[1]);
22980
23100
  for (const line2 of text.split("\n")) {
22981
23101
  if (!/dependencies\s*=/.test(line2)) continue;
@@ -22985,13 +23105,13 @@ function declaredDependencies(root, files) {
22985
23105
  }
22986
23106
  }
22987
23107
  const goMods = [
22988
- (0, import_node_path27.join)(root, "go.mod"),
22989
- ...files.filter((f) => f.includes("/") && (0, import_node_path27.basename)(f) === "go.mod").slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path27.join)(root, f))
23108
+ (0, import_node_path28.join)(root, "go.mod"),
23109
+ ...files.filter((f) => f.includes("/") && (0, import_node_path28.basename)(f) === "go.mod").slice(0, NESTED_MANIFEST_LIMIT).map((f) => (0, import_node_path28.join)(root, f))
22990
23110
  ];
22991
23111
  for (const path of goMods) {
22992
- if (!(0, import_node_fs30.existsSync)(path)) continue;
23112
+ if (!(0, import_node_fs31.existsSync)(path)) continue;
22993
23113
  try {
22994
- const text = (0, import_node_fs30.readFileSync)(path, "utf-8");
23114
+ const text = (0, import_node_fs31.readFileSync)(path, "utf-8");
22995
23115
  for (const m of text.matchAll(/^\s+([\w.-]+\/[\w./-]+)\s+v/gm)) {
22996
23116
  names2.push(m[1].replace(/^github\.com\//, ""));
22997
23117
  }
@@ -22999,10 +23119,10 @@ function declaredDependencies(root, files) {
22999
23119
  }
23000
23120
  }
23001
23121
  for (const file of ["pom.xml", "build.gradle", "build.gradle.kts", "Gemfile", "Cargo.toml"]) {
23002
- const path = (0, import_node_path27.join)(root, file);
23003
- if (!(0, import_node_fs30.existsSync)(path)) continue;
23122
+ const path = (0, import_node_path28.join)(root, file);
23123
+ if (!(0, import_node_fs31.existsSync)(path)) continue;
23004
23124
  try {
23005
- const text = (0, import_node_fs30.readFileSync)(path, "utf-8");
23125
+ const text = (0, import_node_fs31.readFileSync)(path, "utf-8");
23006
23126
  for (const m of text.matchAll(/["'<]([A-Za-z][A-Za-z0-9._-]{2,})["'>]/g)) names2.push(m[1]);
23007
23127
  } catch {
23008
23128
  }
@@ -23010,7 +23130,7 @@ function declaredDependencies(root, files) {
23010
23130
  return names2;
23011
23131
  }
23012
23132
  function detectBuildSystem(root, files) {
23013
- const has = (f) => (0, import_node_fs30.existsSync)((0, import_node_path27.join)(root, f)) || files.some((p) => (0, import_node_path27.basename)(p) === f);
23133
+ const has = (f) => (0, import_node_fs31.existsSync)((0, import_node_path28.join)(root, f)) || files.some((p) => (0, import_node_path28.basename)(p) === f);
23014
23134
  if (has("pnpm-lock.yaml")) return "pnpm";
23015
23135
  if (has("yarn.lock")) return "yarn";
23016
23136
  if (has("bun.lock") || has("bun.lockb")) return "bun";
@@ -23027,8 +23147,8 @@ function detectBuildSystem(root, files) {
23027
23147
  }
23028
23148
  function detectArchitecture(root, files) {
23029
23149
  const workspaceMarkers = ["lerna.json", "pnpm-workspace.yaml", "nx.json", "turbo.json", "rush.json"];
23030
- if (workspaceMarkers.some((m) => (0, import_node_fs30.existsSync)((0, import_node_path27.join)(root, m)))) return "monorepo";
23031
- const pkg = readJson2((0, import_node_path27.join)(root, "package.json"));
23150
+ if (workspaceMarkers.some((m) => (0, import_node_fs31.existsSync)((0, import_node_path28.join)(root, m)))) return "monorepo";
23151
+ const pkg = readJson2((0, import_node_path28.join)(root, "package.json"));
23032
23152
  if (pkg && "workspaces" in pkg) return "monorepo";
23033
23153
  const manifests = files.filter((f) => /(^|\/)(package\.json|go\.mod|pyproject\.toml|Cargo\.toml|pom\.xml)$/.test(f));
23034
23154
  const nested = manifests.filter((f) => f.includes("/"));
@@ -23050,10 +23170,10 @@ function measureAvgFileLength(root, files, languages) {
23050
23170
  let total = 0;
23051
23171
  let counted = 0;
23052
23172
  for (let i2 = 0; i2 < candidates2.length; i2 += stride) {
23053
- const path = (0, import_node_path27.join)(root, candidates2[i2]);
23173
+ const path = (0, import_node_path28.join)(root, candidates2[i2]);
23054
23174
  try {
23055
- if ((0, import_node_fs30.statSync)(path).size > 2 * 1024 * 1024) continue;
23056
- total += (0, import_node_fs30.readFileSync)(path, "utf-8").split("\n").length;
23175
+ if ((0, import_node_fs31.statSync)(path).size > 2 * 1024 * 1024) continue;
23176
+ total += (0, import_node_fs31.readFileSync)(path, "utf-8").split("\n").length;
23057
23177
  counted++;
23058
23178
  } catch {
23059
23179
  }
@@ -23083,14 +23203,14 @@ function detectProject(root = repoRoot()) {
23083
23203
  const existingToolConfigs = [];
23084
23204
  for (const [tool, markers] of TOOL_CONFIG_MARKERS) {
23085
23205
  for (const marker of markers) {
23086
- if ((0, import_node_fs30.existsSync)((0, import_node_path27.join)(root, marker))) {
23206
+ if ((0, import_node_fs31.existsSync)((0, import_node_path28.join)(root, marker))) {
23087
23207
  existingToolConfigs.push({ tool, path: `./${marker}` });
23088
23208
  break;
23089
23209
  }
23090
23210
  }
23091
23211
  }
23092
23212
  return {
23093
- projectName: (0, import_node_path27.basename)(root),
23213
+ projectName: (0, import_node_path28.basename)(root),
23094
23214
  languages,
23095
23215
  languageCounts,
23096
23216
  frameworks: matchAll(dependencies, FRAMEWORK_BY_DEPENDENCY),
@@ -23188,8 +23308,8 @@ ${closingNote(input.origin)}
23188
23308
 
23189
23309
  // src/lib/synthesize.ts
23190
23310
  function loadCatalog() {
23191
- const catalog = (0, import_yaml.parse)((0, import_node_fs31.readFileSync)(setupDataPath("patterns-reference.yaml"), "utf-8"));
23192
- const template = (0, import_yaml.parse)((0, import_node_fs31.readFileSync)(setupDataPath("standard-template.yaml"), "utf-8"));
23311
+ const catalog = (0, import_yaml.parse)((0, import_node_fs32.readFileSync)(setupDataPath("patterns-reference.yaml"), "utf-8"));
23312
+ const template = (0, import_yaml.parse)((0, import_node_fs32.readFileSync)(setupDataPath("standard-template.yaml"), "utf-8"));
23193
23313
  return { catalog, template };
23194
23314
  }
23195
23315
  function selectTools(languages, intensity, catalog) {
@@ -23240,7 +23360,7 @@ var TRIVY_BY_INTENSITY = {
23240
23360
  };
23241
23361
  function adapterPatternIds(toolId) {
23242
23362
  try {
23243
- const out2 = (0, import_node_child_process9.execFileSync)(
23363
+ const out2 = (0, import_node_child_process10.execFileSync)(
23244
23364
  process.execPath,
23245
23365
  [setupDataPath("validate-patterns.mjs"), "--list", toolId],
23246
23366
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e4 }
@@ -23270,7 +23390,7 @@ function resolvePatternId(toolId, curatedId, adapterIds) {
23270
23390
  }
23271
23391
  function trivyPatterns(intensity) {
23272
23392
  try {
23273
- const out2 = (0, import_node_child_process9.execFileSync)(
23393
+ const out2 = (0, import_node_child_process10.execFileSync)(
23274
23394
  process.execPath,
23275
23395
  [setupDataPath("validate-patterns.mjs"), "--emit", "Trivy", TRIVY_BY_INTENSITY[intensity].emit],
23276
23396
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 3e4 }
@@ -23450,7 +23570,7 @@ export default tseslint.config(
23450
23570
  function validatePatternIds() {
23451
23571
  const configPath = projectPath(CODACY_CONFIG_FILE);
23452
23572
  try {
23453
- (0, import_node_child_process9.execFileSync)(process.execPath, [setupDataPath("validate-patterns.mjs"), configPath], {
23573
+ (0, import_node_child_process10.execFileSync)(process.execPath, [setupDataPath("validate-patterns.mjs"), configPath], {
23454
23574
  encoding: "utf-8",
23455
23575
  stdio: ["pipe", "pipe", "pipe"],
23456
23576
  timeout: 6e4
@@ -23467,7 +23587,7 @@ function validatePatternIds() {
23467
23587
  }
23468
23588
  async function runSynthesis(opts) {
23469
23589
  const standardPath = projectPath(STANDARD_FILE);
23470
- if ((0, import_node_fs31.existsSync)(standardPath) && !opts.force) {
23590
+ if ((0, import_node_fs32.existsSync)(standardPath) && !opts.force) {
23471
23591
  return { refused: `${STANDARD_FILE} already exists \u2014 pass --force to replace it.` };
23472
23592
  }
23473
23593
  const detected = opts.detected ?? detectProject();
@@ -23536,7 +23656,7 @@ async function correctVerityMdVersion(opts) {
23536
23656
  }
23537
23657
  async function writeFileTo(relative6, body2) {
23538
23658
  const target = projectPath(relative6);
23539
- await (0, import_promises10.mkdir)((0, import_node_path28.dirname)(target), { recursive: true });
23659
+ await (0, import_promises10.mkdir)((0, import_node_path29.dirname)(target), { recursive: true });
23540
23660
  await (0, import_promises10.writeFile)(target, body2);
23541
23661
  }
23542
23662
  async function deriveConfigForStandard(standard) {
@@ -23595,11 +23715,11 @@ ${validation.detail}`);
23595
23715
 
23596
23716
  // src/lib/setup-state.ts
23597
23717
  var import_promises11 = require("node:fs/promises");
23598
- var import_node_fs32 = require("node:fs");
23718
+ var import_node_fs33 = require("node:fs");
23599
23719
  var SETUP_STATE_FILE = `${VERITY_DIR}/setup.json`;
23600
23720
  async function readSetupState() {
23601
23721
  const path = projectPath(SETUP_STATE_FILE);
23602
- if (!(0, import_node_fs32.existsSync)(path)) return null;
23722
+ if (!(0, import_node_fs33.existsSync)(path)) return null;
23603
23723
  try {
23604
23724
  const parsed = JSON.parse(await (0, import_promises11.readFile)(path, "utf-8"));
23605
23725
  return parsed && typeof parsed === "object" ? parsed : null;
@@ -23615,12 +23735,12 @@ async function writeSetupState(patch) {
23615
23735
  }
23616
23736
 
23617
23737
  // src/lib/push-setup.ts
23618
- var import_node_fs34 = require("node:fs");
23738
+ var import_node_fs35 = require("node:fs");
23619
23739
  var import_promises12 = require("node:fs/promises");
23620
23740
  var import_yaml2 = __toESM2(require_dist());
23621
23741
 
23622
23742
  // src/lib/verityignore.ts
23623
- var import_node_fs33 = require("node:fs");
23743
+ var import_node_fs34 = require("node:fs");
23624
23744
  var EMPTY = { rules: [], securityOverlap: [], problems: [] };
23625
23745
  var SECURITY_PROBES = [
23626
23746
  ".env",
@@ -23713,9 +23833,9 @@ function isIgnored3(ig, path) {
23713
23833
  }
23714
23834
  function loadVerityIgnore() {
23715
23835
  const file = projectPath(VERITYIGNORE_FILE);
23716
- if (!(0, import_node_fs33.existsSync)(file)) return EMPTY;
23836
+ if (!(0, import_node_fs34.existsSync)(file)) return EMPTY;
23717
23837
  try {
23718
- return parseVerityIgnore((0, import_node_fs33.readFileSync)(file, "utf-8"));
23838
+ return parseVerityIgnore((0, import_node_fs34.readFileSync)(file, "utf-8"));
23719
23839
  } catch {
23720
23840
  return EMPTY;
23721
23841
  }
@@ -23753,9 +23873,9 @@ function buildStandardUpload(standard, ignoreRaw) {
23753
23873
  }
23754
23874
  function readVerityIgnoreRaw() {
23755
23875
  const file = projectPath(VERITYIGNORE_FILE);
23756
- if (!(0, import_node_fs33.existsSync)(file)) return null;
23876
+ if (!(0, import_node_fs34.existsSync)(file)) return null;
23757
23877
  try {
23758
- return (0, import_node_fs33.readFileSync)(file, "utf-8");
23878
+ return (0, import_node_fs34.readFileSync)(file, "utf-8");
23759
23879
  } catch {
23760
23880
  return null;
23761
23881
  }
@@ -23783,7 +23903,7 @@ async function pushStandardAndConfig(globals, what = {}) {
23783
23903
  }
23784
23904
  let standardVersion = null;
23785
23905
  const standardPath = projectPath(STANDARD_FILE);
23786
- if (pushStandard && (0, import_node_fs34.existsSync)(standardPath)) {
23906
+ if (pushStandard && (0, import_node_fs35.existsSync)(standardPath)) {
23787
23907
  try {
23788
23908
  const content = (0, import_yaml2.parse)(await (0, import_promises12.readFile)(standardPath, "utf-8"));
23789
23909
  const upload = buildStandardUpload(content, readVerityIgnoreRaw());
@@ -23808,7 +23928,7 @@ async function pushStandardAndConfig(globals, what = {}) {
23808
23928
  }
23809
23929
  let configPushed = false;
23810
23930
  const configPath = projectPath(CODACY_CONFIG_FILE);
23811
- if (pushConfig && (0, import_node_fs34.existsSync)(configPath)) {
23931
+ if (pushConfig && (0, import_node_fs35.existsSync)(configPath)) {
23812
23932
  try {
23813
23933
  const content = JSON.parse(await (0, import_promises12.readFile)(configPath, "utf-8"));
23814
23934
  const result = await apiRequest({
@@ -23840,7 +23960,7 @@ function registerStandardCommands(program2) {
23840
23960
  const state = await readSetupState();
23841
23961
  if (opts.configOnly) {
23842
23962
  const standardPath = projectPath(STANDARD_FILE);
23843
- if (!(0, import_node_fs35.existsSync)(standardPath)) {
23963
+ if (!(0, import_node_fs36.existsSync)(standardPath)) {
23844
23964
  printError(`No ${STANDARD_FILE} here \u2014 run "verity standard synthesize" to create one.`);
23845
23965
  process.exit(1);
23846
23966
  }
@@ -24031,14 +24151,21 @@ function registerConfigCommands(program2) {
24031
24151
  });
24032
24152
  config.command("formal [state]").description('Get or set formal verification at push: "push" or "off" (needs Lean \u2014 verity lean status)').action((state) => {
24033
24153
  if (state === void 0) {
24034
- process.stdout.write((readProjectConfig().formal ?? "off") + "\n");
24154
+ const cfg = readProjectConfig();
24155
+ process.stdout.write((cfg.formal === "push" ? "push" : "off") + "\n");
24156
+ if (cfg.formal_refused) printWarn(formalRefusalMessage(cfg.formal_refused));
24035
24157
  return;
24036
24158
  }
24037
24159
  if (state !== "push" && state !== "off") {
24038
24160
  printError(`Unrecognised state: ${state}. Use "push" or "off".`);
24039
24161
  process.exit(1);
24040
24162
  }
24041
- writeProjectConfig({ formal: state === "push" ? "push" : void 0 });
24163
+ writeProjectConfig({ formal: state === "push" ? "push" : "off" });
24164
+ const refused2 = state === "push" ? readProjectConfig().formal_refused : void 0;
24165
+ if (refused2) {
24166
+ printWarn(`Formal verification at push: still off \u2014 ${formalRefusalMessage(refused2)}`);
24167
+ return;
24168
+ }
24042
24169
  printInfo(state === "push" ? "Formal verification at push: on for this checkout (Lean must be installed \u2014 verity lean status)" : "Formal verification at push: off");
24043
24170
  if (state === "push") printInfo("The phase runs with your Verity login (a push without one is skipped and says so: not-logged-in)");
24044
24171
  });
@@ -24186,10 +24313,10 @@ function formatRunDetail(run4) {
24186
24313
  }
24187
24314
 
24188
24315
  // src/lib/ignore-declaration.ts
24189
- var import_node_fs37 = require("node:fs");
24316
+ var import_node_fs38 = require("node:fs");
24190
24317
 
24191
24318
  // src/lib/debounce.ts
24192
- var import_node_fs36 = require("node:fs");
24319
+ var import_node_fs37 = require("node:fs");
24193
24320
  var import_node_crypto11 = require("node:crypto");
24194
24321
  function scopedFile(base, sessionId) {
24195
24322
  if (!sessionId) return base;
@@ -24197,9 +24324,9 @@ function scopedFile(base, sessionId) {
24197
24324
  }
24198
24325
  function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
24199
24326
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
24200
- if (!(0, import_node_fs36.existsSync)(file)) return null;
24327
+ if (!(0, import_node_fs37.existsSync)(file)) return null;
24201
24328
  try {
24202
- const lastTs = parseInt((0, import_node_fs36.readFileSync)(file, "utf-8").trim(), 10);
24329
+ const lastTs = parseInt((0, import_node_fs37.readFileSync)(file, "utf-8").trim(), 10);
24203
24330
  const nowTs = Math.floor(Date.now() / 1e3);
24204
24331
  const elapsed = nowTs - lastTs;
24205
24332
  if (elapsed < debounceSeconds) {
@@ -24212,10 +24339,10 @@ function checkDebounce(debounceSeconds = DEBOUNCE_SECONDS, sessionId) {
24212
24339
  function checkMtime(files, bypassForRecentCommits, sessionId) {
24213
24340
  if (bypassForRecentCommits) return null;
24214
24341
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
24215
- if (!(0, import_node_fs36.existsSync)(file)) return null;
24342
+ if (!(0, import_node_fs37.existsSync)(file)) return null;
24216
24343
  let debounceTime;
24217
24344
  try {
24218
- debounceTime = (0, import_node_fs36.statSync)(file).mtimeMs;
24345
+ debounceTime = (0, import_node_fs37.statSync)(file).mtimeMs;
24219
24346
  } catch {
24220
24347
  return null;
24221
24348
  }
@@ -24223,7 +24350,7 @@ function checkMtime(files, bypassForRecentCommits, sessionId) {
24223
24350
  const resolved = resolveFile(f);
24224
24351
  if (!resolved) continue;
24225
24352
  try {
24226
- const stat3 = (0, import_node_fs36.statSync)(resolved);
24353
+ const stat3 = (0, import_node_fs37.statSync)(resolved);
24227
24354
  if (stat3.mtimeMs > debounceTime) {
24228
24355
  return null;
24229
24356
  }
@@ -24239,8 +24366,8 @@ function computeContentHash(files) {
24239
24366
  for (const f of sorted) {
24240
24367
  const resolved = resolveFile(f) ?? f;
24241
24368
  try {
24242
- if ((0, import_node_fs36.existsSync)(resolved)) {
24243
- hash.update((0, import_node_fs36.readFileSync)(resolved));
24369
+ if ((0, import_node_fs37.existsSync)(resolved)) {
24370
+ hash.update((0, import_node_fs37.readFileSync)(resolved));
24244
24371
  }
24245
24372
  } catch {
24246
24373
  }
@@ -24250,9 +24377,9 @@ function computeContentHash(files) {
24250
24377
  function checkContentHash(files, sessionId) {
24251
24378
  const hash = computeContentHash(files);
24252
24379
  const file = scopedFile(HASH_FILE, sessionId);
24253
- if ((0, import_node_fs36.existsSync)(file)) {
24380
+ if ((0, import_node_fs37.existsSync)(file)) {
24254
24381
  try {
24255
- const storedHash = (0, import_node_fs36.readFileSync)(file, "utf-8").trim();
24382
+ const storedHash = (0, import_node_fs37.readFileSync)(file, "utf-8").trim();
24256
24383
  if (hash === storedHash) {
24257
24384
  return { skip: "No source changes since last analysis", hash };
24258
24385
  }
@@ -24262,24 +24389,24 @@ function checkContentHash(files, sessionId) {
24262
24389
  return { skip: null, hash };
24263
24390
  }
24264
24391
  function recordAnalysisStart(sessionId) {
24265
- (0, import_node_fs36.mkdirSync)(VERITY_DIR, { recursive: true });
24266
- (0, import_node_fs36.writeFileSync)(scopedFile(DEBOUNCE_FILE, sessionId), String(Math.floor(Date.now() / 1e3)));
24392
+ (0, import_node_fs37.mkdirSync)(VERITY_DIR, { recursive: true });
24393
+ (0, import_node_fs37.writeFileSync)(scopedFile(DEBOUNCE_FILE, sessionId), String(Math.floor(Date.now() / 1e3)));
24267
24394
  }
24268
24395
  function recordPassHash(hash, sessionId) {
24269
- (0, import_node_fs36.writeFileSync)(scopedFile(HASH_FILE, sessionId), hash);
24396
+ (0, import_node_fs37.writeFileSync)(scopedFile(HASH_FILE, sessionId), hash);
24270
24397
  }
24271
24398
  function narrowToRecent(files, sessionId) {
24272
24399
  const file = scopedFile(DEBOUNCE_FILE, sessionId);
24273
- if (!(0, import_node_fs36.existsSync)(file)) return files;
24400
+ if (!(0, import_node_fs37.existsSync)(file)) return files;
24274
24401
  let debounceTime;
24275
24402
  try {
24276
- debounceTime = (0, import_node_fs36.statSync)(file).mtimeMs;
24403
+ debounceTime = (0, import_node_fs37.statSync)(file).mtimeMs;
24277
24404
  } catch {
24278
24405
  return files;
24279
24406
  }
24280
24407
  const recent = files.filter((f) => {
24281
24408
  try {
24282
- return (0, import_node_fs36.existsSync)(f) && (0, import_node_fs36.statSync)(f).mtimeMs > debounceTime;
24409
+ return (0, import_node_fs37.existsSync)(f) && (0, import_node_fs37.statSync)(f).mtimeMs > debounceTime;
24283
24410
  } catch {
24284
24411
  return false;
24285
24412
  }
@@ -24292,9 +24419,9 @@ function readIteration(currentCommit, _contentHash) {
24292
24419
  var NO_BLOCKS = { attempts: 0, blocks: 0, fingerprint: null };
24293
24420
  function readBlockState(currentCommit, opts) {
24294
24421
  if (opts?.newUserPrompt) return NO_BLOCKS;
24295
- if (!(0, import_node_fs36.existsSync)(ITERATION_FILE)) return NO_BLOCKS;
24422
+ if (!(0, import_node_fs37.existsSync)(ITERATION_FILE)) return NO_BLOCKS;
24296
24423
  try {
24297
- const stored = (0, import_node_fs36.readFileSync)(ITERATION_FILE, "utf-8").trim();
24424
+ const stored = (0, import_node_fs37.readFileSync)(ITERATION_FILE, "utf-8").trim();
24298
24425
  const parsed = stored.startsWith("{") ? parseJsonState(stored) : parseLegacyState(stored);
24299
24426
  if (!parsed) return NO_BLOCKS;
24300
24427
  if (parsed.commit !== currentCommit) return NO_BLOCKS;
@@ -24340,8 +24467,8 @@ function isSameProblem(previous, current) {
24340
24467
  return current.split(",").some((k) => prev.has(k));
24341
24468
  }
24342
24469
  function writeBlockState(commit, state) {
24343
- (0, import_node_fs36.mkdirSync)(VERITY_DIR, { recursive: true });
24344
- (0, import_node_fs36.writeFileSync)(
24470
+ (0, import_node_fs37.mkdirSync)(VERITY_DIR, { recursive: true });
24471
+ (0, import_node_fs37.writeFileSync)(
24345
24472
  ITERATION_FILE,
24346
24473
  JSON.stringify({
24347
24474
  v: 2,
@@ -24446,9 +24573,9 @@ function resolveIgnoreState(keys) {
24446
24573
  }
24447
24574
  function readIgnoreState(sessionId) {
24448
24575
  const file = stateFile(sessionId);
24449
- if (!(0, import_node_fs37.existsSync)(file)) return null;
24576
+ if (!(0, import_node_fs38.existsSync)(file)) return null;
24450
24577
  try {
24451
- const o = JSON.parse((0, import_node_fs37.readFileSync)(file, "utf-8")) ?? {};
24578
+ const o = JSON.parse((0, import_node_fs38.readFileSync)(file, "utf-8")) ?? {};
24452
24579
  const spent = typeof o.spent === "number" ? o.spent : 0;
24453
24580
  const raw = o.active;
24454
24581
  let active = null;
@@ -24472,8 +24599,8 @@ function readIgnoreState(sessionId) {
24472
24599
  }
24473
24600
  function writeIgnoreState(state, sessionId) {
24474
24601
  try {
24475
- (0, import_node_fs37.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
24476
- (0, import_node_fs37.writeFileSync)(stateFile(sessionId), JSON.stringify({ v: 1, active: state.active, spent: state.spent }));
24602
+ (0, import_node_fs38.mkdirSync)(projectPath(VERITY_DIR), { recursive: true });
24603
+ (0, import_node_fs38.writeFileSync)(stateFile(sessionId), JSON.stringify({ v: 1, active: state.active, spent: state.spent }));
24477
24604
  } catch {
24478
24605
  }
24479
24606
  }
@@ -24856,85 +24983,10 @@ function createRun(opts, globals) {
24856
24983
  }
24857
24984
 
24858
24985
  // src/commands/analyze/index.ts
24859
- var import_node_fs51 = require("node:fs");
24986
+ var import_node_fs52 = require("node:fs");
24860
24987
 
24861
24988
  // src/lib/repo-context.ts
24862
24989
  var import_node_child_process11 = require("node:child_process");
24863
-
24864
- // src/lib/hardened-git.ts
24865
- var import_node_child_process10 = require("node:child_process");
24866
- var HARDENED_CONFIG_ARGS = [
24867
- "-c",
24868
- "core.fsmonitor=false",
24869
- "-c",
24870
- "core.pager=cat",
24871
- "-c",
24872
- "log.showSignature=false"
24873
- ];
24874
- var DIFF_READ_FLAGS = ["--no-ext-diff", "--no-textconv"];
24875
- var DEFAULT_GIT_TIMEOUT_MS = 6e4;
24876
- var DEFAULT_GIT_MAX_BUFFER = 64 * 1024 * 1024;
24877
- function hardenedGitEnv(base = process.env) {
24878
- const env = {};
24879
- for (const [key, value] of Object.entries(base)) {
24880
- if (key.startsWith("GIT_")) continue;
24881
- env[key] = value;
24882
- }
24883
- env.GIT_OPTIONAL_LOCKS = "0";
24884
- env.GIT_TERMINAL_PROMPT = "0";
24885
- return env;
24886
- }
24887
- function hardenedGitArgv(args2) {
24888
- return [...HARDENED_CONFIG_ARGS, ...args2];
24889
- }
24890
- function classifyError(err2) {
24891
- const e = err2;
24892
- const stderr = typeof e?.stderr === "string" ? e.stderr : e?.stderr ? e.stderr.toString("utf-8") : "";
24893
- if (e?.code === "ETIMEDOUT" || e?.killed && e?.signal === "SIGTERM") return { ok: false, error: "timeout", stderr };
24894
- if (e?.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER") return { ok: false, error: "too_large", stderr };
24895
- return { ok: false, error: "failed", stderr };
24896
- }
24897
- function runGitSync(cwd, args2, opts = {}) {
24898
- try {
24899
- const stdout = (0, import_node_child_process10.execFileSync)("git", hardenedGitArgv(args2), {
24900
- cwd,
24901
- env: hardenedGitEnv(),
24902
- encoding: "utf-8",
24903
- stdio: ["ignore", "pipe", "pipe"],
24904
- timeout: opts.timeoutMs ?? DEFAULT_GIT_TIMEOUT_MS,
24905
- maxBuffer: opts.maxBuffer ?? DEFAULT_GIT_MAX_BUFFER
24906
- });
24907
- return { ok: true, stdout };
24908
- } catch (err2) {
24909
- return classifyError(err2);
24910
- }
24911
- }
24912
- function runGit(cwd, args2, opts = {}) {
24913
- return new Promise((resolvePromise) => {
24914
- (0, import_node_child_process10.execFile)(
24915
- "git",
24916
- hardenedGitArgv(args2),
24917
- {
24918
- cwd,
24919
- env: hardenedGitEnv(),
24920
- encoding: "utf-8",
24921
- timeout: opts.timeoutMs ?? DEFAULT_GIT_TIMEOUT_MS,
24922
- maxBuffer: opts.maxBuffer ?? DEFAULT_GIT_MAX_BUFFER
24923
- },
24924
- (err2, stdout, stderr) => {
24925
- if (err2) {
24926
- const e = err2;
24927
- e.stderr = stderr;
24928
- resolvePromise(classifyError(e));
24929
- return;
24930
- }
24931
- resolvePromise({ ok: true, stdout });
24932
- }
24933
- );
24934
- });
24935
- }
24936
-
24937
- // src/lib/repo-context.ts
24938
24990
  var import_node_os5 = require("node:os");
24939
24991
  function rgInvocations(env = process.env) {
24940
24992
  const out2 = [{ cmd: "rg" }];
@@ -25895,10 +25947,10 @@ function installRunEvidence(run4) {
25895
25947
  }
25896
25948
 
25897
25949
  // src/lib/git-frame.ts
25898
- var import_node_fs38 = require("node:fs");
25950
+ var import_node_fs39 = require("node:fs");
25899
25951
  var import_node_os6 = require("node:os");
25900
- var import_node_path29 = require("node:path");
25901
25952
  var import_node_path30 = require("node:path");
25953
+ var import_node_path31 = require("node:path");
25902
25954
  var VALUE_TOKEN = `(?:'[^']*'|"[^"]*"|\\S+)`;
25903
25955
  var GIT_GLOBAL_OPTS = `(?:\\s+(?:-[Cc]\\s+${VALUE_TOKEN}|--?[\\w-]+(?:=\\S+)?))*`;
25904
25956
  var COMMIT_HEAD = `git${GIT_GLOBAL_OPTS}\\s+commit(?![\\w-])`;
@@ -25985,8 +26037,8 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
25985
26037
  if (SHELL_DYNAMIC.test(raw) || raw === "-") {
25986
26038
  return { dir: null, named: true, unresolvable: `cd target not statically resolvable: ${raw}` };
25987
26039
  }
25988
- const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path30.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
25989
- dir = (0, import_node_path29.isAbsolute)(expanded) ? expanded : (0, import_node_path29.resolve)(dir, expanded);
26040
+ const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path31.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
26041
+ dir = (0, import_node_path30.isAbsolute)(expanded) ? expanded : (0, import_node_path30.resolve)(dir, expanded);
25990
26042
  }
25991
26043
  const seg = segments[segmentIndex];
25992
26044
  const overrideMatch = /--(?:git-dir|work-tree)(?:=|\s)|\bGIT_(?:DIR|WORK_TREE|INDEX_FILE)=/.exec(seg);
@@ -26004,8 +26056,8 @@ function extractCommandTarget(command, segmentIndex, baseDir) {
26004
26056
  if (SHELL_DYNAMIC.test(raw)) {
26005
26057
  return { dir: null, named: true, unresolvable: `-C target not statically resolvable: ${raw}` };
26006
26058
  }
26007
- const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path30.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
26008
- dir = (0, import_node_path29.isAbsolute)(expanded) ? expanded : (0, import_node_path29.resolve)(dir, expanded);
26059
+ const expanded = raw === "~" ? (0, import_node_os6.homedir)() : raw.startsWith("~/") ? (0, import_node_path31.join)((0, import_node_os6.homedir)(), raw.slice(2)) : raw;
26060
+ dir = (0, import_node_path30.isAbsolute)(expanded) ? expanded : (0, import_node_path30.resolve)(dir, expanded);
26009
26061
  }
26010
26062
  }
26011
26063
  return { dir, named, unresolvable: null };
@@ -26065,14 +26117,14 @@ function gitAt(dir, args2) {
26065
26117
  }
26066
26118
  function realpathOr2(p) {
26067
26119
  try {
26068
- return import_node_fs38.realpathSync.native(p);
26120
+ return import_node_fs39.realpathSync.native(p);
26069
26121
  } catch {
26070
- return (0, import_node_path29.resolve)(p);
26122
+ return (0, import_node_path30.resolve)(p);
26071
26123
  }
26072
26124
  }
26073
26125
  function resolveFrame(input) {
26074
26126
  const found = findMomentSegment(input.command, input.on);
26075
- const hookDirUsable = !!input.hookCwd && (0, import_node_fs38.existsSync)(input.hookCwd);
26127
+ const hookDirUsable = !!input.hookCwd && (0, import_node_fs39.existsSync)(input.hookCwd);
26076
26128
  const baseDir = hookDirUsable ? input.hookCwd : process.cwd();
26077
26129
  let anchor = hookDirUsable ? "hook-cwd" : "process-cwd";
26078
26130
  const refuse = (refusal) => ({
@@ -26095,7 +26147,7 @@ function resolveFrame(input) {
26095
26147
  if (dirs.size > 1) return refuse(`target:multiple ${found.moment} targets in one command`);
26096
26148
  const targetDir = dirs.size === 1 ? [...dirs][0] : baseDir;
26097
26149
  if (targetDir !== baseDir) {
26098
- if (!(0, import_node_fs38.existsSync)(targetDir)) return refuse(`target:directory does not exist: ${targetDir}`);
26150
+ if (!(0, import_node_fs39.existsSync)(targetDir)) return refuse(`target:directory does not exist: ${targetDir}`);
26099
26151
  dir = targetDir;
26100
26152
  }
26101
26153
  }
@@ -26106,7 +26158,7 @@ function resolveFrame(input) {
26106
26158
  const gitDirRaw = gitAt(dir, ["rev-parse", "--absolute-git-dir"]);
26107
26159
  const commonRaw = gitAt(dir, ["rev-parse", "--git-common-dir"]);
26108
26160
  const gitDir = gitDirRaw ? realpathOr2(gitDirRaw) : null;
26109
- const commonDir = commonRaw ? realpathOr2((0, import_node_path29.isAbsolute)(commonRaw) ? commonRaw : (0, import_node_path29.resolve)(dir, commonRaw)) : null;
26161
+ const commonDir = commonRaw ? realpathOr2((0, import_node_path30.isAbsolute)(commonRaw) ? commonRaw : (0, import_node_path30.resolve)(dir, commonRaw)) : null;
26110
26162
  const branchRaw = gitAt(dir, ["rev-parse", "--abbrev-ref", "HEAD"]);
26111
26163
  return {
26112
26164
  moment: found?.moment ?? null,
@@ -26281,8 +26333,8 @@ function stagedRange(frame, command) {
26281
26333
  if (plan.kind === "unpredictable") {
26282
26334
  return { kind: "staged", base: "HEAD", head: "INDEX", via: "staged-in-command", refusal: plan.reason };
26283
26335
  }
26284
- const mergeHead = frame.gitDir ? (0, import_node_path30.join)(frame.gitDir, "MERGE_HEAD") : null;
26285
- if (mergeHead && (0, import_node_fs38.existsSync)(mergeHead)) {
26336
+ const mergeHead = frame.gitDir ? (0, import_node_path31.join)(frame.gitDir, "MERGE_HEAD") : null;
26337
+ if (mergeHead && (0, import_node_fs39.existsSync)(mergeHead)) {
26286
26338
  const vsHead = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "HEAD"]).split("\n").filter(Boolean));
26287
26339
  const vsMerge = new Set(frameGit(frame, ["diff", "--cached", "--name-only", "MERGE_HEAD"]).split("\n").filter(Boolean));
26288
26340
  const resolutions = new Set([...vsHead].filter((f) => vsMerge.has(f) && !isVerityOwnedPath(f)));
@@ -26416,7 +26468,7 @@ function truthy(v) {
26416
26468
  }
26417
26469
 
26418
26470
  // src/lib/transcript.ts
26419
- var import_node_fs39 = require("node:fs");
26471
+ var import_node_fs40 = require("node:fs");
26420
26472
  var MAX_READ_BYTES = 256 * 1024;
26421
26473
  var SMALL_FILE_BYTES = 64 * 1024;
26422
26474
  var MAX_FILES_LIST = 20;
@@ -26443,7 +26495,7 @@ async function extractActionSummary(transcriptPath) {
26443
26495
  function readTurnLines(transcriptPath) {
26444
26496
  let size;
26445
26497
  try {
26446
- size = (0, import_node_fs39.statSync)(transcriptPath).size;
26498
+ size = (0, import_node_fs40.statSync)(transcriptPath).size;
26447
26499
  } catch {
26448
26500
  return null;
26449
26501
  }
@@ -26451,7 +26503,7 @@ function readTurnLines(transcriptPath) {
26451
26503
  let raw;
26452
26504
  let windowed = false;
26453
26505
  if (size <= SMALL_FILE_BYTES) {
26454
- raw = (0, import_node_fs39.readFileSync)(transcriptPath, "utf-8");
26506
+ raw = (0, import_node_fs40.readFileSync)(transcriptPath, "utf-8");
26455
26507
  } else {
26456
26508
  windowed = true;
26457
26509
  const buf = Buffer.alloc(Math.min(MAX_READ_BYTES, size));
@@ -27021,7 +27073,7 @@ function channelSilence(input) {
27021
27073
  // src/lib/cli-version.ts
27022
27074
  function cliVersion() {
27023
27075
  try {
27024
- return true ? "0.34.0-experimental.007b74f" : "dev";
27076
+ return true ? "0.34.0-experimental.37a6dcf" : "dev";
27025
27077
  } catch {
27026
27078
  return "dev";
27027
27079
  }
@@ -27062,7 +27114,7 @@ async function sendSkipBeacon(ctx, reason) {
27062
27114
 
27063
27115
  // src/lib/static-analysis.ts
27064
27116
  var import_node_child_process12 = require("node:child_process");
27065
- var import_node_fs40 = require("node:fs");
27117
+ var import_node_fs41 = require("node:fs");
27066
27118
  var SEVERITY_ORDER = {
27067
27119
  Error: 0,
27068
27120
  Critical: 0,
@@ -27118,7 +27170,7 @@ function runCodacyAnalysis(files) {
27118
27170
  if (files.length === 0) return empty;
27119
27171
  const existingFiles = files.filter((f) => {
27120
27172
  try {
27121
- return (0, import_node_fs40.existsSync)(f);
27173
+ return (0, import_node_fs41.existsSync)(f);
27122
27174
  } catch {
27123
27175
  return false;
27124
27176
  }
@@ -27387,8 +27439,8 @@ async function scope(run4) {
27387
27439
  }
27388
27440
 
27389
27441
  // src/lib/specs.ts
27390
- var import_node_fs41 = require("node:fs");
27391
- var import_node_path31 = require("node:path");
27442
+ var import_node_fs42 = require("node:fs");
27443
+ var import_node_path32 = require("node:path");
27392
27444
  var SPEC_CANDIDATES = [
27393
27445
  "CLAUDE.md",
27394
27446
  "AGENTS.md",
@@ -27410,7 +27462,7 @@ var UNCONSULTED_TOTAL_BYTES = 30720;
27410
27462
  function readSpecFiles(specsOpt, root) {
27411
27463
  const out2 = [];
27412
27464
  for (const raw of specsOpt.split(",").map((f) => f.trim()).filter(Boolean)) {
27413
- const candidate = (0, import_node_path31.isAbsolute)(raw) ? (0, import_node_path31.relative)(root, raw) : raw;
27465
+ const candidate = (0, import_node_path32.isAbsolute)(raw) ? (0, import_node_path32.relative)(root, raw) : raw;
27414
27466
  const content = readFileInside(root, candidate, MAX_EXPLICIT_SPEC_FILE_BYTES);
27415
27467
  if (content === null) continue;
27416
27468
  out2.push({ path: raw, content });
@@ -27429,7 +27481,7 @@ function discoverSpecs(consulted = []) {
27429
27481
  const totalCap = relevant ? MAX_TOTAL_SPEC_BYTES : UNCONSULTED_TOTAL_BYTES;
27430
27482
  if (totalBytes >= totalCap) return false;
27431
27483
  if (seen.has(specPath)) return true;
27432
- if (!(0, import_node_fs41.existsSync)(specPath)) return true;
27484
+ if (!(0, import_node_fs42.existsSync)(specPath)) return true;
27433
27485
  seen.add(specPath);
27434
27486
  const remaining = totalCap - totalBytes;
27435
27487
  const fileCap = relevant ? MAX_SPEC_FILE_BYTES : UNCONSULTED_FILE_BYTES;
@@ -27452,7 +27504,7 @@ function discoverSpecs(consulted = []) {
27452
27504
  if (!addSpec(candidate)) break;
27453
27505
  }
27454
27506
  for (const dir of ["spec", "docs"]) {
27455
- if (!(0, import_node_fs41.existsSync)(dir)) continue;
27507
+ if (!(0, import_node_fs42.existsSync)(dir)) continue;
27456
27508
  try {
27457
27509
  const mdFiles = findMdFiles(dir, 2).sort();
27458
27510
  for (const mdFile of mdFiles) {
@@ -27467,9 +27519,9 @@ function findMdFiles(dir, maxDepth, depth = 0) {
27467
27519
  if (depth >= maxDepth) return [];
27468
27520
  const result = [];
27469
27521
  try {
27470
- const entries = (0, import_node_fs41.readdirSync)(dir, { withFileTypes: true });
27522
+ const entries = (0, import_node_fs42.readdirSync)(dir, { withFileTypes: true });
27471
27523
  for (const entry of entries) {
27472
- const fullPath = (0, import_node_path31.join)(dir, entry.name);
27524
+ const fullPath = (0, import_node_path32.join)(dir, entry.name);
27473
27525
  if (entry.isFile() && entry.name.endsWith(".md")) {
27474
27526
  result.push(fullPath);
27475
27527
  } else if (entry.isDirectory() && depth < maxDepth - 1) {
@@ -27482,25 +27534,25 @@ function findMdFiles(dir, maxDepth, depth = 0) {
27482
27534
  }
27483
27535
  function discoverPlans() {
27484
27536
  const home = process.env.HOME ?? "";
27485
- const homePlansDir = (0, import_node_path31.join)(home, ".claude", "plans");
27537
+ const homePlansDir = (0, import_node_path32.join)(home, ".claude", "plans");
27486
27538
  const sources = [];
27487
27539
  if (isRealDirectoryChain(process.cwd(), [".claude", "plans"])) {
27488
- sources.push({ root: process.cwd(), prefix: (0, import_node_path31.join)(".claude", "plans") });
27540
+ sources.push({ root: process.cwd(), prefix: (0, import_node_path32.join)(".claude", "plans") });
27489
27541
  }
27490
- if (home && (0, import_node_fs41.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
27542
+ if (home && (0, import_node_fs42.existsSync)(homePlansDir)) sources.push({ root: homePlansDir, prefix: "" });
27491
27543
  const candidates2 = [];
27492
27544
  const seen = /* @__PURE__ */ new Set();
27493
27545
  for (const source2 of sources) {
27494
27546
  let names2;
27495
27547
  try {
27496
- names2 = (0, import_node_fs41.readdirSync)(source2.prefix ? (0, import_node_path31.join)(source2.root, source2.prefix) : source2.root);
27548
+ names2 = (0, import_node_fs42.readdirSync)(source2.prefix ? (0, import_node_path32.join)(source2.root, source2.prefix) : source2.root);
27497
27549
  } catch {
27498
27550
  continue;
27499
27551
  }
27500
27552
  for (const f of names2) {
27501
27553
  if (!f.endsWith(".md") || seen.has(f)) continue;
27502
27554
  seen.add(f);
27503
- const relPath = source2.prefix ? (0, import_node_path31.join)(source2.prefix, f) : f;
27555
+ const relPath = source2.prefix ? (0, import_node_path32.join)(source2.prefix, f) : f;
27504
27556
  const stat3 = statRegularInRoot(source2.root, relPath);
27505
27557
  if (!stat3.ok) continue;
27506
27558
  candidates2.push({ name: f, root: source2.root, relPath, mtime: stat3.mtimeMs, size: stat3.size });
@@ -27518,9 +27570,9 @@ function discoverPlans() {
27518
27570
  function isRealDirectoryChain(root, parts2) {
27519
27571
  let current = root;
27520
27572
  for (const part of parts2) {
27521
- current = (0, import_node_path31.join)(current, part);
27573
+ current = (0, import_node_path32.join)(current, part);
27522
27574
  try {
27523
- if (!(0, import_node_fs41.lstatSync)(current).isDirectory()) return false;
27575
+ if (!(0, import_node_fs42.lstatSync)(current).isDirectory()) return false;
27524
27576
  } catch {
27525
27577
  return false;
27526
27578
  }
@@ -27535,7 +27587,7 @@ function discoverGuardDocs(rangeFiles2) {
27535
27587
  if (result.length >= MAX_SPEC_FILES) break;
27536
27588
  if (!GUARD_DOC_EXT.test(path)) continue;
27537
27589
  if (path.startsWith("/") || path.includes("..")) continue;
27538
- if (!(0, import_node_fs41.existsSync)(path)) continue;
27590
+ if (!(0, import_node_fs42.existsSync)(path)) continue;
27539
27591
  const opened = openRegularInRoot(process.cwd(), path);
27540
27592
  if (!opened.ok) continue;
27541
27593
  if (opened.size > MAX_PLAN_FILE_BYTES || totalBytes + opened.size > MAX_TOTAL_SPEC_BYTES) {
@@ -27721,8 +27773,8 @@ async function mode(run4) {
27721
27773
  }
27722
27774
 
27723
27775
  // src/lib/fold.ts
27724
- var import_node_fs42 = require("node:fs");
27725
- var import_node_path32 = require("node:path");
27776
+ var import_node_fs43 = require("node:fs");
27777
+ var import_node_path33 = require("node:path");
27726
27778
  var KNOWN_RECORD_TYPES = /* @__PURE__ */ new Set([
27727
27779
  "user",
27728
27780
  "assistant",
@@ -27859,7 +27911,7 @@ function candidateRoots(repoRoot2) {
27859
27911
  const norm2 = repoRoot2.replace(/\\/g, "/").replace(/\/+$/, "");
27860
27912
  const out2 = [norm2];
27861
27913
  try {
27862
- const real = import_node_fs42.realpathSync.native(norm2).replace(/\\/g, "/").replace(/\/+$/, "");
27914
+ const real = import_node_fs43.realpathSync.native(norm2).replace(/\\/g, "/").replace(/\/+$/, "");
27863
27915
  if (real !== norm2) out2.push(real);
27864
27916
  } catch {
27865
27917
  }
@@ -27947,31 +27999,31 @@ function fold(transcriptPath, opts = {}) {
27947
27999
  }
27948
28000
  };
27949
28001
  try {
27950
- if (!(0, import_node_fs42.existsSync)(transcriptPath)) return result;
27951
- ingest((0, import_node_fs42.readFileSync)(transcriptPath, "utf8"), "agent");
28002
+ if (!(0, import_node_fs43.existsSync)(transcriptPath)) return result;
28003
+ ingest((0, import_node_fs43.readFileSync)(transcriptPath, "utf8"), "agent");
27952
28004
  result.coverage.complete = true;
27953
28005
  } catch {
27954
28006
  return result;
27955
28007
  }
27956
28008
  try {
27957
- const sidecarDir = (0, import_node_path32.join)(
27958
- (0, import_node_path32.dirname)(transcriptPath),
27959
- (0, import_node_path32.basename)(transcriptPath).replace(/\.jsonl$/, ""),
28009
+ const sidecarDir = (0, import_node_path33.join)(
28010
+ (0, import_node_path33.dirname)(transcriptPath),
28011
+ (0, import_node_path33.basename)(transcriptPath).replace(/\.jsonl$/, ""),
27960
28012
  "subagents"
27961
28013
  );
27962
- if ((0, import_node_fs42.existsSync)(sidecarDir)) {
28014
+ if ((0, import_node_fs43.existsSync)(sidecarDir)) {
27963
28015
  const maxFiles = opts.maxSidecars ?? 200;
27964
28016
  const maxBytes = opts.maxSidecarBytes ?? 16 * 1024 * 1024;
27965
28017
  const found = [];
27966
28018
  const walk2 = (d, depth) => {
27967
28019
  if (depth > 4) return;
27968
- for (const e of (0, import_node_fs42.readdirSync)(d, { withFileTypes: true })) {
27969
- const p = (0, import_node_path32.join)(d, e.name);
28020
+ for (const e of (0, import_node_fs43.readdirSync)(d, { withFileTypes: true })) {
28021
+ const p = (0, import_node_path33.join)(d, e.name);
27970
28022
  if (e.isDirectory()) {
27971
28023
  walk2(p, depth + 1);
27972
28024
  } else if (e.name.startsWith("agent-") && e.name.endsWith(".jsonl")) {
27973
28025
  try {
27974
- const st = (0, import_node_fs42.statSync)(p);
28026
+ const st = (0, import_node_fs43.statSync)(p);
27975
28027
  found.push({ path: p, size: st.size, mtimeMs: st.mtimeMs });
27976
28028
  } catch {
27977
28029
  result.coverage.malformed++;
@@ -27988,7 +28040,7 @@ function fold(transcriptPath, opts = {}) {
27988
28040
  continue;
27989
28041
  }
27990
28042
  try {
27991
- ingest((0, import_node_fs42.readFileSync)(f.path, "utf8"), "subagent");
28043
+ ingest((0, import_node_fs43.readFileSync)(f.path, "utf8"), "subagent");
27992
28044
  bytes += f.size;
27993
28045
  result.coverage.subagentFiles++;
27994
28046
  } catch {
@@ -28023,7 +28075,7 @@ function fold(transcriptPath, opts = {}) {
28023
28075
  }
28024
28076
  function classifyUnobserved(path) {
28025
28077
  try {
28026
- const st = (0, import_node_fs42.statSync)(path);
28078
+ const st = (0, import_node_fs43.statSync)(path);
28027
28079
  if (!st.isFile()) return "unreadable";
28028
28080
  } catch {
28029
28081
  return "unreadable";
@@ -28338,20 +28390,20 @@ async function evidence(run4) {
28338
28390
  }
28339
28391
 
28340
28392
  // src/lib/cache-cleanup.ts
28341
- var import_node_fs43 = require("node:fs");
28342
- var import_node_path33 = require("node:path");
28393
+ var import_node_fs44 = require("node:fs");
28394
+ var import_node_path34 = require("node:path");
28343
28395
  var CACHE_TTL_DAYS = 7;
28344
28396
  function pruneStaleCache() {
28345
28397
  try {
28346
28398
  const dir = projectPath(CACHE_DIR);
28347
28399
  const cutoff = Date.now() - CACHE_TTL_DAYS * 24 * 3600 * 1e3;
28348
- for (const entry of (0, import_node_fs43.readdirSync)(dir)) {
28400
+ for (const entry of (0, import_node_fs44.readdirSync)(dir)) {
28349
28401
  if (!entry.startsWith("pending-")) continue;
28350
- const path = (0, import_node_path33.join)(dir, entry);
28402
+ const path = (0, import_node_path34.join)(dir, entry);
28351
28403
  try {
28352
- const stat3 = (0, import_node_fs43.statSync)(path);
28404
+ const stat3 = (0, import_node_fs44.statSync)(path);
28353
28405
  if (stat3.mtimeMs < cutoff) {
28354
- (0, import_node_fs43.unlinkSync)(path);
28406
+ (0, import_node_fs44.unlinkSync)(path);
28355
28407
  logEvent("cache_entry_pruned", {
28356
28408
  path: entry,
28357
28409
  age_days: Math.round((Date.now() - stat3.mtimeMs) / 864e5)
@@ -28365,7 +28417,7 @@ function pruneStaleCache() {
28365
28417
  }
28366
28418
 
28367
28419
  // src/lib/context-files.ts
28368
- var import_node_fs44 = require("node:fs");
28420
+ var import_node_fs45 = require("node:fs");
28369
28421
  var import_node_os7 = require("node:os");
28370
28422
  var MAX_CONTEXT_FILES = 10;
28371
28423
  var MAX_CONTEXT_FILE_BYTES = 10240;
@@ -28423,7 +28475,7 @@ function gatherContextFiles(contextPaths, deltaFiles, opts) {
28423
28475
  continue;
28424
28476
  }
28425
28477
  try {
28426
- const content = (0, import_node_fs44.readFileSync)(safePath, "utf8");
28478
+ const content = (0, import_node_fs45.readFileSync)(safePath, "utf8");
28427
28479
  const bytes = Buffer.byteLength(content);
28428
28480
  if (bytes > MAX_CONTEXT_FILE_BYTES) {
28429
28481
  logEvent("context_file_skipped", { path: filePath, reason: "too_large", bytes });
@@ -28581,8 +28633,8 @@ function languageOf2(path) {
28581
28633
  }
28582
28634
 
28583
28635
  // src/lib/code/runtime.ts
28584
- var import_node_fs45 = require("node:fs");
28585
- var import_node_path34 = require("node:path");
28636
+ var import_node_fs46 = require("node:fs");
28637
+ var import_node_path35 = require("node:path");
28586
28638
  var import_web_tree_sitter2 = __toESM2(require_web_tree_sitter2());
28587
28639
 
28588
28640
  // src/lib/code/grammars.json
@@ -28642,18 +28694,18 @@ var grammars_default = {
28642
28694
  var MAX_PARSE_BYTES = 512 * 1024;
28643
28695
  function grammarCandidates(file, pkg, env = process.env) {
28644
28696
  return [
28645
- ...env.VERITY_GRAMMAR_DIR ? [(0, import_node_path34.join)(env.VERITY_GRAMMAR_DIR, file)] : [],
28646
- (0, import_node_path34.join)(__dirname, "..", "data", "grammars", file),
28697
+ ...env.VERITY_GRAMMAR_DIR ? [(0, import_node_path35.join)(env.VERITY_GRAMMAR_DIR, file)] : [],
28698
+ (0, import_node_path35.join)(__dirname, "..", "data", "grammars", file),
28647
28699
  // bundled: cli/bin/ → cli/data/grammars/
28648
- (0, import_node_path34.join)(__dirname, "..", "..", "..", "data", "grammars", file),
28700
+ (0, import_node_path35.join)(__dirname, "..", "..", "..", "data", "grammars", file),
28649
28701
  // tsx: cli/src/lib/code/ → cli/data/grammars/
28650
- (0, import_node_path34.join)(__dirname, "..", "..", "..", "node_modules", pkg, file)
28702
+ (0, import_node_path35.join)(__dirname, "..", "..", "..", "node_modules", pkg, file)
28651
28703
  // tsx, before a build: the pinned devDependency
28652
28704
  ];
28653
28705
  }
28654
28706
  function locateGrammar(id, env = process.env) {
28655
28707
  const g = grammars_default[id];
28656
- return grammarCandidates(g.file, g.package, env).find((p) => (0, import_node_fs45.existsSync)(p)) ?? null;
28708
+ return grammarCandidates(g.file, g.package, env).find((p) => (0, import_node_fs46.existsSync)(p)) ?? null;
28657
28709
  }
28658
28710
  var loading = null;
28659
28711
  function loadRuntime(env = process.env) {
@@ -30982,8 +31034,8 @@ async function repoContext(run4) {
30982
31034
 
30983
31035
  // src/lib/seed-runner.ts
30984
31036
  var import_promises15 = require("node:fs/promises");
30985
- var import_node_fs46 = require("node:fs");
30986
- var import_node_path35 = require("node:path");
31037
+ var import_node_fs47 = require("node:fs");
31038
+ var import_node_path36 = require("node:path");
30987
31039
  var import_yaml4 = __toESM2(require_dist());
30988
31040
 
30989
31041
  // src/lib/seed.ts
@@ -31206,8 +31258,8 @@ function normalizeTitle(title) {
31206
31258
  async function localSeedTitles(memoryDir3 = MEMORY_DIR) {
31207
31259
  const titles = /* @__PURE__ */ new Set();
31208
31260
  for (const dir of NODE_DIRS) {
31209
- const full = (0, import_node_path35.join)(memoryDir3, dir);
31210
- if (!(0, import_node_fs46.existsSync)(full)) continue;
31261
+ const full = (0, import_node_path36.join)(memoryDir3, dir);
31262
+ if (!(0, import_node_fs47.existsSync)(full)) continue;
31211
31263
  let files;
31212
31264
  try {
31213
31265
  files = await (0, import_promises15.readdir)(full);
@@ -31218,7 +31270,7 @@ async function localSeedTitles(memoryDir3 = MEMORY_DIR) {
31218
31270
  if (!file.endsWith(".md")) continue;
31219
31271
  let content;
31220
31272
  try {
31221
- content = await (0, import_promises15.readFile)((0, import_node_path35.join)(full, file), "utf-8");
31273
+ content = await (0, import_promises15.readFile)((0, import_node_path36.join)(full, file), "utf-8");
31222
31274
  } catch {
31223
31275
  continue;
31224
31276
  }
@@ -31289,7 +31341,7 @@ function renderNodeMarkdown(candidate, nodeId, createdAt) {
31289
31341
  return fm;
31290
31342
  }
31291
31343
  async function runSeed(opts) {
31292
- if (!(0, import_node_fs46.existsSync)(STANDARD_FILE)) {
31344
+ if (!(0, import_node_fs47.existsSync)(STANDARD_FILE)) {
31293
31345
  return { created: 0, existing: 0, failed: 0, skipped: "no_standard", candidates: [] };
31294
31346
  }
31295
31347
  let standardDoc;
@@ -31301,7 +31353,7 @@ async function runSeed(opts) {
31301
31353
  }
31302
31354
  const knowledgeSpec = standardDoc.knowledge_spec ?? {};
31303
31355
  let readmeContent;
31304
- if ((0, import_node_fs46.existsSync)("README.md")) {
31356
+ if ((0, import_node_fs47.existsSync)("README.md")) {
31305
31357
  try {
31306
31358
  readmeContent = await (0, import_promises15.readFile)("README.md", "utf-8");
31307
31359
  } catch {
@@ -31309,7 +31361,7 @@ async function runSeed(opts) {
31309
31361
  }
31310
31362
  let claudeMdContent;
31311
31363
  for (const p of ["CLAUDE.md", ".claude/CLAUDE.md"]) {
31312
- if ((0, import_node_fs46.existsSync)(p)) {
31364
+ if ((0, import_node_fs47.existsSync)(p)) {
31313
31365
  try {
31314
31366
  claudeMdContent = await (0, import_promises15.readFile)(p, "utf-8");
31315
31367
  break;
@@ -31389,13 +31441,13 @@ async function runSeed(opts) {
31389
31441
  continue;
31390
31442
  }
31391
31443
  const deduplicated = res.data.deduplicated === true;
31392
- if (deduplicated && (0, import_node_fs46.existsSync)(targetPath)) {
31444
+ if (deduplicated && (0, import_node_fs47.existsSync)(targetPath)) {
31393
31445
  existing++;
31394
31446
  continue;
31395
31447
  }
31396
31448
  const content = typeof res.data.content === "string" && res.data.content.length > 0 ? res.data.content : renderNodeMarkdown(c, nodeId, createdAt);
31397
31449
  try {
31398
- await (0, import_promises15.mkdir)((0, import_node_path35.dirname)(targetPath), { recursive: true });
31450
+ await (0, import_promises15.mkdir)((0, import_node_path36.dirname)(targetPath), { recursive: true });
31399
31451
  await (0, import_promises15.writeFile)(targetPath, content);
31400
31452
  if (deduplicated) existing++;
31401
31453
  else {
@@ -31411,8 +31463,8 @@ async function runSeed(opts) {
31411
31463
  }
31412
31464
 
31413
31465
  // src/commands/analyze/phases/08-memory-manifest.ts
31414
- var import_node_fs47 = require("node:fs");
31415
- var import_node_path36 = require("node:path");
31466
+ var import_node_fs48 = require("node:fs");
31467
+ var import_node_path37 = require("node:path");
31416
31468
  async function memoryManifest(run4) {
31417
31469
  const { globals } = run4;
31418
31470
  const { serviceUrl, token } = run4;
@@ -31422,9 +31474,9 @@ async function memoryManifest(run4) {
31422
31474
  let autoSeedNotice = null;
31423
31475
  try {
31424
31476
  await ensureMemoryDir();
31425
- const seedMarker = (0, import_node_path36.join)(VERITY_DIR, ".seeded");
31426
- const hasStandard = (0, import_node_fs47.existsSync)(STANDARD_FILE);
31427
- const alreadyTried = (0, import_node_fs47.existsSync)(seedMarker);
31477
+ const seedMarker = (0, import_node_path37.join)(VERITY_DIR, ".seeded");
31478
+ const hasStandard = (0, import_node_fs48.existsSync)(STANDARD_FILE);
31479
+ const alreadyTried = (0, import_node_fs48.existsSync)(seedMarker);
31428
31480
  if (hasStandard && !alreadyTried) {
31429
31481
  const preManifest = await buildManifest();
31430
31482
  if (preManifest.nodes.length === 0) {
@@ -31437,7 +31489,7 @@ async function memoryManifest(run4) {
31437
31489
  dryRun: false
31438
31490
  });
31439
31491
  if (seedResult.created > 0 || seedResult.existing > 0) {
31440
- (0, import_node_fs47.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} created=${seedResult.created} existing=${seedResult.existing}
31492
+ (0, import_node_fs48.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} created=${seedResult.created} existing=${seedResult.existing}
31441
31493
  `);
31442
31494
  if (seedResult.created > 0) {
31443
31495
  autoSeedNotice = `Seeded ${seedResult.created} knowledge node(s) from your existing Standard (one-time).`;
@@ -31448,7 +31500,7 @@ async function memoryManifest(run4) {
31448
31500
  failed: seedResult.failed
31449
31501
  });
31450
31502
  } else if (seedResult.skipped === "already_seeded") {
31451
- (0, import_node_fs47.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} skipped=already_seeded
31503
+ (0, import_node_fs48.writeFileSync)(seedMarker, `${(/* @__PURE__ */ new Date()).toISOString()} skipped=already_seeded
31452
31504
  `);
31453
31505
  } else {
31454
31506
  logEvent("auto_seed_noop", {
@@ -31543,7 +31595,7 @@ function computeIncrement(reviewedPaths, hashOf, priorAuthored) {
31543
31595
  }
31544
31596
 
31545
31597
  // src/commands/analyze/phases/10-working-memory.ts
31546
- var import_node_path37 = require("node:path");
31598
+ var import_node_path38 = require("node:path");
31547
31599
  async function workingMemory(run4) {
31548
31600
  const { opts } = run4;
31549
31601
  const { allForReview, baseline, conversation, foldResult, sessionId, token, transcriptPath } = run4;
@@ -31555,7 +31607,7 @@ async function workingMemory(run4) {
31555
31607
  const priorState = foldForMarks(memorySession.d);
31556
31608
  incrementReport = computeIncrement(
31557
31609
  allForReview,
31558
- (p) => fileHash((0, import_node_path37.join)(repoRoot(), p)),
31610
+ (p) => fileHash((0, import_node_path38.join)(repoRoot(), p)),
31559
31611
  priorState.authored_all.map((a) => ({
31560
31612
  path: a.path,
31561
31613
  hash_at_last_verdict: a.hash_at_last_verdict
@@ -31637,7 +31689,7 @@ async function workingMemory(run4) {
31637
31689
  }
31638
31690
 
31639
31691
  // src/lib/note-budget.ts
31640
- var import_node_fs48 = require("node:fs");
31692
+ var import_node_fs49 = require("node:fs");
31641
31693
  var ADVISORY_BUDGET = { PASS: 1, WARN: 2 };
31642
31694
  var EPISODE_STALE_SECONDS = 30 * 60;
31643
31695
  var FRESH = { delivered: 0, tasksCompleted: 0, ts: 0 };
@@ -31659,9 +31711,9 @@ function advisoryBudgetSpent(episode, rawDecision) {
31659
31711
  }
31660
31712
  function readAdvisoryEpisode(sessionId) {
31661
31713
  const file = scopedFile(ADVISORY_EPISODE_FILE, sessionId);
31662
- if (!(0, import_node_fs48.existsSync)(file)) return null;
31714
+ if (!(0, import_node_fs49.existsSync)(file)) return null;
31663
31715
  try {
31664
- const o = JSON.parse((0, import_node_fs48.readFileSync)(file, "utf-8")) ?? {};
31716
+ const o = JSON.parse((0, import_node_fs49.readFileSync)(file, "utf-8")) ?? {};
31665
31717
  const delivered = typeof o.delivered === "number" ? o.delivered : NaN;
31666
31718
  if (isNaN(delivered)) return null;
31667
31719
  return {
@@ -31675,8 +31727,8 @@ function readAdvisoryEpisode(sessionId) {
31675
31727
  }
31676
31728
  function writeAdvisoryEpisode(episode, sessionId) {
31677
31729
  try {
31678
- (0, import_node_fs48.mkdirSync)(VERITY_DIR, { recursive: true });
31679
- (0, import_node_fs48.writeFileSync)(
31730
+ (0, import_node_fs49.mkdirSync)(VERITY_DIR, { recursive: true });
31731
+ (0, import_node_fs49.writeFileSync)(
31680
31732
  scopedFile(ADVISORY_EPISODE_FILE, sessionId),
31681
31733
  JSON.stringify({ v: 1, ...episode })
31682
31734
  );
@@ -32008,14 +32060,14 @@ async function buildRequest(run4) {
32008
32060
  }
32009
32061
 
32010
32062
  // src/lib/offline.ts
32011
- var import_node_fs49 = require("node:fs");
32063
+ var import_node_fs50 = require("node:fs");
32012
32064
  var import_node_crypto13 = require("node:crypto");
32013
32065
  function cacheRequest(body2) {
32014
32066
  try {
32015
- (0, import_node_fs49.mkdirSync)(CACHE_DIR, { recursive: true });
32067
+ (0, import_node_fs50.mkdirSync)(CACHE_DIR, { recursive: true });
32016
32068
  const suffix = (0, import_node_crypto13.randomBytes)(4).toString("hex");
32017
32069
  const filename = `pending-${Math.floor(Date.now() / 1e3)}-${suffix}.json`;
32018
- (0, import_node_fs49.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body2)));
32070
+ (0, import_node_fs50.writeFileSync)(`${CACHE_DIR}/${filename}`, JSON.stringify(redactRequest(body2)));
32019
32071
  } catch {
32020
32072
  }
32021
32073
  }
@@ -32134,8 +32186,8 @@ async function transmit(run4) {
32134
32186
  }
32135
32187
 
32136
32188
  // src/commands/analyze/phases/13-reconcile.ts
32137
- var import_node_fs50 = require("node:fs");
32138
- var import_node_path38 = require("node:path");
32189
+ var import_node_fs51 = require("node:fs");
32190
+ var import_node_path39 = require("node:path");
32139
32191
  async function reconcile(run4) {
32140
32192
  const { actionSummary, allChanged, analyzable, baseline, baselineSessionId, codeDelta, contentHash, conversation, decision, foldResult, memory: memory2, memorySession, response, reviewable, securityFiles, turnId } = run4;
32141
32193
  const sentPaths = codeDelta.files.map((f) => f.path);
@@ -32164,7 +32216,7 @@ async function reconcile(run4) {
32164
32216
  const st = foldDossier(memorySession.d);
32165
32217
  openElsewhere = openBlockingElsewhere(st.statements, sentPaths, (file, line2) => {
32166
32218
  try {
32167
- const src = (0, import_node_fs50.readFileSync)((0, import_node_path38.join)(repoRoot(), file), "utf8").split("\n");
32219
+ const src = (0, import_node_fs51.readFileSync)((0, import_node_path39.join)(repoRoot(), file), "utf8").split("\n");
32168
32220
  const at = src[line2 - 1];
32169
32221
  return at === void 0 ? null : lineSha(at);
32170
32222
  } catch {
@@ -32986,7 +33038,7 @@ function registerAnalyzeCommand(program2) {
32986
33038
  var tracing = () => process.env.VERITY_TRACE_PHASES === "1";
32987
33039
  async function runAnalyze(opts, globals) {
32988
33040
  if (!verityConfigured()) {
32989
- (0, import_node_fs51.writeSync)(2, '[verity] not set up in this project \u2014 run "verity init" first.\n');
33041
+ (0, import_node_fs52.writeSync)(2, '[verity] not set up in this project \u2014 run "verity init" first.\n');
32990
33042
  process.exit(0);
32991
33043
  }
32992
33044
  const run4 = createRun(opts, globals);
@@ -33007,11 +33059,11 @@ async function runAnalyze(opts, globals) {
33007
33059
  }
33008
33060
 
33009
33061
  // src/commands/baseline.ts
33010
- var import_node_fs53 = require("node:fs");
33062
+ var import_node_fs54 = require("node:fs");
33011
33063
 
33012
33064
  // src/lib/project-skills.ts
33013
- var import_node_fs52 = require("node:fs");
33014
- var import_node_path39 = require("node:path");
33065
+ var import_node_fs53 = require("node:fs");
33066
+ var import_node_path40 = require("node:path");
33015
33067
  var PROJECT_SKILL_NAMES = [
33016
33068
  "verity-setup",
33017
33069
  "verity-analyze",
@@ -33037,14 +33089,14 @@ var LEGACY_SKILL_NAMES = [
33037
33089
  var ALL = [...PROJECT_SKILL_NAMES, ...LEGACY_SKILL_NAMES];
33038
33090
  function staleProjectSkills() {
33039
33091
  const root = projectPath(".claude/skills");
33040
- if (!(0, import_node_fs52.existsSync)(root)) return [];
33041
- return ALL.filter((name2) => (0, import_node_fs52.existsSync)((0, import_node_path39.join)(root, name2)));
33092
+ if (!(0, import_node_fs53.existsSync)(root)) return [];
33093
+ return ALL.filter((name2) => (0, import_node_fs53.existsSync)((0, import_node_path40.join)(root, name2)));
33042
33094
  }
33043
33095
  function removeProjectSkills() {
33044
33096
  const root = projectPath(".claude/skills");
33045
33097
  const removed = [];
33046
33098
  for (const name2 of staleProjectSkills()) {
33047
- (0, import_node_fs52.rmSync)((0, import_node_path39.join)(root, name2), { recursive: true, force: true });
33099
+ (0, import_node_fs53.rmSync)((0, import_node_path40.join)(root, name2), { recursive: true, force: true });
33048
33100
  removed.push(name2);
33049
33101
  }
33050
33102
  return removed;
@@ -33109,13 +33161,13 @@ function registerBaselineCommands(program2) {
33109
33161
  let memoryMsg = null;
33110
33162
  let memoryAgentLine = null;
33111
33163
  const memoryNotice = projectPath(`${VERITY_DIR}/.memory-fence-notice`);
33112
- if (realStart && !(0, import_node_fs53.existsSync)(memoryNotice)) {
33164
+ if (realStart && !(0, import_node_fs54.existsSync)(memoryNotice)) {
33113
33165
  const trackedGraph = memoryOptOut() ? 0 : committedMemoryFiles().length;
33114
33166
  if (trackedGraph > 0) {
33115
33167
  memoryMsg = `Verity: this project commits its knowledge base (${trackedGraph} files under .verity/memory/), so Verity's generated notes show up in every diff and pull request. Run \`verity memory untrack\` to keep them on disk but out of git, or \`verity memory track\` to keep committing them on purpose.`;
33116
33168
  memoryAgentLine = `This project has ${trackedGraph} knowledge-graph files tracked in git under .verity/memory/. As of Verity 0.32.6 the graph is machine-local by default \u2014 it is rebuilt from the service, and committing it puts generated notes in every pull request. If the user wants that stopped, run \`verity memory untrack\` for them: it keeps every file on disk and stages their removal from the index, so they only need to commit \u2014 and their teammates' working copies will vanish on the next pull and re-sync from the service, which is expected. If they would rather keep committing it, \`verity memory track\` records that and nothing will offer again.`;
33117
33169
  try {
33118
- (0, import_node_fs53.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
33170
+ (0, import_node_fs54.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
33119
33171
  } catch {
33120
33172
  }
33121
33173
  }
@@ -33216,7 +33268,7 @@ function hookSource(value) {
33216
33268
  }
33217
33269
 
33218
33270
  // src/commands/review.ts
33219
- var import_node_fs54 = require("node:fs");
33271
+ var import_node_fs55 = require("node:fs");
33220
33272
  function registerReviewCommand(program2) {
33221
33273
  program2.command("review").description("Run on-demand Verity analysis (advisory, never blocks)").requiredOption("--files <paths>", "Comma-separated file list").option("--changed <paths>", "Subset of --files that were modified").option("--intent <text>", "User intent description (max 2000 chars)").option("--specs <paths>", "Comma-separated spec file paths").option("--json", "Output raw JSON response").action(async (opts) => {
33222
33274
  const globals = program2.opts();
@@ -33233,7 +33285,7 @@ async function runReview(opts, globals) {
33233
33285
  const changedFiles = opts.changed ? opts.changed.split(",").map((f) => f.trim()).filter(Boolean) : allFiles;
33234
33286
  const analyzable = filterAnalyzable(allFiles);
33235
33287
  const securityFiles = filterSecurity(allFiles);
33236
- const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs54.existsSync)(f) || resolveFile(f) !== null);
33288
+ const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs55.existsSync)(f) || resolveFile(f) !== null);
33237
33289
  const staticResults = runCodacyAnalysisIfAvailable(scannable);
33238
33290
  const codeDelta = collectCodeDelta(allFiles);
33239
33291
  const tokenResult = await resolveToken(globals.token);
@@ -33299,8 +33351,8 @@ async function runReview(opts, globals) {
33299
33351
  }
33300
33352
 
33301
33353
  // src/commands/guard.ts
33302
- var import_node_fs58 = require("node:fs");
33303
- var import_node_path44 = require("node:path");
33354
+ var import_node_fs59 = require("node:fs");
33355
+ var import_node_path45 = require("node:path");
33304
33356
 
33305
33357
  // src/lib/terminal-text.ts
33306
33358
  var CONTROL = /[\x00-\x08\x0b-\x1f\x7f-\x9f\u061c\u200e\u200f\u2028-\u202e\u2066-\u2069]/g;
@@ -33408,7 +33460,7 @@ async function runAgentReview(options) {
33408
33460
  }
33409
33461
 
33410
33462
  // src/lib/prove/auto.ts
33411
- var import_node_path43 = require("node:path");
33463
+ var import_node_path44 = require("node:path");
33412
33464
  var import_node_crypto18 = require("node:crypto");
33413
33465
 
33414
33466
  // src/lib/prove/signals.ts
@@ -33817,6 +33869,11 @@ async function rankViaServer(candidates2, ctx, auth2) {
33817
33869
  cmd: "prove-rank"
33818
33870
  });
33819
33871
  if (!res.ok) return { ok: false, ranker: "luna", error: res.error, ranked: fallback };
33872
+ const off = res.data;
33873
+ if (off?.enabled === false) {
33874
+ const why = typeof off.reason === "string" ? off.reason.slice(0, 40) : "disabled";
33875
+ return { ok: false, ranker: "luna", error: `formal is off for this project (${why})`, ranked: fallback, disabled: why };
33876
+ }
33820
33877
  const items = Array.isArray(res.data?.items) ? res.data.items : [];
33821
33878
  return { ok: true, ranker: "luna", ranked: applyAnnotations(candidates2, items), costUsd: typeof res.data?.cost_usd === "number" ? res.data.cost_usd : null };
33822
33879
  }
@@ -34541,6 +34598,8 @@ async function generateModel(target, opts) {
34541
34598
  });
34542
34599
  if (!res.ok) return { ok: false, error: res.error };
34543
34600
  const d = res.data ?? {};
34601
+ const off = d;
34602
+ if (off.enabled === false) return { ok: false, error: `formal is off for this project (${typeof off.reason === "string" ? off.reason.slice(0, 40) : "disabled"})` };
34544
34603
  if (d.error && typeof d.error === "object") return { ok: false, error: `${d.error.code ?? "SERVICE_ERROR"}: ${d.error.message ?? "the service failed"}` };
34545
34604
  const usage2 = d.usage && typeof d.usage === "object" ? { inputTokens: Number(d.usage.inputTokens ?? 0), outputTokens: Number(d.usage.outputTokens ?? 0) } : null;
34546
34605
  return acceptAnswer(d, usage2, typeof d.cost_usd === "number" ? d.cost_usd : null);
@@ -34720,8 +34779,7 @@ Rules:
34720
34779
  5. Write the harness as ONE file and run it in the SAME shell call that writes it (a heredoc followed by the run). TypeScript: node --experimental-strip-types harness.ts (detect runtimes only if that fails: node --version, python3 --version); if strip-types is unavailable, remove type annotations ONLY on lines that are not part of the function under test's logic, and say so. Python: python3 harness.py.
34721
34780
  6. Nothing you run can reach the network. Do not try.
34722
34781
  7. Keep it under about eight shell calls. Output tokens are time.
34723
- 8. Answer with the JSON object only: verdict (reproduced | diverged | unreplayable), reason (2-4 sentences: what you ran, what the real code did, and how that compares to the trace's final state), harness_files (every file you wrote: path and its line count \u2014 do NOT paste contents, your shell calls already carry them), executed_output (the last relevant stdout, at most 2000 characters), impact (one word, below).
34724
- 9. impact \u2014 AFTER the verdict, and never a reason to change it: what the violation you ran costs a user of this code, the most serious one the run showed. money: a balance, charge, refund, price or stock is wrong. access: someone gets access they should not have, or an auth check is bypassed. data: a user's records are lost, corrupted or wrongly duplicated. external: an effect outside the system happens twice or never (a charge, an email, a shipment, a webhook). count: a counter, metric or statistic is off. cache: a cached or derived value is stale until it refreshes. internal: the program's own bookkeeping is off, with no effect a user would see. none: the verdict is not reproduced.
34782
+ 8. Answer with the JSON object only: verdict (reproduced | diverged | unreplayable), reason (2-4 sentences: what you ran, what the real code did, and how that compares to the trace's final state), harness_files (every file you wrote: path and its line count \u2014 do NOT paste contents, your shell calls already carry them), executed_output (the last relevant stdout, at most 2000 characters).
34725
34783
 
34726
34784
  "reproduced" means the real code, driven by the trace, reached the property violation the model describes. "diverged" means it did not \u2014 the model is wrong about the code, which is a useful answer. "unreplayable" means you could not run the real function faithfully; say why.`;
34727
34785
  var REPLAY_SCHEMA = {
@@ -34739,10 +34797,9 @@ var REPLAY_SCHEMA = {
34739
34797
  required: ["path", "lines"]
34740
34798
  }
34741
34799
  },
34742
- executed_output: { type: "string" },
34743
- impact: { type: "string", enum: ["money", "access", "data", "external", "count", "cache", "internal", "none"] }
34800
+ executed_output: { type: "string" }
34744
34801
  },
34745
- required: ["verdict", "reason", "harness_files", "executed_output", "impact"]
34802
+ required: ["verdict", "reason", "harness_files", "executed_output"]
34746
34803
  };
34747
34804
  function renderBriefInput(brief) {
34748
34805
  const p = brief.property;
@@ -34769,8 +34826,6 @@ function renderBriefInput(brief) {
34769
34826
  }
34770
34827
  return parts2.join("\n");
34771
34828
  }
34772
- var IMPACTS = ["money", "access", "data", "external", "count", "cache", "internal", "none"];
34773
- var isImpact = (v) => typeof v === "string" && IMPACTS.includes(v);
34774
34829
  function stringsIn(value, out2 = [], depth = 0) {
34775
34830
  if (depth > 8) return out2;
34776
34831
  if (typeof value === "string") out2.push(value);
@@ -34812,8 +34867,7 @@ function parseReplayOutput(output) {
34812
34867
  verdict,
34813
34868
  reason: typeof o.reason === "string" ? o.reason.slice(0, 2e3) : "",
34814
34869
  harness_files: Array.isArray(o.harness_files) ? o.harness_files.filter((f) => typeof f.path === "string").map((f) => ({ path: String(f.path).slice(0, 200), lines: Number.isInteger(f.lines) ? f.lines : 0 })) : [],
34815
- executed_output: typeof o.executed_output === "string" ? o.executed_output.slice(0, 2e3) : "",
34816
- impact: isImpact(o.impact) ? o.impact : "none"
34870
+ executed_output: typeof o.executed_output === "string" ? o.executed_output.slice(0, 2e3) : ""
34817
34871
  };
34818
34872
  }
34819
34873
  } catch {
@@ -34821,10 +34875,10 @@ function parseReplayOutput(output) {
34821
34875
  }
34822
34876
  return { claim, shellCalls, executedCalls, shellTexts, outputTexts };
34823
34877
  }
34824
- var RESULT_LINE = /REPLAY_RESULT=(reproduced|diverged)\b/;
34878
+ var RESULT_LINE = /REPLAY_RESULT=(reproduced|diverged)\b/g;
34825
34879
  function printedResult(outputTexts) {
34826
34880
  let last = null;
34827
- for (const t of outputTexts) for (const m of t.matchAll(new RegExp(RESULT_LINE.source, "g"))) last = m[1];
34881
+ for (const t of outputTexts) for (const m of t.matchAll(RESULT_LINE)) last = m[1];
34828
34882
  return last;
34829
34883
  }
34830
34884
  var RESULT_MISSING = "the harness never printed REPLAY_RESULT=reproduced on its own stdout \u2014 the verdict was the model's word, not the run's";
@@ -35014,7 +35068,6 @@ async function runReplayInContainer(brief, opts) {
35014
35068
  ...judged,
35015
35069
  executedCalls,
35016
35070
  shellCalls,
35017
- ...judged.verdict === "reproduced" && parsed.claim ? { impact: parsed.claim.impact } : {},
35018
35071
  executedOutput: parsed.claim?.executed_output ?? "",
35019
35072
  harnessFiles: parsed.claim?.harness_files ?? [],
35020
35073
  usage,
@@ -35061,6 +35114,11 @@ async function runReplayViaServer(brief, auth2, budgetMs = 24e4) {
35061
35114
  return { claimed: null, verdict: "unverified", reason: "", downgrade: res.error, executedCalls: 0, shellCalls: 0, verbatim: none, executedOutput: "", harnessFiles: [], usage: null, durationMs: Date.now() - started, containerId: null, error: res.error };
35062
35115
  }
35063
35116
  const d = res.data ?? {};
35117
+ if (d.enabled === false) {
35118
+ const why = d.reason;
35119
+ const msg = `formal is off for this project (${typeof why === "string" ? why.slice(0, 40) : "disabled"})`;
35120
+ return { claimed: null, verdict: "unverified", reason: "", downgrade: msg, executedCalls: 0, shellCalls: 0, verbatim: none, executedOutput: "", harnessFiles: [], usage: null, durationMs: Date.now() - started, containerId: null, error: msg };
35121
+ }
35064
35122
  if (d.error && typeof d.error === "object") {
35065
35123
  const e = d.error;
35066
35124
  const msg = `${e.code ?? "SERVICE_ERROR"}: ${e.message ?? "the service failed"}`;
@@ -35073,7 +35131,6 @@ async function runReplayViaServer(brief, auth2, budgetMs = 24e4) {
35073
35131
  verdict: verdict === "reproduced" || verdict === "diverged" || verdict === "unreplayable" ? verdict : "unverified",
35074
35132
  reason: typeof d.reason === "string" ? d.reason : "",
35075
35133
  downgrade: typeof d.downgrade === "string" ? d.downgrade : null,
35076
- ...isImpact(d.impact) ? { impact: d.impact } : {},
35077
35134
  executedCalls: Number(d.executed_calls ?? 0),
35078
35135
  shellCalls: Number(d.shell_calls ?? 0),
35079
35136
  verbatim: { covered: Number(v.covered ?? 0), total: Number(v.total ?? 0), ratio: Number(v.ratio ?? 0), basis: v.basis === "symbol" || v.basis === "file" ? v.basis : "none" },
@@ -35130,18 +35187,18 @@ function renderReplay(model, property, r) {
35130
35187
  // src/lib/prove/runner.ts
35131
35188
  var import_node_child_process15 = require("node:child_process");
35132
35189
  var import_node_os8 = require("node:os");
35133
- var import_node_fs57 = require("node:fs");
35190
+ var import_node_fs58 = require("node:fs");
35134
35191
  var import_node_os9 = require("node:os");
35135
- var import_node_path42 = require("node:path");
35192
+ var import_node_path43 = require("node:path");
35136
35193
 
35137
35194
  // src/lib/prove/scaffold.ts
35138
- var import_node_fs56 = require("node:fs");
35139
- var import_node_path41 = require("node:path");
35195
+ var import_node_fs57 = require("node:fs");
35196
+ var import_node_path42 = require("node:path");
35140
35197
 
35141
35198
  // src/lib/prove/safe-write.ts
35142
- var import_node_fs55 = require("node:fs");
35199
+ var import_node_fs56 = require("node:fs");
35143
35200
  var import_node_crypto14 = require("node:crypto");
35144
- var import_node_path40 = require("node:path");
35201
+ var import_node_path41 = require("node:path");
35145
35202
  var SafeWriteError = class extends Error {
35146
35203
  constructor(reason, path) {
35147
35204
  super(`refusing to write ${path}: ${reason}`);
@@ -35150,10 +35207,10 @@ var SafeWriteError = class extends Error {
35150
35207
  this.name = "SafeWriteError";
35151
35208
  }
35152
35209
  };
35153
- var FLAGS3 = import_node_fs55.constants;
35210
+ var FLAGS3 = import_node_fs56.constants;
35154
35211
  var NOFOLLOW2 = FLAGS3.O_NOFOLLOW ?? 0;
35155
35212
  function assertPlainRelative(rel) {
35156
- if (!rel || (0, import_node_path40.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
35213
+ if (!rel || (0, import_node_path41.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
35157
35214
  for (const part of rel.split(/[\\/]/)) {
35158
35215
  if (part === ".." || part === "" || part === ".") throw new SafeWriteError("bad-path", rel);
35159
35216
  }
@@ -35162,34 +35219,34 @@ function ensureDirsNoFollow(root, rel) {
35162
35219
  const parts2 = rel.split(/[\\/]/);
35163
35220
  let cur = root;
35164
35221
  for (const part of parts2.slice(0, -1)) {
35165
- cur = (0, import_node_path40.join)(cur, part);
35222
+ cur = (0, import_node_path41.join)(cur, part);
35166
35223
  let st;
35167
35224
  try {
35168
- st = (0, import_node_fs55.lstatSync)(cur);
35225
+ st = (0, import_node_fs56.lstatSync)(cur);
35169
35226
  } catch {
35170
- (0, import_node_fs55.mkdirSync)(cur);
35227
+ (0, import_node_fs56.mkdirSync)(cur);
35171
35228
  continue;
35172
35229
  }
35173
35230
  if (st.isSymbolicLink()) throw new SafeWriteError("symlink", cur);
35174
35231
  if (!st.isDirectory()) throw new SafeWriteError("not-regular", cur);
35175
35232
  }
35176
- return (0, import_node_path40.join)(root, rel);
35233
+ return (0, import_node_path41.join)(root, rel);
35177
35234
  }
35178
35235
  function insideRoot(realRoot, realPath) {
35179
- return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path40.sep) ? realRoot : realRoot + import_node_path40.sep);
35236
+ return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path41.sep) ? realRoot : realRoot + import_node_path41.sep);
35180
35237
  }
35181
35238
  function removeQuietly(path) {
35182
35239
  try {
35183
- (0, import_node_fs55.unlinkSync)(path);
35240
+ (0, import_node_fs56.unlinkSync)(path);
35184
35241
  } catch {
35185
35242
  }
35186
35243
  }
35187
35244
  function writeFileInRootNoFollow(root, rel, content) {
35188
35245
  assertPlainRelative(rel);
35189
35246
  const dest = ensureDirsNoFollow(root, rel);
35190
- const dir = (0, import_node_path40.dirname)(dest);
35247
+ const dir = (0, import_node_path41.dirname)(dest);
35191
35248
  try {
35192
- const st = (0, import_node_fs55.lstatSync)(dest);
35249
+ const st = (0, import_node_fs56.lstatSync)(dest);
35193
35250
  if (st.isSymbolicLink()) throw new SafeWriteError("symlink", dest);
35194
35251
  if (!st.isFile()) throw new SafeWriteError("not-regular", dest);
35195
35252
  } catch (err2) {
@@ -35197,41 +35254,41 @@ function writeFileInRootNoFollow(root, rel, content) {
35197
35254
  }
35198
35255
  let realRoot;
35199
35256
  try {
35200
- realRoot = (0, import_node_fs55.realpathSync)(root);
35257
+ realRoot = (0, import_node_fs56.realpathSync)(root);
35201
35258
  } catch {
35202
35259
  throw new SafeWriteError("unwritable", root);
35203
35260
  }
35204
- const tmp = (0, import_node_path40.join)(dir, `.${(0, import_node_path40.basename)(dest)}.${(0, import_node_crypto14.randomBytes)(6).toString("hex")}.tmp`);
35261
+ const tmp = (0, import_node_path41.join)(dir, `.${(0, import_node_path41.basename)(dest)}.${(0, import_node_crypto14.randomBytes)(6).toString("hex")}.tmp`);
35205
35262
  let fd;
35206
35263
  try {
35207
- fd = (0, import_node_fs55.openSync)(tmp, import_node_fs55.constants.O_WRONLY | import_node_fs55.constants.O_CREAT | import_node_fs55.constants.O_EXCL | NOFOLLOW2, 420);
35264
+ fd = (0, import_node_fs56.openSync)(tmp, import_node_fs56.constants.O_WRONLY | import_node_fs56.constants.O_CREAT | import_node_fs56.constants.O_EXCL | NOFOLLOW2, 420);
35208
35265
  } catch {
35209
35266
  throw new SafeWriteError("unwritable", tmp);
35210
35267
  }
35211
35268
  try {
35212
- const opened = (0, import_node_fs55.fstatSync)(fd, { bigint: true });
35269
+ const opened = (0, import_node_fs56.fstatSync)(fd, { bigint: true });
35213
35270
  let realTmp;
35214
35271
  try {
35215
- realTmp = (0, import_node_fs55.realpathSync)(tmp);
35272
+ realTmp = (0, import_node_fs56.realpathSync)(tmp);
35216
35273
  } catch {
35217
35274
  throw new SafeWriteError("escaped", tmp);
35218
35275
  }
35219
- const there = (0, import_node_fs55.lstatSync)(realTmp, { bigint: true });
35276
+ const there = (0, import_node_fs56.lstatSync)(realTmp, { bigint: true });
35220
35277
  if (!opened.isFile() || there.ino !== opened.ino || there.dev !== opened.dev || !insideRoot(realRoot, realTmp)) {
35221
35278
  throw new SafeWriteError("escaped", tmp);
35222
35279
  }
35223
35280
  const buf = Buffer.from(content, "utf-8");
35224
35281
  let off = 0;
35225
- while (off < buf.length) off += (0, import_node_fs55.writeSync)(fd, buf, off, buf.length - off);
35282
+ while (off < buf.length) off += (0, import_node_fs56.writeSync)(fd, buf, off, buf.length - off);
35226
35283
  } catch (err2) {
35227
- (0, import_node_fs55.closeSync)(fd);
35284
+ (0, import_node_fs56.closeSync)(fd);
35228
35285
  removeQuietly(tmp);
35229
35286
  throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", tmp);
35230
35287
  }
35231
- (0, import_node_fs55.closeSync)(fd);
35288
+ (0, import_node_fs56.closeSync)(fd);
35232
35289
  try {
35233
- if (!insideRoot(realRoot, (0, import_node_fs55.realpathSync)(dir)) || (0, import_node_fs55.lstatSync)(dir).isSymbolicLink()) throw new SafeWriteError("escaped", dir);
35234
- (0, import_node_fs55.renameSync)(tmp, dest);
35290
+ if (!insideRoot(realRoot, (0, import_node_fs56.realpathSync)(dir)) || (0, import_node_fs56.lstatSync)(dir).isSymbolicLink()) throw new SafeWriteError("escaped", dir);
35291
+ (0, import_node_fs56.renameSync)(tmp, dest);
35235
35292
  } catch (err2) {
35236
35293
  removeQuietly(tmp);
35237
35294
  throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", dest);
@@ -35245,9 +35302,9 @@ function pathHasNoLink(root, rel) {
35245
35302
  }
35246
35303
  let cur = root;
35247
35304
  for (const part of rel.split(/[\\/]/)) {
35248
- cur = cur + import_node_path40.sep + part;
35305
+ cur = cur + import_node_path41.sep + part;
35249
35306
  try {
35250
- if ((0, import_node_fs55.lstatSync)(cur).isSymbolicLink()) return false;
35307
+ if ((0, import_node_fs56.lstatSync)(cur).isSymbolicLink()) return false;
35251
35308
  } catch {
35252
35309
  return true;
35253
35310
  }
@@ -35557,20 +35614,20 @@ This directory is machine-local and gitignored (see ../.gitignore). Models are
35557
35614
  never committed; what reaches the team is the bug report and the fix.
35558
35615
  `;
35559
35616
  function scaffoldProofs(root) {
35560
- const proofsDir = (0, import_node_path41.join)(root, PROOFS_DIR);
35617
+ const proofsDir = (0, import_node_path42.join)(root, PROOFS_DIR);
35561
35618
  const written = [];
35562
35619
  const kept = [];
35563
35620
  for (const stray of ["lakefile.lean"]) {
35564
35621
  const rel = `${PROOFS_DIR}/${stray}`;
35565
- if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path41.join)(root, rel));
35622
+ if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path42.join)(root, rel));
35566
35623
  try {
35567
- (0, import_node_fs56.rmSync)((0, import_node_path41.join)(root, rel), { force: true });
35624
+ (0, import_node_fs57.rmSync)((0, import_node_path42.join)(root, rel), { force: true });
35568
35625
  } catch {
35569
35626
  }
35570
35627
  }
35571
35628
  for (const f of PROOFS_TEMPLATE_FILES) {
35572
35629
  const rel = `${PROOFS_DIR}/${f.path}`;
35573
- if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path41.join)(root, rel));
35630
+ if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path42.join)(root, rel));
35574
35631
  const current = readRegularFileInRoot(root, rel, 4 * 1024 * 1024);
35575
35632
  if (current.ok && current.content === f.content) {
35576
35633
  kept.push(rel);
@@ -35583,8 +35640,8 @@ function scaffoldProofs(root) {
35583
35640
  [`${PROOFS_DIR}/.gitignore`, LOCAL_GITIGNORE],
35584
35641
  [`${MODELS_DIR}/README.md`, MODELS_README]
35585
35642
  ]) {
35586
- if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path41.join)(root, rel));
35587
- if (existsNoFollow((0, import_node_path41.join)(root, rel))) {
35643
+ if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path42.join)(root, rel));
35644
+ if (existsNoFollow((0, import_node_path42.join)(root, rel))) {
35588
35645
  kept.push(rel);
35589
35646
  continue;
35590
35647
  }
@@ -35595,7 +35652,7 @@ function scaffoldProofs(root) {
35595
35652
  }
35596
35653
  function existsNoFollow(abs) {
35597
35654
  try {
35598
- (0, import_node_fs56.lstatSync)(abs);
35655
+ (0, import_node_fs57.lstatSync)(abs);
35599
35656
  return true;
35600
35657
  } catch {
35601
35658
  return false;
@@ -35853,16 +35910,17 @@ function renderReport(r) {
35853
35910
 
35854
35911
  // src/lib/prove/runner.ts
35855
35912
  function verityLeanHome(env = process.env) {
35856
- return env.VERITY_LEAN_HOME ?? (0, import_node_path42.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".verity", "lean");
35913
+ return env.VERITY_LEAN_HOME ?? (0, import_node_path43.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".verity", "lean");
35857
35914
  }
35858
35915
  function findToolchain(env = process.env) {
35859
- const managedBin = (0, import_node_path42.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
35860
- const elanBin = (0, import_node_path42.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
35861
- const path = [managedBin, elanBin, env.PATH ?? ""].filter(Boolean).join(import_node_path42.delimiter);
35916
+ const managedBin = (0, import_node_path43.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
35917
+ const elanBin = (0, import_node_path43.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
35918
+ const elanHas = (0, import_node_fs58.existsSync)((0, import_node_path43.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
35919
+ const userPath = (env.PATH ?? "").split(import_node_path43.delimiter).filter((d) => d && (elanHas || (0, import_node_path43.resolve)(d) !== (0, import_node_path43.resolve)(elanBin)));
35920
+ const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(import_node_path43.delimiter);
35862
35921
  const merged = { ...env, PATH: path, ELAN_TOOLCHAIN: env.ELAN_TOOLCHAIN ?? LEAN_TOOLCHAIN };
35863
- const elanHas = (0, import_node_fs57.existsSync)((0, import_node_path42.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
35864
35922
  const exe = process.platform === "win32" ? "lake.exe" : "lake";
35865
- const candidates2 = [(0, import_node_path42.join)(managedBin, exe), ...elanHas ? [(0, import_node_path42.join)(elanBin, exe)] : [], exe];
35923
+ const candidates2 = [(0, import_node_path43.join)(managedBin, exe), ...elanHas ? [(0, import_node_path43.join)(elanBin, exe)] : [], exe];
35866
35924
  for (const candidate of candidates2) {
35867
35925
  try {
35868
35926
  (0, import_node_child_process15.execFileSync)(candidate, ["--version"], { env: merged, stdio: ["ignore", "pipe", "pipe"], timeout: 1e4 });
@@ -35937,53 +35995,80 @@ function runAsync(tc, cwd, args2, timeoutMs) {
35937
35995
  }
35938
35996
  var DEFAULT_BUILD_TIMEOUT_MS = 10 * 6e4;
35939
35997
  var DEFAULT_CHECK_TIMEOUT_MS = 12e4;
35998
+ function proofsWorkspaceProblem(root) {
35999
+ for (const rel of [".verity", PROOFS_DIR, `${PROOFS_DIR}/.lake`]) {
36000
+ let st;
36001
+ try {
36002
+ st = (0, import_node_fs58.lstatSync)((0, import_node_path43.join)(root, rel));
36003
+ } catch {
36004
+ break;
36005
+ }
36006
+ if (st.isSymbolicLink()) return `${rel} is a symlink; Lean is not run through it`;
36007
+ }
36008
+ const r = runGitSync(root, ["ls-files", "-z", "--", PROOFS_DIR], { timeoutMs: 5e3 });
36009
+ if (!r.ok) return `could not confirm with git that ${PROOFS_DIR} holds no committed files; Lean is not run`;
36010
+ const tracked = r.stdout.split("\0").filter(Boolean);
36011
+ if (tracked.length > 0) {
36012
+ return `${tracked.length} file(s) under ${PROOFS_DIR} are tracked in git (e.g. ${tracked[0]}); Lean is not run on a workspace the repository supplies \u2014 untrack them with: git rm -r --cached ${PROOFS_DIR}`;
36013
+ }
36014
+ return null;
36015
+ }
36016
+ function refused(problem) {
36017
+ return { ok: false, stdout: "", stderr: problem, durationMs: 0, timedOut: false };
36018
+ }
35940
36019
  function buildLibrary(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
35941
- return run2(tc, (0, import_node_path42.join)(root, PROOFS_DIR), ["build"], timeoutMs);
36020
+ const problem = proofsWorkspaceProblem(root);
36021
+ if (problem) return refused(problem);
36022
+ return run2(tc, (0, import_node_path43.join)(root, PROOFS_DIR), ["build"], timeoutMs);
35942
36023
  }
35943
- function buildLibraryAsync(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
35944
- return runAsync(tc, (0, import_node_path42.join)(root, PROOFS_DIR), ["build"], timeoutMs);
36024
+ async function buildLibraryAsync(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
36025
+ const problem = proofsWorkspaceProblem(root);
36026
+ if (problem) return refused(problem);
36027
+ return runAsync(tc, (0, import_node_path43.join)(root, PROOFS_DIR), ["build"], timeoutMs);
35945
36028
  }
35946
36029
  function isModelInRoot(modelsAbs, rel) {
35947
- if (!rel.endsWith(".lean") || (0, import_node_path42.isAbsolute)(rel) || rel.startsWith("..")) return false;
36030
+ if (!rel.endsWith(".lean") || (0, import_node_path43.isAbsolute)(rel) || rel.startsWith("..")) return false;
35948
36031
  return statRegularInRoot(modelsAbs, rel).ok;
35949
36032
  }
35950
36033
  function resolveModelFile(root, arg) {
35951
- const modelsAbs = (0, import_node_path42.join)(root, MODELS_DIR);
35952
- const asPath = (0, import_node_path42.relative)(modelsAbs, (0, import_node_path42.isAbsolute)(arg) ? arg : (0, import_node_path42.resolve)(root, arg));
36034
+ const modelsAbs = (0, import_node_path43.join)(root, MODELS_DIR);
36035
+ const asPath = (0, import_node_path43.relative)(modelsAbs, (0, import_node_path43.isAbsolute)(arg) ? arg : (0, import_node_path43.resolve)(root, arg));
35953
36036
  const candidates2 = arg.includes("/") || arg.includes("\\") ? [asPath] : [arg, `${arg}.lean`];
35954
36037
  for (const rel of candidates2) {
35955
- if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path42.join)(modelsAbs, rel);
36038
+ if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path43.join)(modelsAbs, rel);
35956
36039
  }
35957
36040
  return null;
35958
36041
  }
35959
36042
  function listModelFiles(root) {
35960
- const modelsAbs = (0, import_node_path42.join)(root, MODELS_DIR);
35961
- if (!(0, import_node_fs57.existsSync)(modelsAbs)) return [];
35962
- return (0, import_node_fs57.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path42.join)(modelsAbs, f));
36043
+ const modelsAbs = (0, import_node_path43.join)(root, MODELS_DIR);
36044
+ if (!(0, import_node_fs58.existsSync)(modelsAbs)) return [];
36045
+ return (0, import_node_fs58.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path43.join)(modelsAbs, f));
35963
36046
  }
35964
36047
  function trimDiagnostics(text) {
35965
36048
  return text.split("\n").filter((l) => !l.startsWith("trace:")).join("\n").trim().slice(0, 4e3);
35966
36049
  }
35967
36050
  function checkModel(tc, root, modelFile, opts = {}) {
35968
- const proofsAbs = (0, import_node_path42.join)(root, PROOFS_DIR);
35969
- const rel = (0, import_node_path42.relative)(proofsAbs, modelFile);
35970
- const res = run2(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
36051
+ const proofsAbs = (0, import_node_path43.join)(root, PROOFS_DIR);
36052
+ const rel = (0, import_node_path43.relative)(proofsAbs, modelFile);
36053
+ const problem = proofsWorkspaceProblem(root);
36054
+ const res = problem ? refused(problem) : run2(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
35971
36055
  return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
35972
36056
  }
35973
36057
  async function checkModelAsync(tc, root, modelFile, opts = {}) {
35974
- const proofsAbs = (0, import_node_path42.join)(root, PROOFS_DIR);
35975
- const rel = (0, import_node_path42.relative)(proofsAbs, modelFile);
35976
- const res = await runAsync(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
36058
+ const proofsAbs = (0, import_node_path43.join)(root, PROOFS_DIR);
36059
+ const rel = (0, import_node_path43.relative)(proofsAbs, modelFile);
36060
+ const problem = proofsWorkspaceProblem(root);
36061
+ const res = problem ? refused(problem) : await runAsync(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
35977
36062
  return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
35978
36063
  }
35979
36064
  function toReport(res, root, modelFile, timeoutMs) {
35980
36065
  const parsed = parseVerityLines(res.stdout);
35981
36066
  const combined = `${res.stdout}
35982
36067
  ${res.stderr}`;
35983
- const name2 = parsed.header?.model ?? (0, import_node_path42.basename)(modelFile, ".lean");
36068
+ const name2 = parsed.header?.model ?? (0, import_node_path43.basename)(modelFile, ".lean");
35984
36069
  const report = {
35985
36070
  model: name2,
35986
- file: (0, import_node_path42.relative)(root, modelFile),
36071
+ file: (0, import_node_path43.relative)(root, modelFile),
35987
36072
  ok: res.ok,
35988
36073
  header: parsed.header,
35989
36074
  properties: parsed.properties,
@@ -36028,33 +36113,18 @@ function writeResult(root, report) {
36028
36113
  function isCrashTrace(trace) {
36029
36114
  return trace.some((s) => /\b(crash\w*|kill\w*|restart\w*|interrupt\w*|power|abort\w*|process (dies|exit\w*)|lost (reply|response))\b/i.test(s));
36030
36115
  }
36031
- var SEVERITY_BY_IMPACT = {
36032
- money: "high",
36033
- access: "high",
36034
- data: "high",
36035
- external: "high",
36036
- count: "medium",
36037
- cache: "medium",
36038
- internal: "medium",
36039
- // A reproduced finding always has a real code; 'none' here is a malformed answer, so it blocks.
36040
- none: "high"
36041
- };
36042
- function formalSeverity(f) {
36043
- return f.impact && SEVERITY_BY_IMPACT[f.impact] || "high";
36044
- }
36045
36116
  function mergeFormalFindings(response, outcome, pushedFiles) {
36046
- if (!outcome) return { blocking: 0, warning: 0 };
36117
+ if (!outcome) return { blocking: 0 };
36047
36118
  const norm2 = (p) => p.replace(/\\/g, "/");
36048
36119
  const pushed = new Set(pushedFiles.map(norm2));
36049
- const reproduced = outcome.findings.filter((f) => f.verdict === "reproduced" && !f.waived && pushed.has(norm2(f.file)));
36050
- if (reproduced.length === 0) return { blocking: 0, warning: 0 };
36051
- const blocking = reproduced.filter((f) => formalSeverity(f) === "high");
36120
+ const blocking = outcome.findings.filter((f) => f.verdict === "reproduced" && !f.waived && pushed.has(norm2(f.file)));
36121
+ if (blocking.length === 0) return { blocking: 0 };
36052
36122
  const existing = Array.isArray(response.findings) ? response.findings : [];
36053
36123
  response.findings = [
36054
36124
  ...existing,
36055
- ...reproduced.map((f) => ({
36125
+ ...blocking.map((f) => ({
36056
36126
  pattern_id: "formal-counterexample",
36057
- severity: formalSeverity(f),
36127
+ severity: "high",
36058
36128
  scope: "change",
36059
36129
  file: f.file,
36060
36130
  line: outcome.target?.lines?.from ?? null,
@@ -36062,15 +36132,14 @@ function mergeFormalFindings(response, outcome, pushedFiles) {
36062
36132
  // as a title it read backwards (e2e, 2026-09-26). A trace that needs a
36063
36133
  // crash between two writes is labelled: reproducing it means injecting
36064
36134
  // the crash, so it is a crash-consistency finding, not a race.
36065
- title: `Formal: ${terminalText(f.symbol, 128)} breaks "${terminalText(f.desc, 280)}"${isCrashTrace(f.trace) ? " after a crash (crash consistency)" : ""} \u2014 reproduced on the real code${f.impact && f.impact !== "none" ? ` (impact: ${f.impact})` : ""}`,
36135
+ title: `Formal: ${terminalText(f.symbol, 128)} breaks "${terminalText(f.desc, 280)}"${isCrashTrace(f.trace) ? " after a crash (crash consistency)" : ""} \u2014 reproduced on the real code`,
36066
36136
  description: terminalText(f.reason ?? "", 2e3),
36067
36137
  fix: { description: `Trace: ${terminalText(f.trace.join(" \u2192 ") || "(initial state)", 2e3)}. Replay: ${terminalText(f.reason ?? "reproduced in the container", 2e3)}` },
36068
36138
  source: "formal"
36069
36139
  }))
36070
36140
  ];
36071
- if (blocking.length > 0) response.gate_decision = "FAIL";
36072
- else if (response.gate_decision === "PASS" || response.gate_decision == null) response.gate_decision = "WARN";
36073
- return { blocking: blocking.length, warning: reproduced.length - blocking.length };
36141
+ if (response.gate_decision !== "FAIL") response.gate_decision = "FAIL";
36142
+ return { blocking: blocking.length };
36074
36143
  }
36075
36144
 
36076
36145
  // src/lib/prove/scalpel.ts
@@ -36237,20 +36306,28 @@ function isEligible(s, largePush) {
36237
36306
  function intersects(a, ranges) {
36238
36307
  return ranges.some((b) => a.from <= b.to && b.from <= a.to);
36239
36308
  }
36309
+ function isLocalState(root, rel) {
36310
+ return repoControlled(root, rel) === null;
36311
+ }
36312
+ function nonNegative(v) {
36313
+ return typeof v === "number" && Number.isFinite(v) && v > 0 ? v : 0;
36314
+ }
36240
36315
  function readLedger(root) {
36241
36316
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
36242
36317
  const empty = { day: today, models: 0, costUsd: 0 };
36318
+ if (!isLocalState(root, AUTO_LEDGER)) return empty;
36243
36319
  const read2 = readRegularFileInRoot(root, AUTO_LEDGER, 4096);
36244
36320
  if (!read2.ok) return empty;
36245
36321
  try {
36246
36322
  const o = JSON.parse(read2.content);
36247
36323
  if (o.day !== today || typeof o.models !== "number") return empty;
36248
- return { day: today, models: o.models, costUsd: typeof o.costUsd === "number" && Number.isFinite(o.costUsd) ? o.costUsd : 0 };
36324
+ return { day: today, models: nonNegative(o.models), costUsd: nonNegative(o.costUsd) };
36249
36325
  } catch {
36250
36326
  return empty;
36251
36327
  }
36252
36328
  }
36253
36329
  function writeLedger(root, l) {
36330
+ if (!isLocalState(root, AUTO_LEDGER)) return;
36254
36331
  try {
36255
36332
  writeFileInRootNoFollow(root, AUTO_LEDGER, JSON.stringify(l) + "\n");
36256
36333
  } catch {
@@ -36263,6 +36340,7 @@ function addLedgerCost(root, usd) {
36263
36340
  }
36264
36341
  var FINDINGS_FILE = `${PROOFS_DIR}/.results/.findings.json`;
36265
36342
  function readPersistedFindings(root) {
36343
+ if (!isLocalState(root, FINDINGS_FILE)) return [];
36266
36344
  const read2 = readRegularFileInRoot(root, FINDINGS_FILE, 256 * 1024);
36267
36345
  if (!read2.ok) return [];
36268
36346
  try {
@@ -36286,6 +36364,7 @@ function waiveFormalFindings(root, file, reason) {
36286
36364
  return n;
36287
36365
  }
36288
36366
  function writePersistedFindings(root, findings) {
36367
+ if (!isLocalState(root, FINDINGS_FILE)) return;
36289
36368
  try {
36290
36369
  writeFileInRootNoFollow(root, FINDINGS_FILE, JSON.stringify({ findings: findings.slice(0, 50) }, null, 2) + "\n");
36291
36370
  } catch {
@@ -36379,9 +36458,7 @@ async function runFormalPhase(input) {
36379
36458
  symbol: f.symbol,
36380
36459
  verdict: "reproduced",
36381
36460
  reason: f.waived ? `waived ${f.waived.at.slice(0, 10)}: ${f.waived.reason} (standing since ${f.at.slice(0, 10)}; the file has not changed)` : `${f.reason ?? "reproduced on the real code"} (standing since ${f.at.slice(0, 10)}; the file has not changed)`,
36382
- ...f.waived ? { waived: true } : {},
36383
- // A hand-edited file cannot invent a code: unknown values read as absent (HIGH).
36384
- ...isImpact(f.impact) ? { impact: f.impact } : {}
36461
+ ...f.waived ? { waived: true } : {}
36385
36462
  });
36386
36463
  }
36387
36464
  }
@@ -36420,6 +36497,7 @@ async function runFormalPhase(input) {
36420
36497
  return done({ status: "skipped", skip: "not-eligible", detail: `${best.file}: ${isEligible(best, largePush).why}` });
36421
36498
  }
36422
36499
  const ranked = await deps.rank(eligible, root, input.changedLines);
36500
+ if (!ranked.ok && ranked.disabled) return done({ status: "skipped", skip: "disabled-by-server", detail: ranked.error });
36423
36501
  if (ranked.ok) spend(ranked);
36424
36502
  candidates2 = ranked.ranked.slice(0, 5).map((c) => ({ file: c.file, symbol: c.ai?.symbol ?? null, score: c.ai?.score ?? null, criteria: c.ai?.criteria ?? null, reasked: !!c.ai?.reasked, reasons: (c.ai?.reasons ?? []).map((r) => r.slice(0, 200)) }));
36425
36503
  if (cancelled()) return done({ status: "skipped", skip: "deadline", detail: "cut off after ranking" });
@@ -36560,7 +36638,7 @@ async function runFormalPhase(input) {
36560
36638
  modelName = gen.name;
36561
36639
  const rel = `${AUTO_MODELS_DIR}/${gen.name}.lean`;
36562
36640
  writeFileInRootNoFollow(root, rel, gen.source);
36563
- const abs = resolveModelFile(root, rel) ?? (0, import_node_path43.join)(root, rel);
36641
+ const abs = resolveModelFile(root, rel) ?? (0, import_node_path44.join)(root, rel);
36564
36642
  progress.model = { name: gen.name, file: rel, rounds: round };
36565
36643
  progress.step = "check";
36566
36644
  report = await deps.check(root, abs);
@@ -36654,7 +36732,7 @@ async function runFormalPhase(input) {
36654
36732
  continue;
36655
36733
  }
36656
36734
  const verdict = r.verdict === "reproduced" ? "reproduced" : r.verdict === "diverged" ? "diverged" : r.verdict === "unreplayable" ? "model-only" : "unverified";
36657
- findings.push({ ...baseOf(p), verdict, reason: r.reason || r.downgrade || void 0, ...verdict === "reproduced" && r.impact ? { impact: r.impact } : {} });
36735
+ findings.push({ ...baseOf(p), verdict, reason: r.reason || r.downgrade || void 0 });
36658
36736
  }
36659
36737
  const reproduced = findings.filter((f) => f.verdict === "reproduced");
36660
36738
  if (reproduced.length > 0 && !cancelled()) {
@@ -36662,7 +36740,7 @@ async function runFormalPhase(input) {
36662
36740
  const others = readPersistedFindings(root).filter((f) => f.file !== top.file);
36663
36741
  writePersistedFindings(root, [
36664
36742
  ...others,
36665
- ...reproduced.map((f) => ({ file: f.file, symbol: f.symbol, sha256: sha2562, property: f.property, desc: f.desc, kind: f.kind, trace: f.trace, model: modelName, reason: f.reason, ...f.impact ? { impact: f.impact } : {}, ...lines ? { lines } : {}, at: now }))
36743
+ ...reproduced.map((f) => ({ file: f.file, symbol: f.symbol, sha256: sha2562, property: f.property, desc: f.desc, kind: f.kind, trace: f.trace, model: modelName, reason: f.reason, ...lines ? { lines } : {}, at: now }))
36666
36744
  ]);
36667
36745
  }
36668
36746
  const clean2 = findings.every((f) => f.verdict === "diverged");
@@ -36682,7 +36760,7 @@ async function runFormalPhase(input) {
36682
36760
  return done({
36683
36761
  status: "checked",
36684
36762
  target,
36685
- model: { name: modelName, file: (0, import_node_path43.relative)(root, (0, import_node_path43.join)(root, modelFile)), rounds },
36763
+ model: { name: modelName, file: (0, import_node_path44.relative)(root, (0, import_node_path44.join)(root, modelFile)), rounds },
36686
36764
  properties: report.properties,
36687
36765
  findings
36688
36766
  });
@@ -36745,7 +36823,7 @@ async function generateAndCheck(root, req, opts) {
36745
36823
  }
36746
36824
  const rel = `${dir}/${gen.name}.lean`;
36747
36825
  writeFileInRootNoFollow(root, rel, gen.source);
36748
- const abs = resolveModelFile(root, rel) ?? (0, import_node_path43.join)(root, rel);
36826
+ const abs = resolveModelFile(root, rel) ?? (0, import_node_path44.join)(root, rel);
36749
36827
  const report = await opts.deps.check(root, abs);
36750
36828
  const abstracts = report.header?.abstracts ?? [];
36751
36829
  const stray = abstracts.find((a) => !headerFiles.has(a.file)) ?? (abstracts[0] && abstracts[0].file !== req.file ? abstracts[0] : void 0);
@@ -36783,6 +36861,8 @@ async function prepareFormalPhase(root, env = process.env, auth2, readSource, co
36783
36861
  const apiKey = direct ? env.OPENAI_API_KEY : void 0;
36784
36862
  const toolchain = findToolchain(env);
36785
36863
  if (!toolchain) return { ok: false, skip: "no-toolchain" };
36864
+ const untrusted = proofsWorkspaceProblem(root);
36865
+ if (untrusted) return { ok: false, skip: "workspace-untrusted", detail: untrusted.slice(0, 200) };
36786
36866
  try {
36787
36867
  scaffoldProofs(root);
36788
36868
  } catch (err2) {
@@ -36872,7 +36952,7 @@ var EXCERPT_SOURCE_MAX_BYTES = 2 * 1024 * 1024;
36872
36952
  var WRITERS_BUDGET_MS = 1500;
36873
36953
  var EXCERPT_MAX_LINES2 = 30;
36874
36954
  var GUARD_BLOCK_CAP = 2;
36875
- var GUARD_ITER_FILE = (0, import_node_path44.join)(VERITY_DIR, ".guard-iteration");
36955
+ var GUARD_ITER_FILE = (0, import_node_path45.join)(VERITY_DIR, ".guard-iteration");
36876
36956
  function readPreToolUseStdin() {
36877
36957
  const empty = { command: "", cwd: null, sessionId: null };
36878
36958
  return new Promise((resolve8) => {
@@ -36917,7 +36997,7 @@ function readPreToolUseStdin() {
36917
36997
  }
36918
36998
  function readIterMap() {
36919
36999
  try {
36920
- const raw = JSON.parse((0, import_node_fs58.readFileSync)(GUARD_ITER_FILE, "utf-8"));
37000
+ const raw = JSON.parse((0, import_node_fs59.readFileSync)(GUARD_ITER_FILE, "utf-8"));
36921
37001
  if (raw && typeof raw === "object") {
36922
37002
  if (typeof raw.moment === "string" && typeof raw.count === "number") {
36923
37003
  return { [raw.moment]: raw.count };
@@ -36937,10 +37017,10 @@ function readIter(moment) {
36937
37017
  }
36938
37018
  function writeIter(moment, count) {
36939
37019
  try {
36940
- (0, import_node_fs58.mkdirSync)(VERITY_DIR, { recursive: true });
37020
+ (0, import_node_fs59.mkdirSync)(VERITY_DIR, { recursive: true });
36941
37021
  const map = readIterMap();
36942
37022
  map[moment] = count;
36943
- (0, import_node_fs58.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
37023
+ (0, import_node_fs59.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
36944
37024
  } catch {
36945
37025
  }
36946
37026
  }
@@ -36950,10 +37030,10 @@ function resetIter(moment) {
36950
37030
  if (!(moment in map)) return;
36951
37031
  delete map[moment];
36952
37032
  if (Object.keys(map).length === 0) {
36953
- if ((0, import_node_fs58.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs58.unlinkSync)(GUARD_ITER_FILE);
37033
+ if ((0, import_node_fs59.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs59.unlinkSync)(GUARD_ITER_FILE);
36954
37034
  } else {
36955
- (0, import_node_fs58.mkdirSync)(VERITY_DIR, { recursive: true });
36956
- (0, import_node_fs58.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
37035
+ (0, import_node_fs59.mkdirSync)(VERITY_DIR, { recursive: true });
37036
+ (0, import_node_fs59.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
36957
37037
  }
36958
37038
  } catch {
36959
37039
  }
@@ -37023,7 +37103,7 @@ function hasBlockingFinding(response, sentFiles) {
37023
37103
  function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedIntent, coverageTelemetry) {
37024
37104
  const analyzable = filterAnalyzable(files);
37025
37105
  const securityFiles = filterSecurity(files);
37026
- const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs58.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
37106
+ const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs59.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
37027
37107
  const staticResults = runCodacyAnalysisIfAvailable(scannable);
37028
37108
  const trigger = moment === "pre-commit" ? "hook:pre-commit" : "hook:pre-push";
37029
37109
  const requestBody = {
@@ -37400,8 +37480,6 @@ async function runGuard(opts, globals) {
37400
37480
  rounds: formalOutcome.model?.rounds ?? null,
37401
37481
  properties: formalOutcome.properties?.map((p) => `${p.id}:${p.result}`) ?? [],
37402
37482
  findings: formalOutcome.findings.map((f) => `${f.property}:${f.verdict}`),
37403
- // Decision 82: the replay's impact code per reproduced finding; count/cache/internal warn, the rest block.
37404
- impacts: formalOutcome.findings.filter((f) => f.impact).map((f) => `${f.property}:${f.impact}`),
37405
37483
  // Decision 81: what each property rests on (a rule, or "line"), what was
37406
37484
  // sent back or dropped as ungrounded, and which counterexamples lack their
37407
37485
  // property's trigger (shadow). Ids and rule names only, never code.
@@ -37643,7 +37721,7 @@ function registerIgnoreCommand(program2) {
37643
37721
 
37644
37722
  // src/commands/waive.ts
37645
37723
  var import_node_crypto19 = require("node:crypto");
37646
- var import_node_fs59 = require("node:fs");
37724
+ var import_node_fs60 = require("node:fs");
37647
37725
  function registerWaiveCommand(program2) {
37648
37726
  program2.command("waive <pattern-id>").description("Record an accepted-risk disposition for an open finding (voids when the file changes)").option("--file <path>", "File the finding is anchored to, REPO-RELATIVE (recommended \u2014 narrows the waive)").requiredOption("--reason <text>", "The human disposition this records (reviewer finding, ADR, \u2026)").action(async (patternId, opts) => {
37649
37727
  const globals = program2.opts();
@@ -37672,7 +37750,7 @@ function registerWaiveCommand(program2) {
37672
37750
  if (opts.file) {
37673
37751
  body2.file = opts.file;
37674
37752
  try {
37675
- body2.file_sha256 = (0, import_node_crypto19.createHash)("sha256").update((0, import_node_fs59.readFileSync)(opts.file)).digest("hex");
37753
+ body2.file_sha256 = (0, import_node_crypto19.createHash)("sha256").update((0, import_node_fs60.readFileSync)(opts.file)).digest("hex");
37676
37754
  } catch {
37677
37755
  printError(`Cannot read ${opts.file} \u2014 run from the repo root, or omit --file to waive by pattern.`);
37678
37756
  process.exit(1);
@@ -37697,10 +37775,10 @@ function registerWaiveCommand(program2) {
37697
37775
  }
37698
37776
 
37699
37777
  // src/commands/init.ts
37700
- var import_node_fs64 = require("node:fs");
37778
+ var import_node_fs65 = require("node:fs");
37701
37779
  var import_promises20 = require("node:fs/promises");
37702
37780
  var import_yaml6 = __toESM2(require_dist());
37703
- var import_node_path48 = require("node:path");
37781
+ var import_node_path49 = require("node:path");
37704
37782
  var import_node_child_process19 = require("node:child_process");
37705
37783
 
37706
37784
  // src/lib/banner.ts
@@ -37779,7 +37857,7 @@ function printPhase(n, of, title, subtitle) {
37779
37857
  }
37780
37858
 
37781
37859
  // src/commands/doctor.ts
37782
- var import_node_fs60 = require("node:fs");
37860
+ var import_node_fs61 = require("node:fs");
37783
37861
 
37784
37862
  // src/lib/prereqs.ts
37785
37863
  var import_node_child_process16 = require("node:child_process");
@@ -37987,11 +38065,11 @@ async function buildReport() {
37987
38065
  const hooks = wiring.status;
37988
38066
  const provenance = cliProvenance();
37989
38067
  const telemetry = await checkTelemetry();
37990
- const hasConfig = (0, import_node_fs60.existsSync)(projectPath(CODACY_CONFIG_FILE));
38068
+ const hasConfig = (0, import_node_fs61.existsSync)(projectPath(CODACY_CONFIG_FILE));
37991
38069
  const artifacts = {
37992
- standard: (0, import_node_fs60.existsSync)(projectPath(STANDARD_FILE)),
38070
+ standard: (0, import_node_fs61.existsSync)(projectPath(STANDARD_FILE)),
37993
38071
  analysisConfig: hasConfig,
37994
- verityMd: (0, import_node_fs60.existsSync)(projectPath(VERITY_MD_FILE)),
38072
+ verityMd: (0, import_node_fs61.existsSync)(projectPath(VERITY_MD_FILE)),
37995
38073
  analysisConfigIds: hasConfig ? validatePatternIds().status : "absent"
37996
38074
  };
37997
38075
  const next = [];
@@ -38121,9 +38199,11 @@ function registerDoctorCommand(program2) {
38121
38199
  printInfo(` Stop (verity analyze): ${report.hooks.stop ? plugin ? "on (plugin)" : "on" : "off"}`);
38122
38200
  printInfo(` Git-moment gate: ${report.hooks.guardOn.length ? report.hooks.guardOn.join(", ") : "off"}`);
38123
38201
  {
38124
- const formal = readProjectConfig().formal === "push";
38202
+ const cfg = readProjectConfig();
38203
+ const formal = cfg.formal === "push";
38125
38204
  const tc = formal ? findToolchain() : null;
38126
38205
  printInfo(` Formal verification (push): ${formal ? `on, Lean ${tc ? "\u2713" : "MISSING \u2014 verity lean install"} (ranking, model writing and replay run on the Verity service with your login)` : "off"}`);
38206
+ if (cfg.formal_refused) printWarn(` ${formalRefusalMessage(cfg.formal_refused)}`);
38127
38207
  }
38128
38208
  printInfo(` Infra (intent/baseline/compact/session-end): ${[report.hooks.intent, report.hooks.baseline, report.hooks.compact, report.hooks.sessionEnd].filter(Boolean).length}/4`);
38129
38209
  printInfo(`Telemetry: ${report.telemetry.enabled ? `enabled \u2192 ${report.telemetry.endpoint}` : "disabled"}`);
@@ -38148,8 +38228,8 @@ function registerDoctorCommand(program2) {
38148
38228
  }
38149
38229
 
38150
38230
  // src/commands/migrate.ts
38151
- var import_node_fs61 = require("node:fs");
38152
- var import_node_path45 = require("node:path");
38231
+ var import_node_fs62 = require("node:fs");
38232
+ var import_node_path46 = require("node:path");
38153
38233
  var import_node_child_process17 = require("node:child_process");
38154
38234
  var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
38155
38235
  function defaultNpmRemover(pkg) {
@@ -38186,12 +38266,12 @@ async function runMigration(opts = {}) {
38186
38266
  return { actions, migrated: actions.length > 0 };
38187
38267
  }
38188
38268
  function migrateProjectDir(root, actions) {
38189
- const gateDir = (0, import_node_path45.join)(root, ".gate");
38190
- const verityDir = (0, import_node_path45.join)(root, ".verity");
38191
- if ((0, import_node_fs61.existsSync)(gateDir) && !(0, import_node_fs61.existsSync)(verityDir)) {
38269
+ const gateDir = (0, import_node_path46.join)(root, ".gate");
38270
+ const verityDir = (0, import_node_path46.join)(root, ".verity");
38271
+ if ((0, import_node_fs62.existsSync)(gateDir) && !(0, import_node_fs62.existsSync)(verityDir)) {
38192
38272
  return migrateProjectDirRename(root, gateDir, verityDir, actions);
38193
38273
  }
38194
- if ((0, import_node_fs61.existsSync)(gateDir) && (0, import_node_fs61.existsSync)(verityDir)) {
38274
+ if ((0, import_node_fs62.existsSync)(gateDir) && (0, import_node_fs62.existsSync)(verityDir)) {
38195
38275
  return migrateProjectDirCarry(gateDir, verityDir, actions);
38196
38276
  }
38197
38277
  return false;
@@ -38212,13 +38292,13 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
38212
38292
  }
38213
38293
  }
38214
38294
  if (moved) {
38215
- if ((0, import_node_fs61.existsSync)(gateDir)) {
38295
+ if ((0, import_node_fs62.existsSync)(gateDir)) {
38216
38296
  const carried = carryLegacyContents(gateDir, verityDir);
38217
38297
  if (carried > 0) {
38218
38298
  actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
38219
38299
  }
38220
38300
  try {
38221
- (0, import_node_fs61.rmSync)(gateDir, { recursive: true, force: true });
38301
+ (0, import_node_fs62.rmSync)(gateDir, { recursive: true, force: true });
38222
38302
  } catch {
38223
38303
  }
38224
38304
  }
@@ -38234,18 +38314,18 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
38234
38314
  actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
38235
38315
  }
38236
38316
  try {
38237
- (0, import_node_fs61.rmSync)(gateDir, { recursive: true, force: true });
38317
+ (0, import_node_fs62.rmSync)(gateDir, { recursive: true, force: true });
38238
38318
  } catch {
38239
38319
  }
38240
38320
  return carried > 0;
38241
38321
  }
38242
38322
  function migrateGlobalCredentials(home, actions) {
38243
38323
  if (!home) return;
38244
- const gateCreds = (0, import_node_path45.join)(home, ".gate", "credentials");
38245
- const verityCreds = (0, import_node_path45.join)(home, ".verity", "credentials");
38246
- if (!(0, import_node_fs61.existsSync)(gateCreds)) return;
38247
- if (!(0, import_node_fs61.existsSync)(verityCreds)) {
38248
- (0, import_node_fs61.mkdirSync)((0, import_node_path45.join)(home, ".verity"), { recursive: true });
38324
+ const gateCreds = (0, import_node_path46.join)(home, ".gate", "credentials");
38325
+ const verityCreds = (0, import_node_path46.join)(home, ".verity", "credentials");
38326
+ if (!(0, import_node_fs62.existsSync)(gateCreds)) return;
38327
+ if (!(0, import_node_fs62.existsSync)(verityCreds)) {
38328
+ (0, import_node_fs62.mkdirSync)((0, import_node_path46.join)(home, ".verity"), { recursive: true });
38249
38329
  moveFile(gateCreds, verityCreds);
38250
38330
  actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
38251
38331
  return;
@@ -38267,8 +38347,8 @@ async function migrateLegacyHooks(root, actions) {
38267
38347
  }
38268
38348
  }
38269
38349
  async function migrateClaudeMd(root, actions) {
38270
- const claudeMd = (0, import_node_path45.join)(root, "CLAUDE.md");
38271
- const hadLegacyBlock = (0, import_node_fs61.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
38350
+ const claudeMd = (0, import_node_path46.join)(root, "CLAUDE.md");
38351
+ const hadLegacyBlock = (0, import_node_fs62.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
38272
38352
  if (!hadLegacyBlock) return;
38273
38353
  try {
38274
38354
  await ensureClaudeMdPointer(root);
@@ -38278,9 +38358,9 @@ async function migrateClaudeMd(root, actions) {
38278
38358
  }
38279
38359
  }
38280
38360
  function migrateStandardFile(root, actions) {
38281
- const gateMd = (0, import_node_path45.join)(root, "GATE.md");
38282
- const verityMd = (0, import_node_path45.join)(root, "VERITY.md");
38283
- if (!(0, import_node_fs61.existsSync)(gateMd) || (0, import_node_fs61.existsSync)(verityMd)) return;
38361
+ const gateMd = (0, import_node_path46.join)(root, "GATE.md");
38362
+ const verityMd = (0, import_node_path46.join)(root, "VERITY.md");
38363
+ if (!(0, import_node_fs62.existsSync)(gateMd) || (0, import_node_fs62.existsSync)(verityMd)) return;
38284
38364
  let moved = false;
38285
38365
  if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
38286
38366
  try {
@@ -38292,12 +38372,12 @@ function migrateStandardFile(root, actions) {
38292
38372
  if (!moved) moveFile(gateMd, verityMd);
38293
38373
  const content = readFileSyncSafe(verityMd);
38294
38374
  const refreshed = content.split("GATE.md").join("VERITY.md");
38295
- if (refreshed !== content) (0, import_node_fs61.writeFileSync)(verityMd, refreshed);
38375
+ if (refreshed !== content) (0, import_node_fs62.writeFileSync)(verityMd, refreshed);
38296
38376
  actions.push("Renamed GATE.md \u2192 VERITY.md");
38297
38377
  }
38298
38378
  async function migrateTelemetryHeaders(root, actions) {
38299
- const file = (0, import_node_path45.join)(root, ".claude", "settings.local.json");
38300
- if (!(0, import_node_fs61.existsSync)(file)) return;
38379
+ const file = (0, import_node_path46.join)(root, ".claude", "settings.local.json");
38380
+ if (!(0, import_node_fs62.existsSync)(file)) return;
38301
38381
  let settings;
38302
38382
  try {
38303
38383
  settings = JSON.parse(readFileSyncSafe(file) || "{}");
@@ -38345,14 +38425,14 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
38345
38425
  }
38346
38426
  if (toAppend.length > 0) {
38347
38427
  const sep5 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
38348
- (0, import_node_fs61.writeFileSync)(verityCreds, verityContent + sep5 + toAppend.join("\n") + "\n");
38428
+ (0, import_node_fs62.writeFileSync)(verityCreds, verityContent + sep5 + toAppend.join("\n") + "\n");
38349
38429
  }
38350
- (0, import_node_fs61.rmSync)(gateCreds, { force: true });
38430
+ (0, import_node_fs62.rmSync)(gateCreds, { force: true });
38351
38431
  return toAppend.length;
38352
38432
  }
38353
38433
  function readFileSyncSafe(path) {
38354
38434
  try {
38355
- return (0, import_node_fs61.readFileSync)(path, "utf-8");
38435
+ return (0, import_node_fs62.readFileSync)(path, "utf-8");
38356
38436
  } catch {
38357
38437
  return "";
38358
38438
  }
@@ -38367,35 +38447,35 @@ function hasStagedChanges(root) {
38367
38447
  }
38368
38448
  function moveDir(from, to) {
38369
38449
  try {
38370
- (0, import_node_fs61.renameSync)(from, to);
38450
+ (0, import_node_fs62.renameSync)(from, to);
38371
38451
  } catch (err2) {
38372
38452
  if (err2.code !== "EXDEV") throw err2;
38373
- (0, import_node_fs61.cpSync)(from, to, { recursive: true });
38374
- (0, import_node_fs61.rmSync)(from, { recursive: true, force: true });
38453
+ (0, import_node_fs62.cpSync)(from, to, { recursive: true });
38454
+ (0, import_node_fs62.rmSync)(from, { recursive: true, force: true });
38375
38455
  }
38376
38456
  }
38377
38457
  function moveFile(from, to) {
38378
38458
  try {
38379
- (0, import_node_fs61.renameSync)(from, to);
38459
+ (0, import_node_fs62.renameSync)(from, to);
38380
38460
  } catch (err2) {
38381
38461
  if (err2.code !== "EXDEV") throw err2;
38382
- (0, import_node_fs61.cpSync)(from, to);
38383
- (0, import_node_fs61.rmSync)(from, { force: true });
38462
+ (0, import_node_fs62.cpSync)(from, to);
38463
+ (0, import_node_fs62.rmSync)(from, { force: true });
38384
38464
  }
38385
38465
  }
38386
38466
  function carryLegacyContents(gateDir, verityDir) {
38387
38467
  let copied = 0;
38388
38468
  const walk2 = (relDir) => {
38389
- const srcDir = (0, import_node_path45.join)(gateDir, relDir);
38390
- for (const entry of (0, import_node_fs61.readdirSync)(srcDir)) {
38391
- const rel = relDir ? (0, import_node_path45.join)(relDir, entry) : entry;
38392
- const src = (0, import_node_path45.join)(gateDir, rel);
38393
- const dest = (0, import_node_path45.join)(verityDir, rel);
38394
- if ((0, import_node_fs61.statSync)(src).isDirectory()) {
38469
+ const srcDir = (0, import_node_path46.join)(gateDir, relDir);
38470
+ for (const entry of (0, import_node_fs62.readdirSync)(srcDir)) {
38471
+ const rel = relDir ? (0, import_node_path46.join)(relDir, entry) : entry;
38472
+ const src = (0, import_node_path46.join)(gateDir, rel);
38473
+ const dest = (0, import_node_path46.join)(verityDir, rel);
38474
+ if ((0, import_node_fs62.statSync)(src).isDirectory()) {
38395
38475
  walk2(rel);
38396
- } else if (!(0, import_node_fs61.existsSync)(dest)) {
38397
- (0, import_node_fs61.mkdirSync)((0, import_node_path45.dirname)(dest), { recursive: true });
38398
- (0, import_node_fs61.cpSync)(src, dest);
38476
+ } else if (!(0, import_node_fs62.existsSync)(dest)) {
38477
+ (0, import_node_fs62.mkdirSync)((0, import_node_path46.dirname)(dest), { recursive: true });
38478
+ (0, import_node_fs62.cpSync)(src, dest);
38399
38479
  copied++;
38400
38480
  }
38401
38481
  }
@@ -38404,22 +38484,22 @@ function carryLegacyContents(gateDir, verityDir) {
38404
38484
  return copied;
38405
38485
  }
38406
38486
  async function needsMigration(root = repoRoot()) {
38407
- const gateDir = (0, import_node_path45.join)(root, ".gate");
38408
- const verityDir = (0, import_node_path45.join)(root, ".verity");
38409
- if ((0, import_node_fs61.existsSync)(gateDir) && !(0, import_node_fs61.existsSync)(verityDir)) return true;
38410
- if ((0, import_node_fs61.existsSync)(gateDir) && (0, import_node_fs61.existsSync)(verityDir)) {
38411
- if ((0, import_node_fs61.existsSync)((0, import_node_path45.join)(gateDir, "credentials")) && !(0, import_node_fs61.existsSync)((0, import_node_path45.join)(verityDir, "credentials"))) {
38487
+ const gateDir = (0, import_node_path46.join)(root, ".gate");
38488
+ const verityDir = (0, import_node_path46.join)(root, ".verity");
38489
+ if ((0, import_node_fs62.existsSync)(gateDir) && !(0, import_node_fs62.existsSync)(verityDir)) return true;
38490
+ if ((0, import_node_fs62.existsSync)(gateDir) && (0, import_node_fs62.existsSync)(verityDir)) {
38491
+ if ((0, import_node_fs62.existsSync)((0, import_node_path46.join)(gateDir, "credentials")) && !(0, import_node_fs62.existsSync)((0, import_node_path46.join)(verityDir, "credentials"))) {
38412
38492
  return true;
38413
38493
  }
38414
- if ((0, import_node_fs61.existsSync)((0, import_node_path45.join)(gateDir, "memory")) && !(0, import_node_fs61.existsSync)((0, import_node_path45.join)(verityDir, "memory"))) {
38494
+ if ((0, import_node_fs62.existsSync)((0, import_node_path46.join)(gateDir, "memory")) && !(0, import_node_fs62.existsSync)((0, import_node_path46.join)(verityDir, "memory"))) {
38415
38495
  return true;
38416
38496
  }
38417
38497
  }
38418
- const claudeMd = (0, import_node_path45.join)(root, "CLAUDE.md");
38419
- if ((0, import_node_fs61.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
38498
+ const claudeMd = (0, import_node_path46.join)(root, "CLAUDE.md");
38499
+ if ((0, import_node_fs62.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
38420
38500
  return true;
38421
38501
  }
38422
- if ((0, import_node_fs61.existsSync)((0, import_node_path45.join)(root, "GATE.md")) && !(0, import_node_fs61.existsSync)((0, import_node_path45.join)(root, "VERITY.md"))) {
38502
+ if ((0, import_node_fs62.existsSync)((0, import_node_path46.join)(root, "GATE.md")) && !(0, import_node_fs62.existsSync)((0, import_node_path46.join)(root, "VERITY.md"))) {
38423
38503
  return true;
38424
38504
  }
38425
38505
  if (await hasLegacyHooksAt(root)) return true;
@@ -38700,15 +38780,31 @@ async function promptMultiSelect(question, choices, fallback) {
38700
38780
  }
38701
38781
 
38702
38782
  // src/lib/prove/lean-install.ts
38703
- var import_node_fs62 = require("node:fs");
38783
+ var import_node_fs63 = require("node:fs");
38704
38784
  var import_node_crypto20 = require("node:crypto");
38705
38785
  var import_node_child_process18 = require("node:child_process");
38706
38786
  var import_node_os10 = require("node:os");
38707
- var import_node_path46 = require("node:path");
38787
+ var import_node_path47 = require("node:path");
38708
38788
  var import_promises18 = require("node:stream/promises");
38709
38789
  var import_node_stream = require("node:stream");
38710
38790
  var RELEASES = "https://releases.lean-lang.org/lean4";
38711
38791
  var LEAN_DOWNLOAD_SIZE = "\u2248800 MB download, 2.7 GB on disk";
38792
+ var DOWNLOAD_STALL_MS = 6e4;
38793
+ var LEAN_DISK_NEEDED_BYTES = 3.75 * 1024 ** 3;
38794
+ function freeBytes(dir) {
38795
+ let d = dir;
38796
+ for (let i2 = 0; i2 < 64; i2++) {
38797
+ try {
38798
+ const st = (0, import_node_fs63.statfsSync)(d);
38799
+ return Number(st.bavail) * Number(st.bsize);
38800
+ } catch {
38801
+ const up = (0, import_node_path47.join)(d, "..");
38802
+ if (up === d) return null;
38803
+ d = up;
38804
+ }
38805
+ }
38806
+ return null;
38807
+ }
38712
38808
  var LEAN_ASSET_SHA256 = {
38713
38809
  "v4.34.0": {
38714
38810
  "lean-4.34.0-darwin.zip": "75a2a4b8e3d35680e8f51fae5a42c79702f463dd73ee1520fb61e5a9143e336c",
@@ -38724,7 +38820,7 @@ function expectedSha256(asset, version = pinnedVersion()) {
38724
38820
  function sha256File(path) {
38725
38821
  return new Promise((resolve8, reject) => {
38726
38822
  const hash = (0, import_node_crypto20.createHash)("sha256");
38727
- (0, import_node_fs62.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve8(hash.digest("hex"))).on("error", reject);
38823
+ (0, import_node_fs63.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve8(hash.digest("hex"))).on("error", reject);
38728
38824
  });
38729
38825
  }
38730
38826
  async function verifyDownload(zip, asset, version = pinnedVersion()) {
@@ -38744,7 +38840,7 @@ function leanAssetName(version = pinnedVersion()) {
38744
38840
  return suffix ? `lean-${v}-${suffix}.zip` : null;
38745
38841
  }
38746
38842
  function pinnedVersionDir(env = process.env) {
38747
- return (0, import_node_path46.join)(verityLeanHome(env), pinnedVersion());
38843
+ return (0, import_node_path47.join)(verityLeanHome(env), pinnedVersion());
38748
38844
  }
38749
38845
  function lakeBinary() {
38750
38846
  return (0, import_node_os10.platform)() === "win32" ? "lake.exe" : "lake";
@@ -38755,29 +38851,44 @@ function unzip(zip, dest) {
38755
38851
  for (const [cmd, args2] of attempts) {
38756
38852
  try {
38757
38853
  (0, import_node_child_process18.execFileSync)(cmd, args2, { stdio: ["ignore", "ignore", "pipe"], timeout: 15 * 6e4 });
38758
- if ((0, import_node_fs62.readdirSync)(dest).length > 0) return { ok: true, via: cmd };
38854
+ if ((0, import_node_fs63.readdirSync)(dest).length > 0) return { ok: true, via: cmd };
38759
38855
  errors.push(`${cmd}: produced nothing`);
38760
38856
  } catch (err2) {
38761
38857
  errors.push(`${cmd}: ${String(err2.message).split("\n")[0].slice(0, 120)}`);
38762
38858
  try {
38763
- for (const e of (0, import_node_fs62.readdirSync)(dest)) (0, import_node_fs62.rmSync)((0, import_node_path46.join)(dest, e), { recursive: true, force: true });
38859
+ for (const e of (0, import_node_fs63.readdirSync)(dest)) (0, import_node_fs63.rmSync)((0, import_node_path47.join)(dest, e), { recursive: true, force: true });
38764
38860
  } catch {
38765
38861
  }
38766
38862
  }
38767
38863
  }
38768
38864
  return { ok: false, error: errors.join("; ") };
38769
38865
  }
38770
- async function download(url, dest, onProgress) {
38771
- const res = await fetch(url, { redirect: "follow" });
38772
- if (!res.ok || !res.body) throw new Error(`download failed: HTTP ${res.status}`);
38773
- const total = Number(res.headers.get("content-length")) || null;
38774
- let seen = 0;
38775
- const stream = import_node_stream.Readable.fromWeb(res.body);
38776
- stream.on("data", (chunk) => {
38777
- seen += chunk.length;
38778
- onProgress(seen, total);
38779
- });
38780
- await (0, import_promises18.pipeline)(stream, (0, import_node_fs62.createWriteStream)(dest));
38866
+ async function download(url, dest, onProgress, stallMs = DOWNLOAD_STALL_MS) {
38867
+ const ctrl = new AbortController();
38868
+ let timer;
38869
+ const arm = () => {
38870
+ clearTimeout(timer);
38871
+ timer = setTimeout(() => ctrl.abort(), stallMs);
38872
+ };
38873
+ arm();
38874
+ try {
38875
+ const res = await fetch(url, { redirect: "follow", signal: ctrl.signal });
38876
+ if (!res.ok || !res.body) throw new Error(`download failed: HTTP ${res.status}`);
38877
+ const total = Number(res.headers.get("content-length")) || null;
38878
+ let seen = 0;
38879
+ const stream = import_node_stream.Readable.fromWeb(res.body);
38880
+ stream.on("data", (chunk) => {
38881
+ arm();
38882
+ seen += chunk.length;
38883
+ onProgress(seen, total);
38884
+ });
38885
+ await (0, import_promises18.pipeline)(stream, (0, import_node_fs63.createWriteStream)(dest), { signal: ctrl.signal });
38886
+ } catch (err2) {
38887
+ if (ctrl.signal.aborted) throw new Error(`download stalled: nothing received for ${Math.round(stallMs / 1e3)} s`);
38888
+ throw err2;
38889
+ } finally {
38890
+ clearTimeout(timer);
38891
+ }
38781
38892
  }
38782
38893
  function inPlaceProgress(label2, write = (s) => process.stderr.write(s)) {
38783
38894
  let active = false;
@@ -38815,10 +38926,16 @@ async function installLean(opts = {}) {
38815
38926
  const dir = pinnedVersionDir(env);
38816
38927
  const url = `${RELEASES}/${pinnedVersion()}/${asset}`;
38817
38928
  const home = verityLeanHome(env);
38818
- const tmp = (0, import_node_path46.join)(home, ".tmp");
38819
- (0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
38820
- (0, import_node_fs62.mkdirSync)(tmp, { recursive: true });
38821
- const zip = (0, import_node_path46.join)(tmp, asset);
38929
+ const free = freeBytes(home);
38930
+ const needed = opts.minFreeBytes ?? LEAN_DISK_NEEDED_BYTES;
38931
+ if (free !== null && free < needed) {
38932
+ const gb = (n) => (n / 1024 ** 3).toFixed(1);
38933
+ return { ok: false, error: `not enough disk space for Lean: ${gb(free)} GB free where ${home} lives, needs about ${gb(needed)} GB` };
38934
+ }
38935
+ const tmp = (0, import_node_path47.join)(home, ".tmp");
38936
+ (0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
38937
+ (0, import_node_fs63.mkdirSync)(tmp, { recursive: true });
38938
+ const zip = (0, import_node_path47.join)(tmp, asset);
38822
38939
  say(`downloading ${url}`);
38823
38940
  let lastPct = -1;
38824
38941
  try {
@@ -38831,40 +38948,40 @@ async function installLean(opts = {}) {
38831
38948
  }
38832
38949
  });
38833
38950
  } catch (err2) {
38834
- (0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
38951
+ (0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
38835
38952
  return { ok: false, error: err2.message };
38836
38953
  }
38837
38954
  say("verifying checksum");
38838
38955
  const verified = await verifyDownload(zip, asset);
38839
38956
  if (!verified.ok) {
38840
- (0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
38957
+ (0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
38841
38958
  return { ok: false, error: verified.error };
38842
38959
  }
38843
38960
  say("unpacking (this takes a minute)");
38844
- const unpack = (0, import_node_path46.join)(tmp, "unpack");
38845
- (0, import_node_fs62.mkdirSync)(unpack);
38961
+ const unpack = (0, import_node_path47.join)(tmp, "unpack");
38962
+ (0, import_node_fs63.mkdirSync)(unpack);
38846
38963
  const unpacked = unzip(zip, unpack);
38847
38964
  if (!unpacked.ok) {
38848
- (0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
38965
+ (0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
38849
38966
  return { ok: false, error: `unpack failed: ${unpacked.error}` };
38850
38967
  }
38851
- const entries = (0, import_node_fs62.readdirSync)(unpack);
38852
- const top = entries.length === 1 && (0, import_node_fs62.statSync)((0, import_node_path46.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path46.join)(unpack, entries[0]) : unpack;
38853
- if (!(0, import_node_fs62.existsSync)((0, import_node_path46.join)(top, "bin", lakeBinary()))) {
38854
- (0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
38968
+ const entries = (0, import_node_fs63.readdirSync)(unpack);
38969
+ const top = entries.length === 1 && (0, import_node_fs63.statSync)((0, import_node_path47.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path47.join)(unpack, entries[0]) : unpack;
38970
+ if (!(0, import_node_fs63.existsSync)((0, import_node_path47.join)(top, "bin", lakeBinary()))) {
38971
+ (0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
38855
38972
  return { ok: false, error: "the archive did not contain bin/lake" };
38856
38973
  }
38857
- (0, import_node_fs62.rmSync)(dir, { recursive: true, force: true });
38858
- (0, import_node_fs62.mkdirSync)(home, { recursive: true });
38859
- (0, import_node_fs62.renameSync)(top, dir);
38860
- (0, import_node_fs62.rmSync)(tmp, { recursive: true, force: true });
38974
+ (0, import_node_fs63.rmSync)(dir, { recursive: true, force: true });
38975
+ (0, import_node_fs63.mkdirSync)(home, { recursive: true });
38976
+ (0, import_node_fs63.renameSync)(top, dir);
38977
+ (0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
38861
38978
  return { ok: true, dir };
38862
38979
  }
38863
38980
 
38864
38981
  // src/lib/remote-config.ts
38865
- var import_node_fs63 = require("node:fs");
38982
+ var import_node_fs64 = require("node:fs");
38866
38983
  var import_promises19 = require("node:fs/promises");
38867
- var import_node_path47 = require("node:path");
38984
+ var import_node_path48 = require("node:path");
38868
38985
  var import_yaml5 = __toESM2(require_dist());
38869
38986
  var IGNORE_RIDER = "verityignore";
38870
38987
  async function fetchRemoteSetup(opts) {
@@ -38909,7 +39026,7 @@ async function adoptRemoteSetup(found, opts) {
38909
39026
  written.push(STANDARD_FILE);
38910
39027
  if (rider !== null) {
38911
39028
  const localIgnore = projectPath(VERITYIGNORE_FILE);
38912
- if (!(0, import_node_fs63.existsSync)(localIgnore)) {
39029
+ if (!(0, import_node_fs64.existsSync)(localIgnore)) {
38913
39030
  await writeOut(VERITYIGNORE_FILE, rider);
38914
39031
  written.push(VERITYIGNORE_FILE);
38915
39032
  } else {
@@ -38942,7 +39059,7 @@ async function adoptRemoteSetup(found, opts) {
38942
39059
  }
38943
39060
  async function writeOut(relative6, body2) {
38944
39061
  const target = projectPath(relative6);
38945
- await (0, import_promises19.mkdir)((0, import_node_path47.dirname)(target), { recursive: true });
39062
+ await (0, import_promises19.mkdir)((0, import_node_path48.dirname)(target), { recursive: true });
38946
39063
  await (0, import_promises19.writeFile)(target, body2);
38947
39064
  }
38948
39065
  function describeRemote(found) {
@@ -39059,15 +39176,15 @@ async function runOptionalAuth(resolution, opts = {}) {
39059
39176
  }
39060
39177
  function resolveDataDir2() {
39061
39178
  const candidates2 = [
39062
- (0, import_node_path48.join)(__dirname, "..", "data"),
39179
+ (0, import_node_path49.join)(__dirname, "..", "data"),
39063
39180
  // installed: node_modules/@codacy/verity-cli/data
39064
- (0, import_node_path48.join)(__dirname, "..", "..", "data"),
39181
+ (0, import_node_path49.join)(__dirname, "..", "..", "data"),
39065
39182
  // edge case: nested resolution
39066
- (0, import_node_path48.join)(process.cwd(), "cli", "data")
39183
+ (0, import_node_path49.join)(process.cwd(), "cli", "data")
39067
39184
  // local dev: running from repo root
39068
39185
  ];
39069
39186
  for (const candidate of candidates2) {
39070
- if ((0, import_node_fs64.existsSync)((0, import_node_path48.join)(candidate, "skills"))) {
39187
+ if ((0, import_node_fs65.existsSync)((0, import_node_path49.join)(candidate, "skills"))) {
39071
39188
  return candidate;
39072
39189
  }
39073
39190
  }
@@ -39083,9 +39200,9 @@ async function skillIsCurrent(src, dest) {
39083
39200
  const list2 = (dir) => {
39084
39201
  const out2 = [];
39085
39202
  const walk2 = (d, prefix) => {
39086
- for (const e of (0, import_node_fs64.readdirSync)(d, { withFileTypes: true })) {
39203
+ for (const e of (0, import_node_fs65.readdirSync)(d, { withFileTypes: true })) {
39087
39204
  const rel = prefix ? `${prefix}/${e.name}` : e.name;
39088
- if (e.isDirectory()) walk2((0, import_node_path48.join)(d, e.name), rel);
39205
+ if (e.isDirectory()) walk2((0, import_node_path49.join)(d, e.name), rel);
39089
39206
  else if (e.isFile()) out2.push(rel);
39090
39207
  }
39091
39208
  };
@@ -39096,8 +39213,8 @@ async function skillIsCurrent(src, dest) {
39096
39213
  const shipped = list2(src);
39097
39214
  if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
39098
39215
  for (const rel of shipped) {
39099
- const a = await (0, import_promises20.readFile)((0, import_node_path48.join)(src, rel), "utf-8");
39100
- const b = await (0, import_promises20.readFile)((0, import_node_path48.join)(dest, rel), "utf-8");
39216
+ const a = await (0, import_promises20.readFile)((0, import_node_path49.join)(src, rel), "utf-8");
39217
+ const b = await (0, import_promises20.readFile)((0, import_node_path49.join)(dest, rel), "utf-8");
39101
39218
  if (a !== b) return false;
39102
39219
  }
39103
39220
  return true;
@@ -39123,8 +39240,10 @@ var INTENSITY_CHOICES = [
39123
39240
  { id: "thorough", label: "thorough", hint: "all tools, all rules (~15s)" }
39124
39241
  ];
39125
39242
  var FORMAL_CHOICES = [
39126
- { id: "yes", label: "yes", hint: "a Lean model of the riskiest changed function; blocks only on a REPRODUCED counterexample", recommended: true },
39127
- { id: "no", label: "no", hint: "enable later with: verity config formal push" }
39243
+ { id: "yes", label: "yes", hint: "a Lean model of the riskiest changed function; blocks only on a REPRODUCED counterexample" },
39244
+ // No is the default (review of #255): "yes" downloads ≈800 MB and unpacks
39245
+ // 2.7 GB, and a bare Enter must never do that.
39246
+ { id: "no", label: "no", hint: "enable later with: verity config formal push", recommended: true }
39128
39247
  ];
39129
39248
  var MOMENT_CHOICES = [
39130
39249
  { id: "stop", label: "On stop", hint: "after every agent turn \u2014 fast feedback while you work", recommended: true },
@@ -39298,7 +39417,7 @@ async function synthesizeLocally(opts) {
39298
39417
  async function healStaleAnalysisConfig(globals) {
39299
39418
  const configPath = projectPath(CODACY_CONFIG_FILE);
39300
39419
  const standardPath = projectPath(STANDARD_FILE);
39301
- if (!(0, import_node_fs64.existsSync)(configPath) || !(0, import_node_fs64.existsSync)(standardPath)) return;
39420
+ if (!(0, import_node_fs65.existsSync)(configPath) || !(0, import_node_fs65.existsSync)(standardPath)) return;
39302
39421
  const validation = validatePatternIds();
39303
39422
  if (validation.status !== "invalid") return;
39304
39423
  printWarn(" Your analysis config names pattern ids that no longer resolve \u2014 those tools were");
@@ -39395,17 +39514,17 @@ async function handoffToSetup(enabled, claudeInstalled) {
39395
39514
  async function installSkills(force, step) {
39396
39515
  step("Installing skills");
39397
39516
  const dataDir = resolveDataDir2();
39398
- const skillsSource = (0, import_node_path48.join)(dataDir, "skills");
39517
+ const skillsSource = (0, import_node_path49.join)(dataDir, "skills");
39399
39518
  const skillsDest = ".claude/skills";
39400
39519
  let skillsInstalled = 0;
39401
39520
  for (const skill of SKILLS) {
39402
- const src = (0, import_node_path48.join)(skillsSource, skill);
39403
- const dest = (0, import_node_path48.join)(skillsDest, skill);
39404
- if (!(0, import_node_fs64.existsSync)(src)) {
39521
+ const src = (0, import_node_path49.join)(skillsSource, skill);
39522
+ const dest = (0, import_node_path49.join)(skillsDest, skill);
39523
+ if (!(0, import_node_fs65.existsSync)(src)) {
39405
39524
  printWarn(` Skill data not found: ${skill}`);
39406
39525
  continue;
39407
39526
  }
39408
- if ((0, import_node_fs64.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
39527
+ if ((0, import_node_fs65.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
39409
39528
  skillsInstalled++;
39410
39529
  continue;
39411
39530
  }
@@ -39526,16 +39645,24 @@ async function scaffoldProject(step, defaultsOnly, pluginMode, given = {}) {
39526
39645
  }
39527
39646
  async function offerFormalVerification(defaultsOnly, pluginMode) {
39528
39647
  const cfg = readProjectConfig();
39529
- const toolchain = findToolchain();
39648
+ if (cfg.formal_refused) {
39649
+ printWarn(` Formal verification: off \u2014 ${formalRefusalMessage(cfg.formal_refused)}`);
39650
+ return;
39651
+ }
39530
39652
  if (cfg.formal === "push") {
39531
- if (toolchain) printInfo(" Formal verification at push \u2713");
39653
+ if (findToolchain()) printInfo(" Formal verification at push \u2713");
39532
39654
  else printWarn(" Formal verification is on but Lean is missing \u2014 run: verity lean install");
39533
39655
  return;
39534
39656
  }
39657
+ if (cfg.formal === "off") {
39658
+ printInfo(" Formal verification: off (enable with: verity config formal push)");
39659
+ return;
39660
+ }
39535
39661
  if (defaultsOnly || !interactive()) {
39536
39662
  printInfo(" Formal verification (a model-based bug finder at push): off \u2014 enable with: verity config formal push");
39537
39663
  return;
39538
39664
  }
39665
+ const toolchain = findToolchain();
39539
39666
  console.log("");
39540
39667
  console.log(" Formal verification review \u2014 a model-based bug finder for your riskiest code.");
39541
39668
  console.log(" At push, Verity picks the riskiest changed function, checks a small model of");
@@ -39543,9 +39670,10 @@ async function offerFormalVerification(defaultsOnly, pluginMode) {
39543
39670
  console.log(" Verity for that). Only a reproduced bug can block; most pushes get no model.");
39544
39671
  console.log(` Adds /verity-prove <worry> to check any code on demand.${toolchain ? "" : ` Needs to install Lean 4 (${LEAN_DOWNLOAD_SIZE}) on "yes".`}`);
39545
39672
  console.log("");
39546
- const wants = await promptChoice("Formal verification at push?", FORMAL_CHOICES, "yes");
39673
+ const wants = await promptChoice("Formal verification at push?", FORMAL_CHOICES, "no");
39547
39674
  if (wants === "yes" && pluginMode) printInfo(" Plugin: the push check works now; /verity:verity-prove arrives with the plugin's next release.");
39548
39675
  if (wants !== "yes") {
39676
+ writeProjectConfig({ formal: "off" });
39549
39677
  printInfo(" Formal verification: off (enable later with: verity config formal push)");
39550
39678
  return;
39551
39679
  }
@@ -39596,7 +39724,7 @@ function registerInitCommand(program2) {
39596
39724
  const staleMarker = clearStalePluginMarker();
39597
39725
  const pluginMode = opts.plugin === false ? false : opts.pluginMode ?? pluginActiveHere();
39598
39726
  const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
39599
- const isProject = projectMarkers.some((m) => (0, import_node_fs64.existsSync)(m));
39727
+ const isProject = projectMarkers.some((m) => (0, import_node_fs65.existsSync)(m));
39600
39728
  if (!isProject) {
39601
39729
  printError("No project detected in the current directory.");
39602
39730
  printInfo('Run "verity init" from your project root.');
@@ -39699,7 +39827,7 @@ function registerInitCommand(program2) {
39699
39827
  untrackMemory: opts.untrackMemory === true,
39700
39828
  untrackState: opts.untrackState === true
39701
39829
  });
39702
- const globalVerityDir = (0, import_node_path48.join)(process.env.HOME ?? "", ".verity");
39830
+ const globalVerityDir = (0, import_node_path49.join)(process.env.HOME ?? "", ".verity");
39703
39831
  await (0, import_promises20.mkdir)(globalVerityDir, { recursive: true });
39704
39832
  console.log("");
39705
39833
  step("Wiring Claude Code hooks");
@@ -39774,7 +39902,7 @@ function registerInitCommand(program2) {
39774
39902
  }
39775
39903
  step("Your project's Standard");
39776
39904
  let haveStandard = false;
39777
- if ((0, import_node_fs64.existsSync)(projectPath(STANDARD_FILE))) {
39905
+ if ((0, import_node_fs65.existsSync)(projectPath(STANDARD_FILE))) {
39778
39906
  printInfo(" This project already has .verity/standard.yaml \u2014 keeping it.");
39779
39907
  haveStandard = true;
39780
39908
  } else {
@@ -39804,7 +39932,7 @@ function registerInitCommand(program2) {
39804
39932
  ...telemetryChoice ? { telemetry: telemetryChoice } : {},
39805
39933
  init: {
39806
39934
  completed_at: (/* @__PURE__ */ new Date()).toISOString(),
39807
- cli_version: true ? "0.34.0-experimental.007b74f" : "dev"
39935
+ cli_version: true ? "0.34.0-experimental.37a6dcf" : "dev"
39808
39936
  }
39809
39937
  });
39810
39938
  } catch (err2) {
@@ -39854,8 +39982,8 @@ function registerInitCommand(program2) {
39854
39982
  }
39855
39983
 
39856
39984
  // src/commands/uninstall.ts
39857
- var import_node_fs65 = require("node:fs");
39858
- var import_node_path49 = require("node:path");
39985
+ var import_node_fs66 = require("node:fs");
39986
+ var import_node_path50 = require("node:path");
39859
39987
  function registerUninstallCommand(program2) {
39860
39988
  program2.command("uninstall").description("Remove Verity from this project (skills, hooks, .verity/, VERITY.md)").option("--dry-run", "Show what would be removed without doing it").option("--purge-global", "Also remove ~/.verity/ (deletes saved tokens \u2014 reconnect requires re-registration)").option("--keep-verity-md", "Keep the project root VERITY.md file").action(async (opts) => {
39861
39989
  const dryRun = opts.dryRun ?? false;
@@ -39864,11 +39992,11 @@ function registerUninstallCommand(program2) {
39864
39992
  const actions = [];
39865
39993
  const skillsRoot = projectPath(".claude/skills");
39866
39994
  for (const name2 of PROJECT_SKILL_NAMES) {
39867
- const dir = (0, import_node_path49.join)(skillsRoot, name2);
39868
- if ((0, import_node_fs65.existsSync)(dir)) {
39995
+ const dir = (0, import_node_path50.join)(skillsRoot, name2);
39996
+ if ((0, import_node_fs66.existsSync)(dir)) {
39869
39997
  actions.push({
39870
39998
  label: `Remove .claude/skills/${name2}/`,
39871
- apply: () => (0, import_node_fs65.rmSync)(dir, { recursive: true, force: true })
39999
+ apply: () => (0, import_node_fs66.rmSync)(dir, { recursive: true, force: true })
39872
40000
  });
39873
40001
  }
39874
40002
  }
@@ -39882,24 +40010,24 @@ function registerUninstallCommand(program2) {
39882
40010
  });
39883
40011
  }
39884
40012
  const verityDir = projectPath(VERITY_DIR);
39885
- if ((0, import_node_fs65.existsSync)(verityDir)) {
40013
+ if ((0, import_node_fs66.existsSync)(verityDir)) {
39886
40014
  actions.push({
39887
40015
  label: `Remove ${VERITY_DIR}/`,
39888
- apply: () => (0, import_node_fs65.rmSync)(verityDir, { recursive: true, force: true })
40016
+ apply: () => (0, import_node_fs66.rmSync)(verityDir, { recursive: true, force: true })
39889
40017
  });
39890
40018
  }
39891
40019
  if (!keepVerityMd) {
39892
40020
  const verityMd = projectPath(VERITY_MD_FILE);
39893
- if ((0, import_node_fs65.existsSync)(verityMd)) {
40021
+ if ((0, import_node_fs66.existsSync)(verityMd)) {
39894
40022
  actions.push({
39895
40023
  label: `Remove ${VERITY_MD_FILE}`,
39896
- apply: () => (0, import_node_fs65.rmSync)(verityMd, { force: true })
40024
+ apply: () => (0, import_node_fs66.rmSync)(verityMd, { force: true })
39897
40025
  });
39898
40026
  }
39899
40027
  }
39900
40028
  const cleanupEmptyDir = (path) => {
39901
- if ((0, import_node_fs65.existsSync)(path) && (0, import_node_fs65.statSync)(path).isDirectory() && (0, import_node_fs65.readdirSync)(path).length === 0) {
39902
- (0, import_node_fs65.rmdirSync)(path);
40029
+ if ((0, import_node_fs66.existsSync)(path) && (0, import_node_fs66.statSync)(path).isDirectory() && (0, import_node_fs66.readdirSync)(path).length === 0) {
40030
+ (0, import_node_fs66.rmdirSync)(path);
39903
40031
  }
39904
40032
  };
39905
40033
  actions.push({
@@ -39910,11 +40038,11 @@ function registerUninstallCommand(program2) {
39910
40038
  }
39911
40039
  });
39912
40040
  const home = process.env.HOME ?? "";
39913
- const globalVerityDir = (0, import_node_path49.join)(home, ".verity");
39914
- if (purgeGlobal && (0, import_node_fs65.existsSync)(globalVerityDir)) {
40041
+ const globalVerityDir = (0, import_node_path50.join)(home, ".verity");
40042
+ if (purgeGlobal && (0, import_node_fs66.existsSync)(globalVerityDir)) {
39915
40043
  actions.push({
39916
40044
  label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
39917
- apply: () => (0, import_node_fs65.rmSync)(globalVerityDir, { recursive: true, force: true })
40045
+ apply: () => (0, import_node_fs66.rmSync)(globalVerityDir, { recursive: true, force: true })
39918
40046
  });
39919
40047
  }
39920
40048
  if (actions.length === 0) {
@@ -40108,8 +40236,8 @@ function registerTaskCommands(program2) {
40108
40236
  }
40109
40237
 
40110
40238
  // src/commands/reset.ts
40111
- var import_node_fs66 = require("node:fs");
40112
- var import_node_path50 = require("node:path");
40239
+ var import_node_fs67 = require("node:fs");
40240
+ var import_node_path51 = require("node:path");
40113
40241
  function registerResetCommand(program2) {
40114
40242
  program2.command("reset").description("Close the current task and clear transient state").option("--keep-task", "Only purge caches; leave the current task open").option("--all", "Also purge diagnostic logs (.verity/.logs/)").action(async (opts) => {
40115
40243
  const globals = program2.opts();
@@ -40146,11 +40274,11 @@ function registerResetCommand(program2) {
40146
40274
  }
40147
40275
  const cacheDir = projectPath(CACHE_DIR);
40148
40276
  let purged = 0;
40149
- if ((0, import_node_fs66.existsSync)(cacheDir)) {
40150
- for (const entry of (0, import_node_fs66.readdirSync)(cacheDir)) {
40277
+ if ((0, import_node_fs67.existsSync)(cacheDir)) {
40278
+ for (const entry of (0, import_node_fs67.readdirSync)(cacheDir)) {
40151
40279
  if (entry.startsWith("pending-")) {
40152
40280
  try {
40153
- (0, import_node_fs66.unlinkSync)((0, import_node_path50.join)(cacheDir, entry));
40281
+ (0, import_node_fs67.unlinkSync)((0, import_node_path51.join)(cacheDir, entry));
40154
40282
  purged++;
40155
40283
  } catch {
40156
40284
  }
@@ -40165,19 +40293,19 @@ function registerResetCommand(program2) {
40165
40293
  projectPath(`${VERITY_DIR}/.last-analysis`)
40166
40294
  ];
40167
40295
  for (const file of filesToClear) {
40168
- if ((0, import_node_fs66.existsSync)(file)) {
40296
+ if ((0, import_node_fs67.existsSync)(file)) {
40169
40297
  try {
40170
- (0, import_node_fs66.writeFileSync)(file, "");
40298
+ (0, import_node_fs67.writeFileSync)(file, "");
40171
40299
  } catch {
40172
40300
  }
40173
40301
  }
40174
40302
  }
40175
40303
  if (opts.all) {
40176
40304
  const logsDir = projectPath(`${VERITY_DIR}/.logs`);
40177
- if ((0, import_node_fs66.existsSync)(logsDir)) {
40178
- for (const entry of (0, import_node_fs66.readdirSync)(logsDir)) {
40305
+ if ((0, import_node_fs67.existsSync)(logsDir)) {
40306
+ for (const entry of (0, import_node_fs67.readdirSync)(logsDir)) {
40179
40307
  try {
40180
- (0, import_node_fs66.unlinkSync)((0, import_node_path50.join)(logsDir, entry));
40308
+ (0, import_node_fs67.unlinkSync)((0, import_node_path51.join)(logsDir, entry));
40181
40309
  } catch {
40182
40310
  }
40183
40311
  }
@@ -40189,7 +40317,7 @@ function registerResetCommand(program2) {
40189
40317
  }
40190
40318
 
40191
40319
  // src/commands/reflect.ts
40192
- var import_node_fs67 = require("node:fs");
40320
+ var import_node_fs68 = require("node:fs");
40193
40321
 
40194
40322
  // src/lib/reflection-globs.ts
40195
40323
  var MAX_GLOBS = 6;
@@ -40227,7 +40355,7 @@ async function writeNodeToDisk(args2) {
40227
40355
  { treePaths: listTrackedFiles(), recordBaseline: false }
40228
40356
  );
40229
40357
  if (written === 0) return false;
40230
- return (0, import_node_fs67.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
40358
+ return (0, import_node_fs68.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
40231
40359
  } catch {
40232
40360
  return false;
40233
40361
  }
@@ -40659,9 +40787,9 @@ function registerRunCommand(program2) {
40659
40787
  }
40660
40788
 
40661
40789
  // src/commands/telemetry.ts
40662
- var import_node_fs68 = require("node:fs");
40790
+ var import_node_fs69 = require("node:fs");
40663
40791
  async function recordTelemetryChoice(choice) {
40664
- if (!(0, import_node_fs68.existsSync)(projectPath(SETUP_STATE_FILE))) return;
40792
+ if (!(0, import_node_fs69.existsSync)(projectPath(SETUP_STATE_FILE))) return;
40665
40793
  try {
40666
40794
  if ((await readSetupState())?.telemetry === choice) return;
40667
40795
  await writeSetupState({ telemetry: choice });
@@ -40738,8 +40866,8 @@ function registerTelemetryCommands(program2) {
40738
40866
  }
40739
40867
 
40740
40868
  // src/commands/prove.ts
40741
- var import_node_fs69 = require("node:fs");
40742
- var import_node_path51 = require("node:path");
40869
+ var import_node_fs70 = require("node:fs");
40870
+ var import_node_path52 = require("node:path");
40743
40871
 
40744
40872
  // src/lib/prove/hint-pool.ts
40745
40873
  var STOP2 = /* @__PURE__ */ new Set([
@@ -40875,7 +41003,7 @@ function registerProveCommand(program2) {
40875
41003
  process.exit(2);
40876
41004
  }
40877
41005
  const limit = Math.max(1, Math.min(50, Number(opts.limit) || 10));
40878
- let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path51.relative)(root, (0, import_node_path51.resolve)(p)) || ".") });
41006
+ let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path52.relative)(root, (0, import_node_path52.resolve)(p)) || ".") });
40879
41007
  if (opts.hint && paths.length === 0) {
40880
41008
  const hit = hintMatches(root, opts.hint);
40881
41009
  if (hit.files.length > 0) {
@@ -40929,7 +41057,7 @@ function registerProveCommand(program2) {
40929
41057
  });
40930
41058
  prove.command("check [model]").description("Elaborate a model (or every model) with the local Lean toolchain and report each property").option("--timeout <ms>", "Per-model timeout in ms", "120000").option("--json", "Machine-readable output").action((model, opts) => {
40931
41059
  const root = repoRoot();
40932
- if (!(0, import_node_fs69.existsSync)((0, import_node_path51.join)(root, PROOFS_DIR, "lakefile.toml"))) {
41060
+ if (!(0, import_node_fs70.existsSync)((0, import_node_path52.join)(root, PROOFS_DIR, "lakefile.toml"))) {
40933
41061
  printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
40934
41062
  process.exit(2);
40935
41063
  }
@@ -40953,7 +41081,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
40953
41081
  const reports = [];
40954
41082
  for (const f of files) {
40955
41083
  const report = checkModel(tc, root, f, { timeoutMs: Math.max(1e3, Number(opts.timeout) || 12e4) });
40956
- report.file = (0, import_node_path51.relative)(root, f);
41084
+ report.file = (0, import_node_path52.relative)(root, f);
40957
41085
  reports.push(report);
40958
41086
  try {
40959
41087
  writeResult(root, report);
@@ -40991,7 +41119,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
40991
41119
  printError("Not logged in \u2014 replays run on the Verity service. Run `verity login` first.");
40992
41120
  process.exit(2);
40993
41121
  }
40994
- if (!(0, import_node_fs69.existsSync)((0, import_node_path51.join)(root, PROOFS_DIR, "lakefile.toml"))) {
41122
+ if (!(0, import_node_fs70.existsSync)((0, import_node_path52.join)(root, PROOFS_DIR, "lakefile.toml"))) {
40995
41123
  printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
40996
41124
  process.exit(2);
40997
41125
  }
@@ -41022,7 +41150,7 @@ ${report.error ?? ""}`);
41022
41150
  printInfo(opts.property ? `${model} ${opts.property} has no counterexample to replay` : `${model} has no counterexample to replay`);
41023
41151
  return;
41024
41152
  }
41025
- const modelSource = readRegularFileInRoot(root, (0, import_node_path51.relative)(root, file), 512 * 1024);
41153
+ const modelSource = readRegularFileInRoot(root, (0, import_node_path52.relative)(root, file), 512 * 1024);
41026
41154
  if (!opts.json) printInfo(`replaying ${targets.length} counterexample(s) of ${model} in network-less containers (${Math.min(targets.length, REPLAY_CONCURRENCY)} at a time)\u2026`);
41027
41155
  const outcomes = await mapPool(targets, REPLAY_CONCURRENCY, async (p) => {
41028
41156
  const brief = buildReplayBrief(root, report, p, modelSource.ok ? modelSource.content : "");
@@ -41042,7 +41170,7 @@ ${report.error ?? ""}`);
41042
41170
  });
41043
41171
  prove.command("auto [files...]").description("The formal phase the pre-push guard runs: select one risky symbol among changed files, generate a model, check it, replay counterexamples (default files: the commits ahead of upstream)").option("--deadline <ms>", "Budget for the whole phase", "170000").option("--json", "Machine-readable output").action(async (paths, opts) => {
41044
41172
  const root = repoRoot();
41045
- let files = paths.map((p) => (0, import_node_path51.relative)(root, (0, import_node_path51.resolve)(p)));
41173
+ let files = paths.map((p) => (0, import_node_path52.relative)(root, (0, import_node_path52.resolve)(p)));
41046
41174
  if (files.length === 0) {
41047
41175
  const ahead = runGitSync(root, ["diff", "--name-only", "@{upstream}...HEAD"]);
41048
41176
  const fallback = ahead.ok ? ahead : runGitSync(root, ["diff", "--name-only", "HEAD~1..HEAD"]);
@@ -41102,7 +41230,7 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
41102
41230
  let revise;
41103
41231
  if (opts.revise) {
41104
41232
  const existing = resolveModelFile(root, opts.revise);
41105
- const src = existing ? readRegularFileInRoot(root, (0, import_node_path51.relative)(root, existing), 64 * 1024) : null;
41233
+ const src = existing ? readRegularFileInRoot(root, (0, import_node_path52.relative)(root, existing), 64 * 1024) : null;
41106
41234
  if (!src || !src.ok || !opts.note) {
41107
41235
  printError('--revise needs an existing model under Models/ and --note "<what the replay showed>"');
41108
41236
  process.exit(2);
@@ -41141,8 +41269,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
41141
41269
  });
41142
41270
  prove.command("waive <file>").description("Dismiss the remembered formal finding(s) on a file for its current bytes \u2014 the accepted-risk path for a formal block").requiredOption("--reason <text>", "The human disposition this records (reviewer finding, ADR, \u2026)").action((file, opts) => {
41143
41271
  const root = repoRoot();
41144
- const rel0 = (0, import_node_path51.relative)(root, (0, import_node_path51.isAbsolute)(file) ? file : (0, import_node_path51.join)(root, file)).replace(/\\/g, "/");
41145
- const rel = rel0.startsWith("..") || (0, import_node_path51.isAbsolute)(rel0) ? null : rel0;
41272
+ const rel0 = (0, import_node_path52.relative)(root, (0, import_node_path52.isAbsolute)(file) ? file : (0, import_node_path52.join)(root, file)).replace(/\\/g, "/");
41273
+ const rel = rel0.startsWith("..") || (0, import_node_path52.isAbsolute)(rel0) ? null : rel0;
41146
41274
  if (!rel) {
41147
41275
  printError(`${file} is not inside this repository`);
41148
41276
  process.exit(2);
@@ -41158,8 +41286,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
41158
41286
  });
41159
41287
  prove.command("hash <file>").description("Print the sha256 of a file, for a model header (Verity.model \u2026 sha256). Path is REPO-relative, as in the header").action((file) => {
41160
41288
  const root = repoRoot();
41161
- const rel = (0, import_node_path51.relative)(root, (0, import_node_path51.isAbsolute)(file) ? file : (0, import_node_path51.join)(root, file));
41162
- const digest = rel.startsWith("..") || (0, import_node_path51.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
41289
+ const rel = (0, import_node_path52.relative)(root, (0, import_node_path52.isAbsolute)(file) ? file : (0, import_node_path52.join)(root, file));
41290
+ const digest = rel.startsWith("..") || (0, import_node_path52.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
41163
41291
  if (!digest) {
41164
41292
  printError(`Cannot hash ${file}: it must be a regular file inside this repository (not a symlink)`);
41165
41293
  process.exit(2);
@@ -41193,10 +41321,10 @@ function refreshScaffold(root) {
41193
41321
  }
41194
41322
 
41195
41323
  // src/commands/lean.ts
41196
- var import_node_fs70 = require("node:fs");
41324
+ var import_node_fs71 = require("node:fs");
41197
41325
  var import_node_child_process20 = require("node:child_process");
41198
41326
  var import_node_os11 = require("node:os");
41199
- var import_node_path52 = require("node:path");
41327
+ var import_node_path53 = require("node:path");
41200
41328
  function registerLeanCommand(program2) {
41201
41329
  const lean = program2.command("lean").description("The Lean 4 toolchain formal verification needs (managed download, pinned by this CLI)");
41202
41330
  lean.command("status").option("--json", "Machine-readable output").description("Which toolchain would run, and whether it matches the pinned version").action((opts) => {
@@ -41213,7 +41341,7 @@ function registerLeanCommand(program2) {
41213
41341
  const managed = pinnedVersionDir();
41214
41342
  const matches = version ? version.includes(pin) : false;
41215
41343
  if (opts.json) {
41216
- printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs70.existsSync)((0, import_node_path52.join)(managed, "bin")), asset: leanAssetName() });
41344
+ printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs71.existsSync)((0, import_node_path53.join)(managed, "bin")), asset: leanAssetName() });
41217
41345
  return;
41218
41346
  }
41219
41347
  printInfo(`pinned: ${LEAN_TOOLCHAIN}`);
@@ -41231,7 +41359,7 @@ function registerLeanCommand(program2) {
41231
41359
  process.exit(2);
41232
41360
  }
41233
41361
  const dir = pinnedVersionDir();
41234
- if ((0, import_node_fs70.existsSync)((0, import_node_path52.join)(dir, "bin", "lake")) && !opts.force) {
41362
+ if ((0, import_node_fs71.existsSync)((0, import_node_path53.join)(dir, "bin", "lake")) && !opts.force) {
41235
41363
  printInfo(`already installed at ${dir}`);
41236
41364
  return;
41237
41365
  }
@@ -41267,18 +41395,18 @@ function registerLeanCommand(program2) {
41267
41395
  });
41268
41396
  lean.command("remove").description("Delete the Verity-managed toolchain for the pinned version").action(() => {
41269
41397
  const dir = pinnedVersionDir();
41270
- if (!(0, import_node_fs70.existsSync)(dir)) {
41398
+ if (!(0, import_node_fs71.existsSync)(dir)) {
41271
41399
  printInfo("nothing to remove");
41272
41400
  return;
41273
41401
  }
41274
- (0, import_node_fs70.rmSync)(dir, { recursive: true, force: true });
41402
+ (0, import_node_fs71.rmSync)(dir, { recursive: true, force: true });
41275
41403
  printInfo(`removed ${dir}`);
41276
41404
  });
41277
41405
  }
41278
41406
 
41279
41407
  // src/cli.ts
41280
- program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.007b74f").option("--token <token>", "Override authentication token").option("--service-url <url>", "Override service URL").option("--verbose", "Log HTTP requests/responses to stderr").hook("preAction", async (_thisCommand, actionCommand) => {
41281
- installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.007b74f");
41408
+ program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.37a6dcf").option("--token <token>", "Override authentication token").option("--service-url <url>", "Override service URL").option("--verbose", "Log HTTP requests/responses to stderr").hook("preAction", async (_thisCommand, actionCommand) => {
41409
+ installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.37a6dcf");
41282
41410
  setUserNamedServiceUrl(program.opts().serviceUrl);
41283
41411
  try {
41284
41412
  await foldLegacyLocalCredential();