@codacy/verity-cli 0.34.1-experimental.89100b5 → 0.34.1-experimental.c910405

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/README.md +38 -0
  2. package/bin/verity.js +481 -313
  3. package/package.json +1 -1
package/bin/verity.js CHANGED
@@ -13782,9 +13782,9 @@ ${JSON.stringify(symbolNames, null, 2)}`);
13782
13782
  PatternStructure: 5
13783
13783
  };
13784
13784
  var QueryError = class _QueryError extends Error {
13785
- constructor(kind, info2, index, length) {
13786
- super(_QueryError.formatMessage(kind, info2));
13787
- this.kind = kind;
13785
+ constructor(kind2, info2, index, length) {
13786
+ super(_QueryError.formatMessage(kind2, info2));
13787
+ this.kind = kind2;
13788
13788
  this.info = info2;
13789
13789
  this.index = index;
13790
13790
  this.length = length;
@@ -13798,8 +13798,8 @@ ${JSON.stringify(symbolNames, null, 2)}`);
13798
13798
  __name(this, "QueryError");
13799
13799
  }
13800
13800
  /** Formats an error message based on the error kind and info */
13801
- static formatMessage(kind, info2) {
13802
- switch (kind) {
13801
+ static formatMessage(kind2, info2) {
13802
+ switch (kind2) {
13803
13803
  case QueryErrorKind.NodeName:
13804
13804
  return `Bad node name '${info2.word}'`;
13805
13805
  case QueryErrorKind.FieldName:
@@ -16278,8 +16278,8 @@ async function reportLoginOutcome(out2, opts = {}) {
16278
16278
  printWarn(" repository will report that account. Remove its line from ~/.verity/credentials");
16279
16279
  printWarn(" only if you want this repository on the login you just completed.");
16280
16280
  } else {
16281
- const kind = rec.userId != null ? "superseded per-repository" : "anonymous project-specific";
16282
- printWarn(` Note: this repository has a ${kind} credential that takes`);
16281
+ const kind2 = rec.userId != null ? "superseded per-repository" : "anonymous project-specific";
16282
+ printWarn(` Note: this repository has a ${kind2} credential that takes`);
16283
16283
  printWarn(" precedence here. Remove its line from ~/.verity/credentials to use your login.");
16284
16284
  printWarn(' Until then, "verity login" in this repository re-runs the full GitHub flow');
16285
16285
  printWarn(" every time.");
@@ -16851,6 +16851,7 @@ var VERITY_SESSION_END_HOOK = {
16851
16851
  command: "verity session end"
16852
16852
  };
16853
16853
  var GUARD_TIMEOUT = 300;
16854
+ var GUARD_TIMEOUT_MS = GUARD_TIMEOUT * 1e3;
16854
16855
  function buildGuardHook(on) {
16855
16856
  return {
16856
16857
  type: "command",
@@ -17606,9 +17607,9 @@ function pointsAtVerity(src) {
17606
17607
  }
17607
17608
  function describeSource(src) {
17608
17609
  if (!src || typeof src !== "object") return "an unrecognised source";
17609
- const kind = typeof src.source === "string" ? src.source : "unknown";
17610
+ const kind2 = typeof src.source === "string" ? src.source : "unknown";
17610
17611
  const target = typeof src.repo === "string" && src.repo || typeof src.url === "string" && src.url || typeof src.path === "string" && src.path || "";
17611
- return target ? `${kind} \u2192 ${target}` : kind;
17612
+ return target ? `${kind2} \u2192 ${target}` : kind2;
17612
17613
  }
17613
17614
  function legacyMarketplaceInstall() {
17614
17615
  const plugins = readJsonFile((0, import_node_path11.join)(claudeConfigDir(), "plugins", "installed_plugins.json"))?.plugins;
@@ -18532,8 +18533,8 @@ function slugify(s) {
18532
18533
  return s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
18533
18534
  }
18534
18535
  function orgNodePath(node) {
18535
- const kind = ORG_KINDS.includes(node.kind) ? node.kind : "domain";
18536
- return `${kind}/${slugify(node.title) || "claim"}-${node.tag_id.replace(/-/g, "").slice(0, 8)}.md`;
18536
+ const kind2 = ORG_KINDS.includes(node.kind) ? node.kind : "domain";
18537
+ return `${kind2}/${slugify(node.title) || "claim"}-${node.tag_id.replace(/-/g, "").slice(0, 8)}.md`;
18537
18538
  }
18538
18539
  function renderOrgNode(node, orgName) {
18539
18540
  const fm = [
@@ -18622,10 +18623,10 @@ function renderIndex(orgName, nodes) {
18622
18623
  ];
18623
18624
  const byKind = /* @__PURE__ */ new Map();
18624
18625
  for (const n of nodes) byKind.set(n.kind, [...byKind.get(n.kind) ?? [], n]);
18625
- for (const kind of ORG_KINDS) {
18626
- const list2 = byKind.get(kind);
18626
+ for (const kind2 of ORG_KINDS) {
18627
+ const list2 = byKind.get(kind2);
18627
18628
  if (!list2?.length) continue;
18628
- lines.push(`## ${kind}/ (${list2.length})`);
18629
+ lines.push(`## ${kind2}/ (${list2.length})`);
18629
18630
  for (const n of list2) lines.push(`- [[${orgNodePath(n).split("/")[1].replace(/\.md$/, "")}]] \u2014 ${n.title} \xB7 ${n.origin}`);
18630
18631
  lines.push("");
18631
18632
  }
@@ -18684,8 +18685,8 @@ async function readOrgMirror(remote = requestRemote()) {
18684
18685
  const dir = orgMirrorDir(remote);
18685
18686
  if (!dir || !(0, import_node_fs14.existsSync)(dir)) return [];
18686
18687
  const out2 = [];
18687
- for (const kind of ORG_KINDS) {
18688
- const kindDir = (0, import_node_path14.join)(dir, kind);
18688
+ for (const kind2 of ORG_KINDS) {
18689
+ const kindDir = (0, import_node_path14.join)(dir, kind2);
18689
18690
  if (!(0, import_node_fs14.existsSync)(kindDir)) continue;
18690
18691
  let files;
18691
18692
  try {
@@ -18953,16 +18954,16 @@ function relevance(node, ctx) {
18953
18954
  return { score, via: { glob: globHit, tag: tagScore, text: textScore } };
18954
18955
  }
18955
18956
  var KIND_POOL_STRENGTH = 20;
18956
- function priorFor(kind, pooled) {
18957
- const base = KIND_PRIOR_MEAN[kind] ?? DEFAULT_PRIOR_MEAN;
18957
+ function priorFor(kind2, pooled) {
18958
+ const base = KIND_PRIOR_MEAN[kind2] ?? DEFAULT_PRIOR_MEAN;
18958
18959
  const a = pooled ? Math.max(0, pooled.alpha) : 0;
18959
18960
  const b = pooled ? Math.max(0, pooled.beta) : 0;
18960
- const mean = pooled && kind !== "integration" ? (KIND_POOL_STRENGTH * base + a) / (KIND_POOL_STRENGTH + a + b) : base;
18961
+ const mean = pooled && kind2 !== "integration" ? (KIND_POOL_STRENGTH * base + a) / (KIND_POOL_STRENGTH + a + b) : base;
18961
18962
  return { alpha: mean * PRIOR_STRENGTH, beta: (1 - mean) * PRIOR_STRENGTH };
18962
18963
  }
18963
- function posteriorFor(kind, own, pooled) {
18964
- const p = priorFor(kind, pooled);
18965
- if (!own || kind === "integration") return p;
18964
+ function posteriorFor(kind2, own, pooled) {
18965
+ const p = priorFor(kind2, pooled);
18966
+ if (!own || kind2 === "integration") return p;
18966
18967
  return { alpha: p.alpha + Math.max(0, own.alpha), beta: p.beta + Math.max(0, own.beta) };
18967
18968
  }
18968
18969
  function posteriorMean(p) {
@@ -20002,7 +20003,7 @@ async function regenerateIndex() {
20002
20003
  try {
20003
20004
  const content = await (0, import_promises9.readFile)((0, import_node_path19.join)(domainDir, file), "utf-8");
20004
20005
  const title = pickFrontmatter(content, "title") ?? slug;
20005
- const kind = pickFrontmatter(content, "kind") ?? "-";
20006
+ const kind2 = pickFrontmatter(content, "kind") ?? "-";
20006
20007
  const confidence = pickFrontmatter(content, "confidence");
20007
20008
  const globs = pickFrontmatterArray(content, "file_globs");
20008
20009
  const status = pickFrontmatter(content, "status") ?? "active";
@@ -20010,7 +20011,7 @@ async function regenerateIndex() {
20010
20011
  const globPart = globs.length > 0 ? ` \xB7 scope: \`${globs.slice(0, 3).join("`, `")}\`` : "";
20011
20012
  const statusPart = status !== "active" ? ` \xB7 *${status}*` : "";
20012
20013
  lines.push(`- [[${slug}]] \u2014 **${title}**`);
20013
- lines.push(` *${kind}*${confPart}${globPart}${statusPart}`);
20014
+ lines.push(` *${kind2}*${confPart}${globPart}${statusPart}`);
20014
20015
  } catch {
20015
20016
  lines.push(`- [[${slug}]]`);
20016
20017
  }
@@ -22053,8 +22054,8 @@ function toRegister(severity) {
22053
22054
  return "NOTE";
22054
22055
  }
22055
22056
  }
22056
- function recordMark(d, kind, from, to) {
22057
- appendEvent(d, { k: "mark", kind, from: from ?? null, to: to ?? null });
22057
+ function recordMark(d, kind2, from, to) {
22058
+ appendEvent(d, { k: "mark", kind: kind2, from: from ?? null, to: to ?? null });
22058
22059
  }
22059
22060
  function recordCapabilities(d, c, known) {
22060
22061
  const put = (field, value, tier) => {
@@ -27257,7 +27258,7 @@ function channelSilence(input) {
27257
27258
  // src/lib/cli-version.ts
27258
27259
  function cliVersion() {
27259
27260
  try {
27260
- return true ? "0.34.1-experimental.89100b5" : "dev";
27261
+ return true ? "0.34.1-experimental.c910405" : "dev";
27261
27262
  } catch {
27262
27263
  return "dev";
27263
27264
  }
@@ -27497,10 +27498,10 @@ var EMPTY_RESULT = {
27497
27498
  findings: [],
27498
27499
  summary: { total_findings: 0, by_severity: {}, tools_run: [] }
27499
27500
  };
27500
- function withFailure(kind, detail) {
27501
+ function withFailure(kind2, detail) {
27501
27502
  return {
27502
27503
  ...EMPTY_RESULT,
27503
- summary: { ...EMPTY_RESULT.summary, failure: { kind, detail: detail.slice(0, 300) } }
27504
+ summary: { ...EMPTY_RESULT.summary, failure: { kind: kind2, detail: detail.slice(0, 300) } }
27504
27505
  };
27505
27506
  }
27506
27507
  function runCodacyAnalysisIfAvailable(files) {
@@ -28259,11 +28260,11 @@ var rootCandidateCache = /* @__PURE__ */ new Map();
28259
28260
  function candidateRoots(repoRoot2) {
28260
28261
  const cached2 = rootCandidateCache.get(repoRoot2);
28261
28262
  if (cached2) return cached2;
28262
- const norm2 = repoRoot2.replace(/\\/g, "/").replace(/\/+$/, "");
28263
- const out2 = [norm2];
28263
+ const norm3 = repoRoot2.replace(/\\/g, "/").replace(/\/+$/, "");
28264
+ const out2 = [norm3];
28264
28265
  try {
28265
- const real = import_node_fs44.realpathSync.native(norm2).replace(/\\/g, "/").replace(/\/+$/, "");
28266
- if (real !== norm2) out2.push(real);
28266
+ const real = import_node_fs44.realpathSync.native(norm3).replace(/\\/g, "/").replace(/\/+$/, "");
28267
+ if (real !== norm3) out2.push(real);
28267
28268
  } catch {
28268
28269
  }
28269
28270
  for (const r of [...out2]) {
@@ -29114,39 +29115,39 @@ function extentOf(node) {
29114
29115
  }
29115
29116
  function definitionsIn(root, spec) {
29116
29117
  const out2 = [];
29117
- const add = (name2, kind, extent, fn, owner, last = extent) => {
29118
+ const add = (name2, kind2, extent, fn, owner, last = extent) => {
29118
29119
  const q = qualifierOf(owner, spec);
29119
- out2.push({ name: name2, qualified: q ? `${q}.${name2}` : name2, kind, extent, last, fn });
29120
+ out2.push({ name: name2, qualified: q ? `${q}.${name2}` : name2, kind: kind2, extent, last, fn });
29120
29121
  };
29121
29122
  const visit = (n) => {
29122
- const kind = spec.definitions[n.type];
29123
- if (kind && n.childForFieldName("body")) {
29123
+ const kind2 = spec.definitions[n.type];
29124
+ if (kind2 && n.childForFieldName("body")) {
29124
29125
  const nameNode = n.childForFieldName("name");
29125
29126
  if (nameNode && nameNode.type !== "computed_property_name") {
29126
29127
  const inClass = qualifierOf(n, spec) !== null;
29127
- const k = spec.id === "python" ? inClass ? "method" : "function" : kind;
29128
+ const k = spec.id === "python" ? inClass ? "method" : "function" : kind2;
29128
29129
  add(nameNode.text, k, extentOf(n), n, n, n.parent?.type === "decorated_definition" ? n.parent : n);
29129
29130
  }
29130
29131
  } else if (spec.functionValues.has(n.type) && n.parent) {
29131
29132
  const p = n.parent;
29132
- const kind2 = n.type === "arrow_function" ? "arrow" : n.type === "lambda" || n.type === "lambda_expression" ? "lambda" : "function";
29133
+ const kind3 = n.type === "arrow_function" ? "arrow" : n.type === "lambda" || n.type === "lambda_expression" ? "lambda" : "function";
29133
29134
  const bound = p.childForFieldName("value")?.id === n.id;
29134
29135
  if (bound && p.type === "variable_declarator" && p.childForFieldName("name")?.type === "identifier") {
29135
29136
  const decl = p.parent && p.parent.namedChildren.filter((c) => c.type === "variable_declarator").length === 1 ? p.parent : p;
29136
- add(p.childForFieldName("name").text, kind2, decl, n, p);
29137
+ add(p.childForFieldName("name").text, kind3, decl, n, p);
29137
29138
  } else if (bound && (p.type === "public_field_definition" || p.type === "field_definition")) {
29138
29139
  const nameNode = p.childForFieldName("name") ?? p.childForFieldName("property");
29139
- if (nameNode && nameNode.type !== "computed_property_name") add(nameNode.text, kind2, extentOf(p), n, p, p);
29140
+ if (nameNode && nameNode.type !== "computed_property_name") add(nameNode.text, kind3, extentOf(p), n, p, p);
29140
29141
  } else if (bound && p.type === "pair") {
29141
29142
  const key = p.childForFieldName("key");
29142
- if (key && (key.type === "property_identifier" || key.type === "identifier")) add(key.text, kind2, p, n, p);
29143
+ if (key && (key.type === "property_identifier" || key.type === "identifier")) add(key.text, kind3, p, n, p);
29143
29144
  } else if (p.type === "arguments" && moduleCall(p.parent)) {
29144
29145
  const call = p.parent;
29145
29146
  const route = p.namedChildren[0];
29146
29147
  const quoted = route && route.id !== n.id && route.type === "string" ? unquote2(route.text) : null;
29147
29148
  const path = quoted && /^[\w/:.{}*-]{1,60}$/.test(quoted) ? quoted : null;
29148
29149
  const callee = call.childForFieldName("function").text;
29149
- add(path ? `${callee} ${path}` : callee, kind2, call.parent, n, call);
29150
+ add(path ? `${callee} ${path}` : callee, kind3, call.parent, n, call);
29150
29151
  }
29151
29152
  }
29152
29153
  for (const c of n.namedChildren) visit(c);
@@ -29423,15 +29424,15 @@ var STABLE_EXPRESSION = (t) => {
29423
29424
  const root = t.split(".")[0];
29424
29425
  return root === "this" || root === "self" || /^[A-Z]/.test(root);
29425
29426
  };
29426
- function argResource(kind, arg) {
29427
- if (!arg) return { kind, name: null, confidence: "unknown" };
29427
+ function argResource(kind2, arg) {
29428
+ if (!arg) return { kind: kind2, name: null, confidence: "unknown" };
29428
29429
  if (arg.literal !== null) {
29429
29430
  const n = literalName(arg.literal);
29430
- return n ? { kind, name: n.name, confidence: n.confidence } : { kind, name: null, confidence: "unknown" };
29431
+ return n ? { kind: kind2, name: n.name, confidence: n.confidence } : { kind: kind2, name: null, confidence: "unknown" };
29431
29432
  }
29432
- if (SIMPLE_EXPRESSION.test(arg.text) && STABLE_EXPRESSION(arg.text)) return { kind, name: arg.text, confidence: "expression" };
29433
+ if (SIMPLE_EXPRESSION.test(arg.text) && STABLE_EXPRESSION(arg.text)) return { kind: kind2, name: arg.text, confidence: "expression" };
29433
29434
  const keyed = keyedCall(arg.text);
29434
- return keyed ? { kind, name: keyed, confidence: "expression" } : { kind, name: null, confidence: "unknown" };
29435
+ return keyed ? { kind: kind2, name: keyed, confidence: "expression" } : { kind: kind2, name: null, confidence: "unknown" };
29435
29436
  }
29436
29437
  function keyedCall(text) {
29437
29438
  const t = text.trim();
@@ -30940,8 +30941,8 @@ ${m.accessors.map((x) => ` ${x.fn.path}:${x.fn.start.line} ${x.fn.qualified} \u
30940
30941
  var KINDS = ["table", "cache", "file", "http", "queue", "service", "memory"];
30941
30942
  function parseResource(text) {
30942
30943
  const colon = text.indexOf(":");
30943
- const kind = colon > 0 ? text.slice(0, colon) : "";
30944
- if (KINDS.includes(kind)) return { kinds: [kind], name: text.slice(colon + 1) };
30944
+ const kind2 = colon > 0 ? text.slice(0, colon) : "";
30945
+ if (KINDS.includes(kind2)) return { kinds: [kind2], name: text.slice(colon + 1) };
30945
30946
  return { kinds: KINDS, name: text };
30946
30947
  }
30947
30948
  var writersOfTool = async (ctx, args2) => {
@@ -33434,12 +33435,41 @@ async function runAnalyze(opts, globals) {
33434
33435
  }
33435
33436
 
33436
33437
  // src/commands/baseline.ts
33437
- var import_node_fs55 = require("node:fs");
33438
- var import_node_path42 = require("node:path");
33438
+ var import_node_fs56 = require("node:fs");
33439
+ var import_node_path43 = require("node:path");
33439
33440
 
33440
- // src/lib/project-skills.ts
33441
+ // src/lib/skew-notice.ts
33441
33442
  var import_node_fs54 = require("node:fs");
33442
33443
  var import_node_path41 = require("node:path");
33444
+ var MARKER = ".skew-notice.json";
33445
+ function markerPath2() {
33446
+ return (0, import_node_path41.join)(verityHome(), MARKER);
33447
+ }
33448
+ function today(now) {
33449
+ const y = now.getFullYear();
33450
+ const m = String(now.getMonth() + 1).padStart(2, "0");
33451
+ const d = String(now.getDate()).padStart(2, "0");
33452
+ return `${y}-${m}-${d}`;
33453
+ }
33454
+ function skewNoticeDue(skew, now = /* @__PURE__ */ new Date()) {
33455
+ try {
33456
+ const seen = JSON.parse((0, import_node_fs54.readFileSync)(markerPath2(), "utf-8"));
33457
+ return !(seen.global === skew.global && seen.hooks === skew.hooks && seen.day === today(now));
33458
+ } catch {
33459
+ return true;
33460
+ }
33461
+ }
33462
+ function recordSkewNotice(skew, now = /* @__PURE__ */ new Date()) {
33463
+ try {
33464
+ (0, import_node_fs54.mkdirSync)(verityHome(), { recursive: true, mode: 448 });
33465
+ (0, import_node_fs54.writeFileSync)(markerPath2(), JSON.stringify({ global: skew.global, hooks: skew.hooks, day: today(now) }) + "\n");
33466
+ } catch {
33467
+ }
33468
+ }
33469
+
33470
+ // src/lib/project-skills.ts
33471
+ var import_node_fs55 = require("node:fs");
33472
+ var import_node_path42 = require("node:path");
33443
33473
  var PROJECT_SKILL_NAMES = [
33444
33474
  "verity-setup",
33445
33475
  "verity-analyze",
@@ -33465,14 +33495,14 @@ var LEGACY_SKILL_NAMES = [
33465
33495
  var ALL = [...PROJECT_SKILL_NAMES, ...LEGACY_SKILL_NAMES];
33466
33496
  function staleProjectSkills() {
33467
33497
  const root = projectPath(".claude/skills");
33468
- if (!(0, import_node_fs54.existsSync)(root)) return [];
33469
- return ALL.filter((name2) => (0, import_node_fs54.existsSync)((0, import_node_path41.join)(root, name2)));
33498
+ if (!(0, import_node_fs55.existsSync)(root)) return [];
33499
+ return ALL.filter((name2) => (0, import_node_fs55.existsSync)((0, import_node_path42.join)(root, name2)));
33470
33500
  }
33471
33501
  function removeProjectSkills() {
33472
33502
  const root = projectPath(".claude/skills");
33473
33503
  const removed = [];
33474
33504
  for (const name2 of staleProjectSkills()) {
33475
- (0, import_node_fs54.rmSync)((0, import_node_path41.join)(root, name2), { recursive: true, force: true });
33505
+ (0, import_node_fs55.rmSync)((0, import_node_path42.join)(root, name2), { recursive: true, force: true });
33476
33506
  removed.push(name2);
33477
33507
  }
33478
33508
  return removed;
@@ -33502,10 +33532,12 @@ function registerBaselineCommands(program2) {
33502
33532
  const skew = cliVersionSkew();
33503
33533
  const why = skew ? `the \`verity\` on PATH is ${skew.global} but the hooks run ${skew.hooks}, so it is not the CLI they use` : verityOnPath() ? "the `verity` on PATH is a separate install whose version could not be read" : "this machine has no `verity` on PATH \u2014 the plugin carries its own copy";
33504
33534
  const cliLine = cli ? `Verity CLI: ${why}. When a Verity skill tells you to run \`verity <args>\`, run \`${cli} <args>\` instead. Everything else about the command is identical.` : null;
33505
- const skewMsg = skew ? `Verity: your global \`verity\` CLI is ${skew.global} but the hooks run ${skew.hooks}. Fix it before using \`verity\` in a terminal: ${skew.remedy}` : null;
33506
- const skewNote = skew ? `Before anything else, including /verity:init's questions, tell the user their global \`verity\` is ${skew.global}, the hooks run ${skew.hooks}, and \`${skew.remedy}\` fixes it. Until they have, do not send them to run \`verity login\` in a terminal: that runs the global one, which can sign this machine in to a different server.` : null;
33535
+ const skewLoud = !!skew && skewNoticeDue(skew);
33536
+ const skewMsg = skew && skewLoud ? `Verity: your global \`verity\` CLI is ${skew.global} but the hooks run ${skew.hooks}. Fix it before using \`verity\` in a terminal: ${skew.remedy}` : null;
33537
+ const loginWarning = "Until they have, do not send them to run `verity login` in a terminal: that runs the global one, which can sign this machine in to a different server.";
33538
+ const skewNote = !skew ? null : skewLoud ? `Before anything else, including /verity:init's questions, tell the user their global \`verity\` is ${skew.global}, the hooks run ${skew.hooks}, and \`${skew.remedy}\` fixes it. ${loginWarning}` : `The user's global \`verity\` is ${skew.global} and the hooks run ${skew.hooks}; \`${skew.remedy}\` fixes it. They were already told today, so do not repeat it unprompted \u2014 mention it only where it matters, such as before suggesting a \`verity\` command for their terminal. ${loginWarning}`;
33507
33539
  if (!verityConfigured()) {
33508
- if (isMachineStore((0, import_node_path42.join)(repoRoot(), VERITY_DIR))) process.exit(0);
33540
+ if (isMachineStore((0, import_node_path43.join)(repoRoot(), VERITY_DIR))) process.exit(0);
33509
33541
  const how = isPluginInvocation() ? "Tell the user to run /verity:init \u2014 they type it; you cannot invoke it." : "Tell the user to run `verity init` in their terminal.";
33510
33542
  const lines = [
33511
33543
  `Verity is installed but this project is not set up yet, so the quality gate will not review anything here. ${how}`
@@ -33532,19 +33564,20 @@ function registerBaselineCommands(program2) {
33532
33564
  }
33533
33565
  }) + "\n"
33534
33566
  );
33567
+ if (skew && skewMsg) recordSkewNotice(skew);
33535
33568
  process.exit(0);
33536
33569
  }
33537
33570
  const realStart = source2 === void 0 || source2 === "startup" || source2 === "clear";
33538
33571
  let memoryMsg = null;
33539
33572
  let memoryAgentLine = null;
33540
33573
  const memoryNotice = projectPath(`${VERITY_DIR}/.memory-fence-notice`);
33541
- if (realStart && !(0, import_node_fs55.existsSync)(memoryNotice)) {
33574
+ if (realStart && !(0, import_node_fs56.existsSync)(memoryNotice)) {
33542
33575
  const trackedGraph = memoryOptOut() ? 0 : committedMemoryFiles().length;
33543
33576
  if (trackedGraph > 0) {
33544
33577
  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.`;
33545
33578
  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.`;
33546
33579
  try {
33547
- (0, import_node_fs55.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
33580
+ (0, import_node_fs56.writeFileSync)(memoryNotice, (/* @__PURE__ */ new Date()).toISOString() + "\n");
33548
33581
  } catch {
33549
33582
  }
33550
33583
  }
@@ -33572,7 +33605,7 @@ function registerBaselineCommands(program2) {
33572
33605
  }
33573
33606
  }
33574
33607
  if (memoryAgentLine) notices.push(memoryAgentLine);
33575
- if (notices.length > 0) {
33608
+ if (notices.length > 0 || skewMsg) {
33576
33609
  process.stdout.write(
33577
33610
  JSON.stringify({
33578
33611
  ...userMsg || skewMsg || memoryMsg ? { systemMessage: [skewMsg, userMsg, memoryMsg].filter(Boolean).join("\n") } : {},
@@ -33582,6 +33615,7 @@ function registerBaselineCommands(program2) {
33582
33615
  }
33583
33616
  }) + "\n"
33584
33617
  );
33618
+ if (skew && skewMsg) recordSkewNotice(skew);
33585
33619
  }
33586
33620
  } else if (memoryMsg) {
33587
33621
  process.stdout.write(
@@ -33645,7 +33679,7 @@ function hookSource(value) {
33645
33679
  }
33646
33680
 
33647
33681
  // src/commands/review.ts
33648
- var import_node_fs56 = require("node:fs");
33682
+ var import_node_fs57 = require("node:fs");
33649
33683
  function registerReviewCommand(program2) {
33650
33684
  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); - reads it from stdin, so the words never pass through shell quoting").option("--specs <paths>", "Comma-separated spec file paths").option("--json", "Output raw JSON response").action(async (opts) => {
33651
33685
  const globals = program2.opts();
@@ -33668,7 +33702,7 @@ async function runReview(opts, globals) {
33668
33702
  const changedFiles = opts.changed ? opts.changed.split(",").map((f) => f.trim()).filter(Boolean) : allFiles;
33669
33703
  const analyzable = filterAnalyzable(allFiles);
33670
33704
  const securityFiles = filterSecurity(allFiles);
33671
- const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs56.existsSync)(f) || resolveFile(f) !== null);
33705
+ const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).filter((f) => (0, import_node_fs57.existsSync)(f) || resolveFile(f) !== null);
33672
33706
  const staticResults = runCodacyAnalysisIfAvailable(scannable);
33673
33707
  const codeDelta = collectCodeDelta(allFiles);
33674
33708
  const tokenResult = await resolveToken(globals.token);
@@ -33734,12 +33768,12 @@ async function runReview(opts, globals) {
33734
33768
  }
33735
33769
 
33736
33770
  // src/commands/guard.ts
33737
- var import_node_fs61 = require("node:fs");
33738
- var import_node_path48 = require("node:path");
33771
+ var import_node_fs62 = require("node:fs");
33772
+ var import_node_path49 = require("node:path");
33739
33773
 
33740
33774
  // src/lib/vendored.ts
33741
- var import_node_fs57 = require("node:fs");
33742
- var import_node_path43 = require("node:path");
33775
+ var import_node_fs58 = require("node:fs");
33776
+ var import_node_path44 = require("node:path");
33743
33777
  var INSTALLED_SKILL = /^\.claude\/skills\/(verity-[a-z0-9-]+)\/(.+)$/;
33744
33778
  function dataDirOrNull() {
33745
33779
  try {
@@ -33754,7 +33788,7 @@ function shippedSkillFile(path, dataDir = dataDirOrNull()) {
33754
33788
  const [, skill, rel] = m;
33755
33789
  if (rel.split("/").some((seg) => seg === ".." || seg === ".")) return null;
33756
33790
  try {
33757
- return (0, import_node_fs57.readFileSync)((0, import_node_path43.join)(dataDir, "skills", skill, rel), "utf8");
33791
+ return (0, import_node_fs58.readFileSync)((0, import_node_path44.join)(dataDir, "skills", skill, rel), "utf8");
33758
33792
  } catch {
33759
33793
  return null;
33760
33794
  }
@@ -33864,7 +33898,7 @@ async function runAgentReview(options) {
33864
33898
  }
33865
33899
 
33866
33900
  // src/lib/prove/auto.ts
33867
- var import_node_path47 = require("node:path");
33901
+ var import_node_path48 = require("node:path");
33868
33902
  var import_node_crypto19 = require("node:crypto");
33869
33903
 
33870
33904
  // src/lib/prove/signals.ts
@@ -34906,9 +34940,9 @@ function effectSites(numbered2) {
34906
34940
  const t = r.text.trim();
34907
34941
  if (!t || t.startsWith("//") || t.startsWith("#") || t.startsWith("*")) continue;
34908
34942
  const onParam = [...params].some((p) => callsOn(t, p) || callsDirect(t, p));
34909
- const kind = EFFECT_LINE2.test(t) || onParam ? "effect" : CONTROL_LINE.test(t) ? "control" : null;
34910
- if (!kind) continue;
34911
- out2.push(`L${r.n} [${kind}] ${t.length > 160 ? t.slice(0, 157) + "\u2026" : t}`);
34943
+ const kind2 = EFFECT_LINE2.test(t) || onParam ? "effect" : CONTROL_LINE.test(t) ? "control" : null;
34944
+ if (!kind2) continue;
34945
+ out2.push(`L${r.n} [${kind2}] ${t.length > 160 ? t.slice(0, 157) + "\u2026" : t}`);
34912
34946
  if (out2.length >= MAX_EFFECT_SITES) break;
34913
34947
  }
34914
34948
  return out2;
@@ -35591,18 +35625,18 @@ function renderReplay(model, property, r) {
35591
35625
  // src/lib/prove/runner.ts
35592
35626
  var import_node_child_process15 = require("node:child_process");
35593
35627
  var import_node_os8 = require("node:os");
35594
- var import_node_fs60 = require("node:fs");
35628
+ var import_node_fs61 = require("node:fs");
35595
35629
  var import_node_os9 = require("node:os");
35596
- var import_node_path46 = require("node:path");
35630
+ var import_node_path47 = require("node:path");
35597
35631
 
35598
35632
  // src/lib/prove/scaffold.ts
35599
- var import_node_fs59 = require("node:fs");
35600
- var import_node_path45 = require("node:path");
35633
+ var import_node_fs60 = require("node:fs");
35634
+ var import_node_path46 = require("node:path");
35601
35635
 
35602
35636
  // src/lib/prove/safe-write.ts
35603
- var import_node_fs58 = require("node:fs");
35637
+ var import_node_fs59 = require("node:fs");
35604
35638
  var import_node_crypto15 = require("node:crypto");
35605
- var import_node_path44 = require("node:path");
35639
+ var import_node_path45 = require("node:path");
35606
35640
  var SafeWriteError = class extends Error {
35607
35641
  constructor(reason, path) {
35608
35642
  super(`refusing to write ${path}: ${reason}`);
@@ -35611,10 +35645,10 @@ var SafeWriteError = class extends Error {
35611
35645
  this.name = "SafeWriteError";
35612
35646
  }
35613
35647
  };
35614
- var FLAGS3 = import_node_fs58.constants;
35648
+ var FLAGS3 = import_node_fs59.constants;
35615
35649
  var NOFOLLOW2 = FLAGS3.O_NOFOLLOW ?? 0;
35616
35650
  function assertPlainRelative(rel) {
35617
- if (!rel || (0, import_node_path44.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
35651
+ if (!rel || (0, import_node_path45.isAbsolute)(rel)) throw new SafeWriteError("bad-path", rel);
35618
35652
  for (const part of rel.split(/[\\/]/)) {
35619
35653
  if (part === ".." || part === "" || part === ".") throw new SafeWriteError("bad-path", rel);
35620
35654
  }
@@ -35623,34 +35657,34 @@ function ensureDirsNoFollow(root, rel) {
35623
35657
  const parts2 = rel.split(/[\\/]/);
35624
35658
  let cur = root;
35625
35659
  for (const part of parts2.slice(0, -1)) {
35626
- cur = (0, import_node_path44.join)(cur, part);
35660
+ cur = (0, import_node_path45.join)(cur, part);
35627
35661
  let st;
35628
35662
  try {
35629
- st = (0, import_node_fs58.lstatSync)(cur);
35663
+ st = (0, import_node_fs59.lstatSync)(cur);
35630
35664
  } catch {
35631
- (0, import_node_fs58.mkdirSync)(cur);
35665
+ (0, import_node_fs59.mkdirSync)(cur);
35632
35666
  continue;
35633
35667
  }
35634
35668
  if (st.isSymbolicLink()) throw new SafeWriteError("symlink", cur);
35635
35669
  if (!st.isDirectory()) throw new SafeWriteError("not-regular", cur);
35636
35670
  }
35637
- return (0, import_node_path44.join)(root, rel);
35671
+ return (0, import_node_path45.join)(root, rel);
35638
35672
  }
35639
35673
  function insideRoot(realRoot, realPath) {
35640
- return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path44.sep) ? realRoot : realRoot + import_node_path44.sep);
35674
+ return realPath === realRoot || realPath.startsWith(realRoot.endsWith(import_node_path45.sep) ? realRoot : realRoot + import_node_path45.sep);
35641
35675
  }
35642
35676
  function removeQuietly(path) {
35643
35677
  try {
35644
- (0, import_node_fs58.unlinkSync)(path);
35678
+ (0, import_node_fs59.unlinkSync)(path);
35645
35679
  } catch {
35646
35680
  }
35647
35681
  }
35648
35682
  function writeFileInRootNoFollow(root, rel, content) {
35649
35683
  assertPlainRelative(rel);
35650
35684
  const dest = ensureDirsNoFollow(root, rel);
35651
- const dir = (0, import_node_path44.dirname)(dest);
35685
+ const dir = (0, import_node_path45.dirname)(dest);
35652
35686
  try {
35653
- const st = (0, import_node_fs58.lstatSync)(dest);
35687
+ const st = (0, import_node_fs59.lstatSync)(dest);
35654
35688
  if (st.isSymbolicLink()) throw new SafeWriteError("symlink", dest);
35655
35689
  if (!st.isFile()) throw new SafeWriteError("not-regular", dest);
35656
35690
  } catch (err2) {
@@ -35658,41 +35692,41 @@ function writeFileInRootNoFollow(root, rel, content) {
35658
35692
  }
35659
35693
  let realRoot;
35660
35694
  try {
35661
- realRoot = (0, import_node_fs58.realpathSync)(root);
35695
+ realRoot = (0, import_node_fs59.realpathSync)(root);
35662
35696
  } catch {
35663
35697
  throw new SafeWriteError("unwritable", root);
35664
35698
  }
35665
- const tmp = (0, import_node_path44.join)(dir, `.${(0, import_node_path44.basename)(dest)}.${(0, import_node_crypto15.randomBytes)(6).toString("hex")}.tmp`);
35699
+ const tmp = (0, import_node_path45.join)(dir, `.${(0, import_node_path45.basename)(dest)}.${(0, import_node_crypto15.randomBytes)(6).toString("hex")}.tmp`);
35666
35700
  let fd;
35667
35701
  try {
35668
- fd = (0, import_node_fs58.openSync)(tmp, import_node_fs58.constants.O_WRONLY | import_node_fs58.constants.O_CREAT | import_node_fs58.constants.O_EXCL | NOFOLLOW2, 420);
35702
+ fd = (0, import_node_fs59.openSync)(tmp, import_node_fs59.constants.O_WRONLY | import_node_fs59.constants.O_CREAT | import_node_fs59.constants.O_EXCL | NOFOLLOW2, 420);
35669
35703
  } catch {
35670
35704
  throw new SafeWriteError("unwritable", tmp);
35671
35705
  }
35672
35706
  try {
35673
- const opened = (0, import_node_fs58.fstatSync)(fd, { bigint: true });
35707
+ const opened = (0, import_node_fs59.fstatSync)(fd, { bigint: true });
35674
35708
  let realTmp;
35675
35709
  try {
35676
- realTmp = (0, import_node_fs58.realpathSync)(tmp);
35710
+ realTmp = (0, import_node_fs59.realpathSync)(tmp);
35677
35711
  } catch {
35678
35712
  throw new SafeWriteError("escaped", tmp);
35679
35713
  }
35680
- const there = (0, import_node_fs58.lstatSync)(realTmp, { bigint: true });
35714
+ const there = (0, import_node_fs59.lstatSync)(realTmp, { bigint: true });
35681
35715
  if (!opened.isFile() || there.ino !== opened.ino || there.dev !== opened.dev || !insideRoot(realRoot, realTmp)) {
35682
35716
  throw new SafeWriteError("escaped", tmp);
35683
35717
  }
35684
35718
  const buf = Buffer.from(content, "utf-8");
35685
35719
  let off = 0;
35686
- while (off < buf.length) off += (0, import_node_fs58.writeSync)(fd, buf, off, buf.length - off);
35720
+ while (off < buf.length) off += (0, import_node_fs59.writeSync)(fd, buf, off, buf.length - off);
35687
35721
  } catch (err2) {
35688
- (0, import_node_fs58.closeSync)(fd);
35722
+ (0, import_node_fs59.closeSync)(fd);
35689
35723
  removeQuietly(tmp);
35690
35724
  throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", tmp);
35691
35725
  }
35692
- (0, import_node_fs58.closeSync)(fd);
35726
+ (0, import_node_fs59.closeSync)(fd);
35693
35727
  try {
35694
- if (!insideRoot(realRoot, (0, import_node_fs58.realpathSync)(dir)) || (0, import_node_fs58.lstatSync)(dir).isSymbolicLink()) throw new SafeWriteError("escaped", dir);
35695
- (0, import_node_fs58.renameSync)(tmp, dest);
35728
+ if (!insideRoot(realRoot, (0, import_node_fs59.realpathSync)(dir)) || (0, import_node_fs59.lstatSync)(dir).isSymbolicLink()) throw new SafeWriteError("escaped", dir);
35729
+ (0, import_node_fs59.renameSync)(tmp, dest);
35696
35730
  } catch (err2) {
35697
35731
  removeQuietly(tmp);
35698
35732
  throw err2 instanceof SafeWriteError ? err2 : new SafeWriteError("unwritable", dest);
@@ -35706,9 +35740,9 @@ function pathHasNoLink(root, rel) {
35706
35740
  }
35707
35741
  let cur = root;
35708
35742
  for (const part of rel.split(/[\\/]/)) {
35709
- cur = cur + import_node_path44.sep + part;
35743
+ cur = cur + import_node_path45.sep + part;
35710
35744
  try {
35711
- if ((0, import_node_fs58.lstatSync)(cur).isSymbolicLink()) return false;
35745
+ if ((0, import_node_fs59.lstatSync)(cur).isSymbolicLink()) return false;
35712
35746
  } catch {
35713
35747
  return true;
35714
35748
  }
@@ -36018,20 +36052,20 @@ This directory is machine-local and gitignored (see ../.gitignore). Models are
36018
36052
  never committed; what reaches the team is the bug report and the fix.
36019
36053
  `;
36020
36054
  function scaffoldProofs(root) {
36021
- const proofsDir = (0, import_node_path45.join)(root, PROOFS_DIR);
36055
+ const proofsDir = (0, import_node_path46.join)(root, PROOFS_DIR);
36022
36056
  const written = [];
36023
36057
  const kept = [];
36024
36058
  for (const stray of ["lakefile.lean"]) {
36025
36059
  const rel = `${PROOFS_DIR}/${stray}`;
36026
- if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path45.join)(root, rel));
36060
+ if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path46.join)(root, rel));
36027
36061
  try {
36028
- (0, import_node_fs59.rmSync)((0, import_node_path45.join)(root, rel), { force: true });
36062
+ (0, import_node_fs60.rmSync)((0, import_node_path46.join)(root, rel), { force: true });
36029
36063
  } catch {
36030
36064
  }
36031
36065
  }
36032
36066
  for (const f of PROOFS_TEMPLATE_FILES) {
36033
36067
  const rel = `${PROOFS_DIR}/${f.path}`;
36034
- if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path45.join)(root, rel));
36068
+ if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path46.join)(root, rel));
36035
36069
  const current = readRegularFileInRoot(root, rel, 4 * 1024 * 1024);
36036
36070
  if (current.ok && current.content === f.content) {
36037
36071
  kept.push(rel);
@@ -36044,8 +36078,8 @@ function scaffoldProofs(root) {
36044
36078
  [`${PROOFS_DIR}/.gitignore`, LOCAL_GITIGNORE],
36045
36079
  [`${MODELS_DIR}/README.md`, MODELS_README]
36046
36080
  ]) {
36047
- if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path45.join)(root, rel));
36048
- if (existsNoFollow((0, import_node_path45.join)(root, rel))) {
36081
+ if (!pathHasNoLink(root, rel)) throw new SafeWriteError("symlink", (0, import_node_path46.join)(root, rel));
36082
+ if (existsNoFollow((0, import_node_path46.join)(root, rel))) {
36049
36083
  kept.push(rel);
36050
36084
  continue;
36051
36085
  }
@@ -36056,7 +36090,7 @@ function scaffoldProofs(root) {
36056
36090
  }
36057
36091
  function existsNoFollow(abs) {
36058
36092
  try {
36059
- (0, import_node_fs59.lstatSync)(abs);
36093
+ (0, import_node_fs60.lstatSync)(abs);
36060
36094
  return true;
36061
36095
  } catch {
36062
36096
  return false;
@@ -36135,12 +36169,12 @@ function parseHeader(obj) {
36135
36169
  function parseProperty(obj) {
36136
36170
  const model = ident(obj.model);
36137
36171
  const id = ident(obj.id);
36138
- const kind = typeof obj.kind === "string" && KINDS2.has(obj.kind) ? obj.kind : null;
36172
+ const kind2 = typeof obj.kind === "string" && KINDS2.has(obj.kind) ? obj.kind : null;
36139
36173
  const result = typeof obj.result === "string" && RESULTS.has(obj.result) ? obj.result : null;
36140
36174
  const source2 = obj.source === void 0 ? "" : str2(obj.source, LIMITS.text);
36141
36175
  const desc = obj.desc === void 0 ? "" : str2(obj.desc, LIMITS.text);
36142
- if (!model || !id || !kind || !result || source2 === null || desc === null) return null;
36143
- const p = { model, id, kind, source: source2, desc, result };
36176
+ if (!model || !id || !kind2 || !result || source2 === null || desc === null) return null;
36177
+ const p = { model, id, kind: kind2, source: source2, desc, result };
36144
36178
  if (obj.bound !== void 0) {
36145
36179
  const n = nat(obj.bound);
36146
36180
  if (n === null) return null;
@@ -36314,17 +36348,17 @@ function renderReport(r) {
36314
36348
 
36315
36349
  // src/lib/prove/runner.ts
36316
36350
  function verityLeanHome(env = process.env) {
36317
- return env.VERITY_LEAN_HOME ?? (0, import_node_path46.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".verity", "lean");
36351
+ return env.VERITY_LEAN_HOME ?? (0, import_node_path47.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".verity", "lean");
36318
36352
  }
36319
36353
  function findToolchain(env = process.env) {
36320
- const managedBin = (0, import_node_path46.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
36321
- const elanBin = (0, import_node_path46.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
36322
- const elanHas = (0, import_node_fs60.existsSync)((0, import_node_path46.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
36323
- const userPath = (env.PATH ?? "").split(import_node_path46.delimiter).filter((d) => d && (elanHas || (0, import_node_path46.resolve)(d) !== (0, import_node_path46.resolve)(elanBin)));
36324
- const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(import_node_path46.delimiter);
36354
+ const managedBin = (0, import_node_path47.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
36355
+ const elanBin = (0, import_node_path47.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
36356
+ const elanHas = (0, import_node_fs61.existsSync)((0, import_node_path47.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
36357
+ const userPath = (env.PATH ?? "").split(import_node_path47.delimiter).filter((d) => d && (elanHas || (0, import_node_path47.resolve)(d) !== (0, import_node_path47.resolve)(elanBin)));
36358
+ const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(import_node_path47.delimiter);
36325
36359
  const merged = { ...env, PATH: path, ELAN_TOOLCHAIN: env.ELAN_TOOLCHAIN ?? LEAN_TOOLCHAIN };
36326
36360
  const exe = process.platform === "win32" ? "lake.exe" : "lake";
36327
- const candidates2 = [(0, import_node_path46.join)(managedBin, exe), ...elanHas ? [(0, import_node_path46.join)(elanBin, exe)] : [], exe];
36361
+ const candidates2 = [(0, import_node_path47.join)(managedBin, exe), ...elanHas ? [(0, import_node_path47.join)(elanBin, exe)] : [], exe];
36328
36362
  for (const candidate of candidates2) {
36329
36363
  try {
36330
36364
  (0, import_node_child_process15.execFileSync)(candidate, ["--version"], { env: merged, stdio: ["ignore", "pipe", "pipe"], timeout: 1e4 });
@@ -36403,7 +36437,7 @@ function proofsWorkspaceProblem(root) {
36403
36437
  for (const rel of [".verity", PROOFS_DIR, `${PROOFS_DIR}/.lake`]) {
36404
36438
  let st;
36405
36439
  try {
36406
- st = (0, import_node_fs60.lstatSync)((0, import_node_path46.join)(root, rel));
36440
+ st = (0, import_node_fs61.lstatSync)((0, import_node_path47.join)(root, rel));
36407
36441
  } catch {
36408
36442
  break;
36409
36443
  }
@@ -36423,44 +36457,44 @@ function refused(problem) {
36423
36457
  function buildLibrary(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
36424
36458
  const problem = proofsWorkspaceProblem(root);
36425
36459
  if (problem) return refused(problem);
36426
- return run2(tc, (0, import_node_path46.join)(root, PROOFS_DIR), ["build"], timeoutMs);
36460
+ return run2(tc, (0, import_node_path47.join)(root, PROOFS_DIR), ["build"], timeoutMs);
36427
36461
  }
36428
36462
  async function buildLibraryAsync(tc, root, timeoutMs = DEFAULT_BUILD_TIMEOUT_MS) {
36429
36463
  const problem = proofsWorkspaceProblem(root);
36430
36464
  if (problem) return refused(problem);
36431
- return runAsync(tc, (0, import_node_path46.join)(root, PROOFS_DIR), ["build"], timeoutMs);
36465
+ return runAsync(tc, (0, import_node_path47.join)(root, PROOFS_DIR), ["build"], timeoutMs);
36432
36466
  }
36433
36467
  function isModelInRoot(modelsAbs, rel) {
36434
- if (!rel.endsWith(".lean") || (0, import_node_path46.isAbsolute)(rel) || rel.startsWith("..")) return false;
36468
+ if (!rel.endsWith(".lean") || (0, import_node_path47.isAbsolute)(rel) || rel.startsWith("..")) return false;
36435
36469
  return statRegularInRoot(modelsAbs, rel).ok;
36436
36470
  }
36437
36471
  function resolveModelFile(root, arg) {
36438
- const modelsAbs = (0, import_node_path46.join)(root, MODELS_DIR);
36439
- const asPath = (0, import_node_path46.relative)(modelsAbs, (0, import_node_path46.isAbsolute)(arg) ? arg : (0, import_node_path46.resolve)(root, arg));
36472
+ const modelsAbs = (0, import_node_path47.join)(root, MODELS_DIR);
36473
+ const asPath = (0, import_node_path47.relative)(modelsAbs, (0, import_node_path47.isAbsolute)(arg) ? arg : (0, import_node_path47.resolve)(root, arg));
36440
36474
  const candidates2 = arg.includes("/") || arg.includes("\\") ? [asPath] : [arg, `${arg}.lean`];
36441
36475
  for (const rel of candidates2) {
36442
- if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path46.join)(modelsAbs, rel);
36476
+ if (isModelInRoot(modelsAbs, rel)) return (0, import_node_path47.join)(modelsAbs, rel);
36443
36477
  }
36444
36478
  return null;
36445
36479
  }
36446
36480
  function listModelFiles(root) {
36447
- const modelsAbs = (0, import_node_path46.join)(root, MODELS_DIR);
36448
- if (!(0, import_node_fs60.existsSync)(modelsAbs)) return [];
36449
- return (0, import_node_fs60.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path46.join)(modelsAbs, f));
36481
+ const modelsAbs = (0, import_node_path47.join)(root, MODELS_DIR);
36482
+ if (!(0, import_node_fs61.existsSync)(modelsAbs)) return [];
36483
+ return (0, import_node_fs61.readdirSync)(modelsAbs).filter((f) => isModelInRoot(modelsAbs, f)).sort().map((f) => (0, import_node_path47.join)(modelsAbs, f));
36450
36484
  }
36451
36485
  function trimDiagnostics(text) {
36452
36486
  return text.split("\n").filter((l) => !l.startsWith("trace:")).join("\n").trim().slice(0, 4e3);
36453
36487
  }
36454
36488
  function checkModel(tc, root, modelFile, opts = {}) {
36455
- const proofsAbs = (0, import_node_path46.join)(root, PROOFS_DIR);
36456
- const rel = (0, import_node_path46.relative)(proofsAbs, modelFile);
36489
+ const proofsAbs = (0, import_node_path47.join)(root, PROOFS_DIR);
36490
+ const rel = (0, import_node_path47.relative)(proofsAbs, modelFile);
36457
36491
  const problem = proofsWorkspaceProblem(root);
36458
36492
  const res = problem ? refused(problem) : run2(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
36459
36493
  return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
36460
36494
  }
36461
36495
  async function checkModelAsync(tc, root, modelFile, opts = {}) {
36462
- const proofsAbs = (0, import_node_path46.join)(root, PROOFS_DIR);
36463
- const rel = (0, import_node_path46.relative)(proofsAbs, modelFile);
36496
+ const proofsAbs = (0, import_node_path47.join)(root, PROOFS_DIR);
36497
+ const rel = (0, import_node_path47.relative)(proofsAbs, modelFile);
36464
36498
  const problem = proofsWorkspaceProblem(root);
36465
36499
  const res = problem ? refused(problem) : await runAsync(tc, proofsAbs, ["env", "lean", rel], opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
36466
36500
  return toReport(res, root, modelFile, opts.timeoutMs ?? DEFAULT_CHECK_TIMEOUT_MS);
@@ -36469,10 +36503,10 @@ function toReport(res, root, modelFile, timeoutMs) {
36469
36503
  const parsed = parseVerityLines(res.stdout);
36470
36504
  const combined = `${res.stdout}
36471
36505
  ${res.stderr}`;
36472
- const name2 = parsed.header?.model ?? (0, import_node_path46.basename)(modelFile, ".lean");
36506
+ const name2 = parsed.header?.model ?? (0, import_node_path47.basename)(modelFile, ".lean");
36473
36507
  const report = {
36474
36508
  model: name2,
36475
- file: (0, import_node_path46.relative)(root, modelFile),
36509
+ file: (0, import_node_path47.relative)(root, modelFile),
36476
36510
  ok: res.ok,
36477
36511
  header: parsed.header,
36478
36512
  properties: parsed.properties,
@@ -36519,9 +36553,9 @@ function isCrashTrace(trace) {
36519
36553
  }
36520
36554
  function mergeFormalFindings(response, outcome, pushedFiles) {
36521
36555
  if (!outcome) return { blocking: 0 };
36522
- const norm2 = (p) => p.replace(/\\/g, "/");
36523
- const pushed = new Set(pushedFiles.map(norm2));
36524
- const blocking = outcome.findings.filter((f) => f.verdict === "reproduced" && !f.waived && pushed.has(norm2(f.file)));
36556
+ const norm3 = (p) => p.replace(/\\/g, "/");
36557
+ const pushed = new Set(pushedFiles.map(norm3));
36558
+ const blocking = outcome.findings.filter((f) => f.verdict === "reproduced" && !f.waived && pushed.has(norm3(f.file)));
36525
36559
  if (blocking.length === 0) return { blocking: 0 };
36526
36560
  const existing = Array.isArray(response.findings) ? response.findings : [];
36527
36561
  response.findings = [
@@ -36717,15 +36751,15 @@ function nonNegative(v) {
36717
36751
  return typeof v === "number" && Number.isFinite(v) && v > 0 ? v : 0;
36718
36752
  }
36719
36753
  function readLedger(root) {
36720
- const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
36721
- const empty = { day: today, models: 0, costUsd: 0 };
36754
+ const today2 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
36755
+ const empty = { day: today2, models: 0, costUsd: 0 };
36722
36756
  if (!isLocalState(root, AUTO_LEDGER)) return empty;
36723
36757
  const read2 = readRegularFileInRoot(root, AUTO_LEDGER, 4096);
36724
36758
  if (!read2.ok) return empty;
36725
36759
  try {
36726
36760
  const o = JSON.parse(read2.content);
36727
- if (o.day !== today || typeof o.models !== "number") return empty;
36728
- return { day: today, models: nonNegative(o.models), costUsd: nonNegative(o.costUsd) };
36761
+ if (o.day !== today2 || typeof o.models !== "number") return empty;
36762
+ return { day: today2, models: nonNegative(o.models), costUsd: nonNegative(o.costUsd) };
36729
36763
  } catch {
36730
36764
  return empty;
36731
36765
  }
@@ -36903,7 +36937,7 @@ async function runFormalPhase(input) {
36903
36937
  const ranked = await deps.rank(eligible, root, input.changedLines);
36904
36938
  if (!ranked.ok && ranked.disabled) return done({ status: "skipped", skip: "disabled-by-server", detail: ranked.error });
36905
36939
  if (ranked.ok) spend(ranked);
36906
- 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)) }));
36940
+ 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)), commits: c.commits, fixCommits: c.fixCommits, risk: c.risk }));
36907
36941
  if (cancelled()) return done({ status: "skipped", skip: "deadline", detail: "cut off after ranking" });
36908
36942
  const minScore = input.minScore ?? DEFAULT_MIN_SCORE;
36909
36943
  let qualified = ranked.ranked.filter((c) => c.ai && c.ai.score >= minScore);
@@ -37012,7 +37046,7 @@ async function runFormalPhase(input) {
37012
37046
  const sha2562 = sha256Of(chosen.content);
37013
37047
  const chosenContent = chosen.content;
37014
37048
  const { lines, numbered: numbered2 } = chosen;
37015
- const target = { file: top.file, symbol: top.ai.symbol, lines, score: top.ai.score, reasons: [...top.reasons, ...top.ai.reasons], extent: chosen.extent, ...chosen.context ? { context: chosen.context.stats } : {}, ...floor ? { floor: true } : {} };
37049
+ const target = { file: top.file, symbol: top.ai.symbol, lines, score: top.ai.score, reasons: [...top.reasons, ...top.ai.reasons], extent: chosen.extent, ...chosen.context ? { context: chosen.context.stats } : {}, ...floor ? { floor: true } : {}, signals: { commits: top.commits, fixCommits: top.fixCommits, risk: top.risk } };
37016
37050
  progress.target = target;
37017
37051
  if (!REPLAYABLE.test(top.file)) return done({ status: "skipped", skip: "replay-unsupported", detail: `${top.file}: replay supports TS/JS and Python`, target });
37018
37052
  if (timeLeft() < GENERATE_RESERVE_MS) return done({ status: "skipped", skip: "not-enough-time", detail: `${Math.round(timeLeft() / 1e3)} s left before generation`, target });
@@ -37042,7 +37076,7 @@ async function runFormalPhase(input) {
37042
37076
  modelName = gen.name;
37043
37077
  const rel = `${AUTO_MODELS_DIR}/${gen.name}.lean`;
37044
37078
  writeFileInRootNoFollow(root, rel, gen.source);
37045
- const abs = resolveModelFile(root, rel) ?? (0, import_node_path47.join)(root, rel);
37079
+ const abs = resolveModelFile(root, rel) ?? (0, import_node_path48.join)(root, rel);
37046
37080
  progress.model = { name: gen.name, file: rel, rounds: round };
37047
37081
  progress.step = "check";
37048
37082
  report = await deps.check(root, abs);
@@ -37164,7 +37198,7 @@ async function runFormalPhase(input) {
37164
37198
  return done({
37165
37199
  status: "checked",
37166
37200
  target,
37167
- model: { name: modelName, file: (0, import_node_path47.relative)(root, (0, import_node_path47.join)(root, modelFile)), rounds },
37201
+ model: { name: modelName, file: (0, import_node_path48.relative)(root, (0, import_node_path48.join)(root, modelFile)), rounds },
37168
37202
  properties: report.properties,
37169
37203
  findings
37170
37204
  });
@@ -37241,7 +37275,7 @@ async function generateAndCheck(root, req, opts) {
37241
37275
  }
37242
37276
  const rel = `${dir}/${gen.name}.lean`;
37243
37277
  writeFileInRootNoFollow(root, rel, gen.source);
37244
- const abs = resolveModelFile(root, rel) ?? (0, import_node_path47.join)(root, rel);
37278
+ const abs = resolveModelFile(root, rel) ?? (0, import_node_path48.join)(root, rel);
37245
37279
  const report = await opts.deps.check(root, abs);
37246
37280
  const abstracts = report.header?.abstracts ?? [];
37247
37281
  const stray = abstracts.find((a) => !headerFiles.has(a.file)) ?? (abstracts[0] && abstracts[0].file !== req.file ? abstracts[0] : void 0);
@@ -37372,13 +37406,138 @@ function describeFormalOutcome(o) {
37372
37406
  return `formal: ${o.model?.name ?? "?"} on ${o.target?.file ?? "?"}#${o.target?.symbol ?? "?"} (${o.model?.rounds ?? 1} round${o.model?.rounds === 1 ? "" : "s"}) \xB7 ${parts2.join(" \xB7 ")} \xB7 ${Math.round(o.durationMs / 1e3)} s${cost}${cut}`;
37373
37407
  }
37374
37408
 
37409
+ // src/lib/prove/record.ts
37410
+ var RECORD_TIMEOUT_MS = 8e3;
37411
+ var HOOK_EXIT_MARGIN_MS = 5e3;
37412
+ var MIN_RECORD_POST_MS = 1e3;
37413
+ function guardRecordDeadline(hookStartedAt) {
37414
+ return hookStartedAt + GUARD_TIMEOUT_MS - HOOK_EXIT_MARGIN_MS;
37415
+ }
37416
+ function recordPostTimeout(now, deadlineAt, timeoutMs = RECORD_TIMEOUT_MS) {
37417
+ if (deadlineAt === void 0) return timeoutMs;
37418
+ const left = deadlineAt - now;
37419
+ return left < MIN_RECORD_POST_MS ? null : Math.min(timeoutMs, left);
37420
+ }
37421
+ var norm2 = (p) => p.replace(/\\/g, "/");
37422
+ var SAFE_SEGMENT = /^[A-Za-z0-9._@+~$()[\]-]{1,255}$/;
37423
+ function safeRepoPath(p) {
37424
+ const n = norm2(p);
37425
+ if (!n || n.length > 512 || n.startsWith("/") || /^[A-Za-z]:\//.test(n)) return null;
37426
+ return n.split("/").every((s) => s !== "." && s !== ".." && SAFE_SEGMENT.test(s)) ? n : null;
37427
+ }
37428
+ var SYMBOL = /^[A-Za-z_$][\w$]*(?:[.#:][A-Za-z_$][\w$]*)*$/;
37429
+ var IDENT3 = /^[A-Za-z][\w]*$/;
37430
+ var TRACE_STEP = /^[A-Za-z_]\w{0,63}$/;
37431
+ var ELIDED_STEP = "\u2026";
37432
+ function recordBasis(source2) {
37433
+ if (typeof source2 !== "string") return "";
37434
+ if (/^rule:[a-z-]+$/.test(source2)) return source2;
37435
+ const m = /^(?:([^:\s]+):)?L(\d+)(?::|$)/.exec(source2);
37436
+ return m ? m[1] ? `${norm2(m[1])}:L${m[2]}` : `L${m[2]}` : "";
37437
+ }
37438
+ function recordTrace(trace) {
37439
+ return trace.slice(0, 16).map((s) => {
37440
+ const name2 = (s.trim().split(/[\s(]/, 1)[0] ?? "").split(".").pop() ?? "";
37441
+ return TRACE_STEP.test(name2) ? name2 : ELIDED_STEP;
37442
+ });
37443
+ }
37444
+ var ident2 = (s, re, max) => typeof s === "string" && s.length <= max && re.test(s) ? s : null;
37445
+ var kind = (k) => k === "intent" ? "intent" : "structural";
37446
+ var signalsOf = (c) => c && typeof c.commits === "number" && typeof c.fixCommits === "number" ? { commits: c.commits, fix_commits: c.fixCommits, risk: Object.fromEntries(Object.entries(c.risk ?? {}).filter(([, n]) => typeof n === "number" && n > 0).slice(0, 16)) } : null;
37447
+ function buildPhaseRecord(outcome, ctx) {
37448
+ const pushed = new Set(ctx.pushedFiles.map(norm2));
37449
+ const blocks = (f) => ctx.moment === "push" && f.verdict === "reproduced" && !f.waived && pushed.has(norm2(f.file));
37450
+ const symbol = (s) => ident2(s, SYMBOL, 200);
37451
+ return {
37452
+ moment: ctx.moment,
37453
+ status: outcome.status,
37454
+ skip: outcome.skip ?? null,
37455
+ parent_run_id: ctx.parentRunId,
37456
+ target: outcome.target && symbol(outcome.target.symbol) && safeRepoPath(outcome.target.file) ? {
37457
+ file: safeRepoPath(outcome.target.file),
37458
+ symbol: symbol(outcome.target.symbol),
37459
+ lines: outcome.target.lines ?? null,
37460
+ score: Math.max(0, Math.min(1, outcome.target.score)),
37461
+ extent: ident2(outcome.target.extent, /^[a-z-]+(?::[a-z-]+)?$/, 60),
37462
+ signals: signalsOf(outcome.target.signals)
37463
+ } : null,
37464
+ candidates: (outcome.candidates ?? []).filter((c) => safeRepoPath(c.file)).slice(0, 12).map((c) => ({
37465
+ file: safeRepoPath(c.file),
37466
+ symbol: c.symbol === null ? null : symbol(c.symbol),
37467
+ score: c.score === null ? null : Math.max(0, Math.min(1, c.score)),
37468
+ criteria: c.criteria,
37469
+ reasked: c.reasked,
37470
+ signals: signalsOf(c)
37471
+ })),
37472
+ model: outcome.model && ident2(outcome.model.name, /^[A-Za-z][\w]*(?:\.[A-Za-z][\w]*)*$/, 120) ? { name: outcome.model.name, rounds: Math.max(0, Math.min(20, outcome.model.rounds)) } : null,
37473
+ properties: (outcome.properties ?? []).filter((p) => ident2(p.id, IDENT3, 120)).slice(0, 16).map((p) => ({
37474
+ id: p.id,
37475
+ kind: kind(p.kind),
37476
+ basis: recordBasis(p.source),
37477
+ result: p.result,
37478
+ bound: p.bound ?? null,
37479
+ states: p.states ?? null
37480
+ })),
37481
+ findings: outcome.findings.filter((f) => ident2(f.property, IDENT3, 120) && symbol(f.symbol) && safeRepoPath(f.file)).slice(0, 8).map((f) => ({
37482
+ property: f.property,
37483
+ kind: kind(f.kind),
37484
+ trace: recordTrace(f.trace),
37485
+ file: safeRepoPath(f.file),
37486
+ symbol: f.symbol,
37487
+ verdict: f.verdict,
37488
+ waived: f.waived === true,
37489
+ blocked: blocks(f)
37490
+ })),
37491
+ grounding: outcome.grounding ? {
37492
+ sent_back: outcome.grounding.sentBack,
37493
+ dropped: outcome.grounding.dropped.filter((id) => ident2(id, IDENT3, 120)).slice(0, 16),
37494
+ trigger_missing: (outcome.grounding.triggerMissing ?? []).filter((id) => ident2(id, IDENT3, 120)).slice(0, 16)
37495
+ } : null,
37496
+ usage: {
37497
+ input_tokens: outcome.usage.inputTokens,
37498
+ output_tokens: outcome.usage.outputTokens,
37499
+ cost_usd: outcome.usage.costUsd,
37500
+ unpriced: outcome.usage.unpriced
37501
+ },
37502
+ duration_ms: Math.round(outcome.durationMs)
37503
+ };
37504
+ }
37505
+ async function postPhaseRecord(outcome, ctx, post) {
37506
+ try {
37507
+ const timeout = recordPostTimeout((post.now ?? Date.now)(), post.deadlineAt, post.timeoutMs ?? RECORD_TIMEOUT_MS);
37508
+ if (timeout === null) {
37509
+ logEvent("formal_record_skipped", { moment: ctx.moment, reason: "hook-deadline" });
37510
+ return null;
37511
+ }
37512
+ const res = await apiRequest({
37513
+ method: "POST",
37514
+ path: "/prove/record",
37515
+ serviceUrl: post.serviceUrl,
37516
+ token: post.token,
37517
+ body: buildPhaseRecord(outcome, ctx),
37518
+ timeout,
37519
+ cmd: "prove-record"
37520
+ });
37521
+ if (!res.ok) {
37522
+ logEvent("formal_record_failed", { moment: ctx.moment, category: res.category ?? "unknown", http_status: res.http_status ?? null });
37523
+ return null;
37524
+ }
37525
+ const runId = typeof res.data?.run_id === "string" ? res.data.run_id : null;
37526
+ logEvent("formal_record", { moment: ctx.moment, run_id: runId });
37527
+ return runId;
37528
+ } catch (err2) {
37529
+ logEvent("formal_record_failed", { moment: ctx.moment, category: "exception", name: err2?.constructor?.name ?? "Error" });
37530
+ return null;
37531
+ }
37532
+ }
37533
+
37375
37534
  // src/commands/guard.ts
37376
37535
  var EXCERPT_SOURCE_MAX_BYTES = 2 * 1024 * 1024;
37377
37536
  var WRITERS_BUDGET_MS = 1500;
37378
37537
  var EXCERPT_MAX_LINES2 = 30;
37379
37538
  var VENDORED_READ_MAX_BYTES = 256 * 1024;
37380
37539
  var GUARD_BLOCK_CAP = 2;
37381
- var GUARD_ITER_FILE = (0, import_node_path48.join)(VERITY_DIR, ".guard-iteration");
37540
+ var GUARD_ITER_FILE = (0, import_node_path49.join)(VERITY_DIR, ".guard-iteration");
37382
37541
  function readPreToolUseStdin() {
37383
37542
  const empty = { command: "", cwd: null, sessionId: null };
37384
37543
  return new Promise((resolve9) => {
@@ -37423,7 +37582,7 @@ function readPreToolUseStdin() {
37423
37582
  }
37424
37583
  function readIterMap() {
37425
37584
  try {
37426
- const raw = JSON.parse((0, import_node_fs61.readFileSync)(GUARD_ITER_FILE, "utf-8"));
37585
+ const raw = JSON.parse((0, import_node_fs62.readFileSync)(GUARD_ITER_FILE, "utf-8"));
37427
37586
  if (raw && typeof raw === "object") {
37428
37587
  if (typeof raw.moment === "string" && typeof raw.count === "number") {
37429
37588
  return { [raw.moment]: raw.count };
@@ -37443,10 +37602,10 @@ function readIter(moment) {
37443
37602
  }
37444
37603
  function writeIter(moment, count) {
37445
37604
  try {
37446
- (0, import_node_fs61.mkdirSync)(VERITY_DIR, { recursive: true });
37605
+ (0, import_node_fs62.mkdirSync)(VERITY_DIR, { recursive: true });
37447
37606
  const map = readIterMap();
37448
37607
  map[moment] = count;
37449
- (0, import_node_fs61.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
37608
+ (0, import_node_fs62.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
37450
37609
  } catch {
37451
37610
  }
37452
37611
  }
@@ -37456,10 +37615,10 @@ function resetIter(moment) {
37456
37615
  if (!(moment in map)) return;
37457
37616
  delete map[moment];
37458
37617
  if (Object.keys(map).length === 0) {
37459
- if ((0, import_node_fs61.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs61.unlinkSync)(GUARD_ITER_FILE);
37618
+ if ((0, import_node_fs62.existsSync)(GUARD_ITER_FILE)) (0, import_node_fs62.unlinkSync)(GUARD_ITER_FILE);
37460
37619
  } else {
37461
- (0, import_node_fs61.mkdirSync)(VERITY_DIR, { recursive: true });
37462
- (0, import_node_fs61.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
37620
+ (0, import_node_fs62.mkdirSync)(VERITY_DIR, { recursive: true });
37621
+ (0, import_node_fs62.writeFileSync)(GUARD_ITER_FILE, JSON.stringify(map));
37463
37622
  }
37464
37623
  } catch {
37465
37624
  }
@@ -37529,7 +37688,7 @@ function hasBlockingFinding(response, sentFiles) {
37529
37688
  function buildGuardRequest(moment, files, codeDelta, iter, sessionId, statedIntent, coverageTelemetry) {
37530
37689
  const analyzable = filterAnalyzable(files);
37531
37690
  const securityFiles = filterSecurity(files);
37532
- const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs61.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
37691
+ const scannable = Array.from(/* @__PURE__ */ new Set([...analyzable, ...securityFiles])).map((f) => (0, import_node_fs62.existsSync)(f) ? f : resolveFile(f)).filter((f) => f !== null);
37533
37692
  const staticResults = runCodacyAnalysisIfAvailable(scannable);
37534
37693
  const trigger = moment === "pre-commit" ? "hook:pre-commit" : "hook:pre-push";
37535
37694
  const requestBody = {
@@ -37946,6 +38105,13 @@ async function runGuard(opts, globals) {
37946
38105
  const witnessed = [...codeDelta.files.map((f) => f.path), ...agentVerdict?.witnessed_files ?? []];
37947
38106
  mergeFormalFindings(response, formalOutcome, files);
37948
38107
  decision = response.gate_decision ?? "(unrecognised)";
38108
+ if (formalOutcome) {
38109
+ await postPhaseRecord(formalOutcome, {
38110
+ moment: "push",
38111
+ parentRunId: typeof response.run_id === "string" ? response.run_id : null,
38112
+ pushedFiles: files
38113
+ }, { serviceUrl: urlResult.data, token: tokenResult.data.token, deadlineAt: guardRecordDeadline(hookStartedAt) });
38114
+ }
37949
38115
  if (!result.ok) {
37950
38116
  const authRemedy = result.error.startsWith("STALE_VERIFICATION") ? " Your GitHub verification expired \u2014 run `verity login` to re-verify." : result.error.startsWith("FORBIDDEN") ? " No access grant for this repository \u2014 run `verity login` to refresh your grants." : result.error.startsWith("INVALID_TOKEN") ? " Your Verity login expired or was revoked \u2014 run `verity login` to sign in again." : "";
37951
38117
  if (oneShotLostOutcome({ agentGate: decision, agentBlocking: hasBlockingFinding(response, witnessed) }) === "block") {
@@ -38155,7 +38321,7 @@ function registerIgnoreCommand(program2) {
38155
38321
 
38156
38322
  // src/commands/waive.ts
38157
38323
  var import_node_crypto20 = require("node:crypto");
38158
- var import_node_fs62 = require("node:fs");
38324
+ var import_node_fs63 = require("node:fs");
38159
38325
  function registerWaiveCommand(program2) {
38160
38326
  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) => {
38161
38327
  const globals = program2.opts();
@@ -38184,7 +38350,7 @@ function registerWaiveCommand(program2) {
38184
38350
  if (opts.file) {
38185
38351
  body2.file = opts.file;
38186
38352
  try {
38187
- body2.file_sha256 = (0, import_node_crypto20.createHash)("sha256").update((0, import_node_fs62.readFileSync)(opts.file)).digest("hex");
38353
+ body2.file_sha256 = (0, import_node_crypto20.createHash)("sha256").update((0, import_node_fs63.readFileSync)(opts.file)).digest("hex");
38188
38354
  } catch {
38189
38355
  printError(`Cannot read ${opts.file} \u2014 run from the repo root, or omit --file to waive by pattern.`);
38190
38356
  process.exit(1);
@@ -38209,10 +38375,10 @@ function registerWaiveCommand(program2) {
38209
38375
  }
38210
38376
 
38211
38377
  // src/commands/init.ts
38212
- var import_node_fs67 = require("node:fs");
38378
+ var import_node_fs68 = require("node:fs");
38213
38379
  var import_promises20 = require("node:fs/promises");
38214
38380
  var import_yaml6 = __toESM2(require_dist());
38215
- var import_node_path52 = require("node:path");
38381
+ var import_node_path53 = require("node:path");
38216
38382
  var import_node_os11 = require("node:os");
38217
38383
  var import_node_child_process19 = require("node:child_process");
38218
38384
 
@@ -38292,7 +38458,7 @@ function printPhase(n, of, title, subtitle) {
38292
38458
  }
38293
38459
 
38294
38460
  // src/commands/doctor.ts
38295
- var import_node_fs63 = require("node:fs");
38461
+ var import_node_fs64 = require("node:fs");
38296
38462
 
38297
38463
  // src/lib/prereqs.ts
38298
38464
  var import_node_child_process16 = require("node:child_process");
@@ -38500,11 +38666,11 @@ async function buildReport() {
38500
38666
  const hooks = wiring.status;
38501
38667
  const provenance = cliProvenance();
38502
38668
  const telemetry = await checkTelemetry();
38503
- const hasConfig = (0, import_node_fs63.existsSync)(projectPath(CODACY_CONFIG_FILE));
38669
+ const hasConfig = (0, import_node_fs64.existsSync)(projectPath(CODACY_CONFIG_FILE));
38504
38670
  const artifacts = {
38505
- standard: (0, import_node_fs63.existsSync)(projectPath(STANDARD_FILE)),
38671
+ standard: (0, import_node_fs64.existsSync)(projectPath(STANDARD_FILE)),
38506
38672
  analysisConfig: hasConfig,
38507
- verityMd: (0, import_node_fs63.existsSync)(projectPath(VERITY_MD_FILE)),
38673
+ verityMd: (0, import_node_fs64.existsSync)(projectPath(VERITY_MD_FILE)),
38508
38674
  analysisConfigIds: hasConfig ? validatePatternIds().status : "absent"
38509
38675
  };
38510
38676
  const next = [];
@@ -38663,8 +38829,8 @@ function registerDoctorCommand(program2) {
38663
38829
  }
38664
38830
 
38665
38831
  // src/commands/migrate.ts
38666
- var import_node_fs64 = require("node:fs");
38667
- var import_node_path49 = require("node:path");
38832
+ var import_node_fs65 = require("node:fs");
38833
+ var import_node_path50 = require("node:path");
38668
38834
  var import_node_child_process17 = require("node:child_process");
38669
38835
  var LEGACY_NPM_PACKAGE = "@codacy/gate-cli";
38670
38836
  function defaultNpmRemover(pkg) {
@@ -38701,12 +38867,12 @@ async function runMigration(opts = {}) {
38701
38867
  return { actions, migrated: actions.length > 0 };
38702
38868
  }
38703
38869
  function migrateProjectDir(root, actions) {
38704
- const gateDir = (0, import_node_path49.join)(root, ".gate");
38705
- const verityDir = (0, import_node_path49.join)(root, ".verity");
38706
- if ((0, import_node_fs64.existsSync)(gateDir) && !(0, import_node_fs64.existsSync)(verityDir)) {
38870
+ const gateDir = (0, import_node_path50.join)(root, ".gate");
38871
+ const verityDir = (0, import_node_path50.join)(root, ".verity");
38872
+ if ((0, import_node_fs65.existsSync)(gateDir) && !(0, import_node_fs65.existsSync)(verityDir)) {
38707
38873
  return migrateProjectDirRename(root, gateDir, verityDir, actions);
38708
38874
  }
38709
- if ((0, import_node_fs64.existsSync)(gateDir) && (0, import_node_fs64.existsSync)(verityDir)) {
38875
+ if ((0, import_node_fs65.existsSync)(gateDir) && (0, import_node_fs65.existsSync)(verityDir)) {
38710
38876
  return migrateProjectDirCarry(gateDir, verityDir, actions);
38711
38877
  }
38712
38878
  return false;
@@ -38727,13 +38893,13 @@ function migrateProjectDirRename(root, gateDir, verityDir, actions) {
38727
38893
  }
38728
38894
  }
38729
38895
  if (moved) {
38730
- if ((0, import_node_fs64.existsSync)(gateDir)) {
38896
+ if ((0, import_node_fs65.existsSync)(gateDir)) {
38731
38897
  const carried = carryLegacyContents(gateDir, verityDir);
38732
38898
  if (carried > 0) {
38733
38899
  actions.push(`Carried ${carried} untracked legacy file(s) from .gate/ into .verity/`);
38734
38900
  }
38735
38901
  try {
38736
- (0, import_node_fs64.rmSync)(gateDir, { recursive: true, force: true });
38902
+ (0, import_node_fs65.rmSync)(gateDir, { recursive: true, force: true });
38737
38903
  } catch {
38738
38904
  }
38739
38905
  }
@@ -38749,18 +38915,18 @@ function migrateProjectDirCarry(gateDir, verityDir, actions) {
38749
38915
  actions.push(`Carried ${carried} legacy file(s) from .gate/ into .verity/`);
38750
38916
  }
38751
38917
  try {
38752
- (0, import_node_fs64.rmSync)(gateDir, { recursive: true, force: true });
38918
+ (0, import_node_fs65.rmSync)(gateDir, { recursive: true, force: true });
38753
38919
  } catch {
38754
38920
  }
38755
38921
  return carried > 0;
38756
38922
  }
38757
38923
  function migrateGlobalCredentials(home, actions) {
38758
38924
  if (!home) return;
38759
- const gateCreds = (0, import_node_path49.join)(home, ".gate", "credentials");
38760
- const verityCreds = (0, import_node_path49.join)(home, ".verity", "credentials");
38761
- if (!(0, import_node_fs64.existsSync)(gateCreds)) return;
38762
- if (!(0, import_node_fs64.existsSync)(verityCreds)) {
38763
- (0, import_node_fs64.mkdirSync)((0, import_node_path49.join)(home, ".verity"), { recursive: true });
38925
+ const gateCreds = (0, import_node_path50.join)(home, ".gate", "credentials");
38926
+ const verityCreds = (0, import_node_path50.join)(home, ".verity", "credentials");
38927
+ if (!(0, import_node_fs65.existsSync)(gateCreds)) return;
38928
+ if (!(0, import_node_fs65.existsSync)(verityCreds)) {
38929
+ (0, import_node_fs65.mkdirSync)((0, import_node_path50.join)(home, ".verity"), { recursive: true });
38764
38930
  moveFile(gateCreds, verityCreds);
38765
38931
  actions.push("Moved ~/.gate/credentials \u2192 ~/.verity/credentials");
38766
38932
  return;
@@ -38782,8 +38948,8 @@ async function migrateLegacyHooks(root, actions) {
38782
38948
  }
38783
38949
  }
38784
38950
  async function migrateClaudeMd(root, actions) {
38785
- const claudeMd = (0, import_node_path49.join)(root, "CLAUDE.md");
38786
- const hadLegacyBlock = (0, import_node_fs64.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
38951
+ const claudeMd = (0, import_node_path50.join)(root, "CLAUDE.md");
38952
+ const hadLegacyBlock = (0, import_node_fs65.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd));
38787
38953
  if (!hadLegacyBlock) return;
38788
38954
  try {
38789
38955
  await ensureClaudeMdPointer(root);
@@ -38793,9 +38959,9 @@ async function migrateClaudeMd(root, actions) {
38793
38959
  }
38794
38960
  }
38795
38961
  function migrateStandardFile(root, actions) {
38796
- const gateMd = (0, import_node_path49.join)(root, "GATE.md");
38797
- const verityMd = (0, import_node_path49.join)(root, "VERITY.md");
38798
- if (!(0, import_node_fs64.existsSync)(gateMd) || (0, import_node_fs64.existsSync)(verityMd)) return;
38962
+ const gateMd = (0, import_node_path50.join)(root, "GATE.md");
38963
+ const verityMd = (0, import_node_path50.join)(root, "VERITY.md");
38964
+ if (!(0, import_node_fs65.existsSync)(gateMd) || (0, import_node_fs65.existsSync)(verityMd)) return;
38799
38965
  let moved = false;
38800
38966
  if (isGitRepo(root) && isGitTracked(root, "GATE.md")) {
38801
38967
  try {
@@ -38807,12 +38973,12 @@ function migrateStandardFile(root, actions) {
38807
38973
  if (!moved) moveFile(gateMd, verityMd);
38808
38974
  const content = readFileSyncSafe(verityMd);
38809
38975
  const refreshed = content.split("GATE.md").join("VERITY.md");
38810
- if (refreshed !== content) (0, import_node_fs64.writeFileSync)(verityMd, refreshed);
38976
+ if (refreshed !== content) (0, import_node_fs65.writeFileSync)(verityMd, refreshed);
38811
38977
  actions.push("Renamed GATE.md \u2192 VERITY.md");
38812
38978
  }
38813
38979
  async function migrateTelemetryHeaders(root, actions) {
38814
- const file = (0, import_node_path49.join)(root, ".claude", "settings.local.json");
38815
- if (!(0, import_node_fs64.existsSync)(file)) return;
38980
+ const file = (0, import_node_path50.join)(root, ".claude", "settings.local.json");
38981
+ if (!(0, import_node_fs65.existsSync)(file)) return;
38816
38982
  let settings;
38817
38983
  try {
38818
38984
  settings = JSON.parse(readFileSyncSafe(file) || "{}");
@@ -38860,14 +39026,14 @@ function mergeGlobalCredentials(gateCreds, verityCreds) {
38860
39026
  }
38861
39027
  if (toAppend.length > 0) {
38862
39028
  const sep6 = verityContent.endsWith("\n") || verityContent === "" ? "" : "\n";
38863
- (0, import_node_fs64.writeFileSync)(verityCreds, verityContent + sep6 + toAppend.join("\n") + "\n");
39029
+ (0, import_node_fs65.writeFileSync)(verityCreds, verityContent + sep6 + toAppend.join("\n") + "\n");
38864
39030
  }
38865
- (0, import_node_fs64.rmSync)(gateCreds, { force: true });
39031
+ (0, import_node_fs65.rmSync)(gateCreds, { force: true });
38866
39032
  return toAppend.length;
38867
39033
  }
38868
39034
  function readFileSyncSafe(path) {
38869
39035
  try {
38870
- return (0, import_node_fs64.readFileSync)(path, "utf-8");
39036
+ return (0, import_node_fs65.readFileSync)(path, "utf-8");
38871
39037
  } catch {
38872
39038
  return "";
38873
39039
  }
@@ -38882,35 +39048,35 @@ function hasStagedChanges(root) {
38882
39048
  }
38883
39049
  function moveDir(from, to) {
38884
39050
  try {
38885
- (0, import_node_fs64.renameSync)(from, to);
39051
+ (0, import_node_fs65.renameSync)(from, to);
38886
39052
  } catch (err2) {
38887
39053
  if (err2.code !== "EXDEV") throw err2;
38888
- (0, import_node_fs64.cpSync)(from, to, { recursive: true });
38889
- (0, import_node_fs64.rmSync)(from, { recursive: true, force: true });
39054
+ (0, import_node_fs65.cpSync)(from, to, { recursive: true });
39055
+ (0, import_node_fs65.rmSync)(from, { recursive: true, force: true });
38890
39056
  }
38891
39057
  }
38892
39058
  function moveFile(from, to) {
38893
39059
  try {
38894
- (0, import_node_fs64.renameSync)(from, to);
39060
+ (0, import_node_fs65.renameSync)(from, to);
38895
39061
  } catch (err2) {
38896
39062
  if (err2.code !== "EXDEV") throw err2;
38897
- (0, import_node_fs64.cpSync)(from, to);
38898
- (0, import_node_fs64.rmSync)(from, { force: true });
39063
+ (0, import_node_fs65.cpSync)(from, to);
39064
+ (0, import_node_fs65.rmSync)(from, { force: true });
38899
39065
  }
38900
39066
  }
38901
39067
  function carryLegacyContents(gateDir, verityDir) {
38902
39068
  let copied = 0;
38903
39069
  const walk2 = (relDir) => {
38904
- const srcDir = (0, import_node_path49.join)(gateDir, relDir);
38905
- for (const entry of (0, import_node_fs64.readdirSync)(srcDir)) {
38906
- const rel = relDir ? (0, import_node_path49.join)(relDir, entry) : entry;
38907
- const src = (0, import_node_path49.join)(gateDir, rel);
38908
- const dest = (0, import_node_path49.join)(verityDir, rel);
38909
- if ((0, import_node_fs64.statSync)(src).isDirectory()) {
39070
+ const srcDir = (0, import_node_path50.join)(gateDir, relDir);
39071
+ for (const entry of (0, import_node_fs65.readdirSync)(srcDir)) {
39072
+ const rel = relDir ? (0, import_node_path50.join)(relDir, entry) : entry;
39073
+ const src = (0, import_node_path50.join)(gateDir, rel);
39074
+ const dest = (0, import_node_path50.join)(verityDir, rel);
39075
+ if ((0, import_node_fs65.statSync)(src).isDirectory()) {
38910
39076
  walk2(rel);
38911
- } else if (!(0, import_node_fs64.existsSync)(dest)) {
38912
- (0, import_node_fs64.mkdirSync)((0, import_node_path49.dirname)(dest), { recursive: true });
38913
- (0, import_node_fs64.cpSync)(src, dest);
39077
+ } else if (!(0, import_node_fs65.existsSync)(dest)) {
39078
+ (0, import_node_fs65.mkdirSync)((0, import_node_path50.dirname)(dest), { recursive: true });
39079
+ (0, import_node_fs65.cpSync)(src, dest);
38914
39080
  copied++;
38915
39081
  }
38916
39082
  }
@@ -38919,22 +39085,22 @@ function carryLegacyContents(gateDir, verityDir) {
38919
39085
  return copied;
38920
39086
  }
38921
39087
  async function needsMigration(root = repoRoot()) {
38922
- const gateDir = (0, import_node_path49.join)(root, ".gate");
38923
- const verityDir = (0, import_node_path49.join)(root, ".verity");
38924
- if ((0, import_node_fs64.existsSync)(gateDir) && !(0, import_node_fs64.existsSync)(verityDir)) return true;
38925
- if ((0, import_node_fs64.existsSync)(gateDir) && (0, import_node_fs64.existsSync)(verityDir)) {
38926
- if ((0, import_node_fs64.existsSync)((0, import_node_path49.join)(gateDir, "credentials")) && !(0, import_node_fs64.existsSync)((0, import_node_path49.join)(verityDir, "credentials"))) {
39088
+ const gateDir = (0, import_node_path50.join)(root, ".gate");
39089
+ const verityDir = (0, import_node_path50.join)(root, ".verity");
39090
+ if ((0, import_node_fs65.existsSync)(gateDir) && !(0, import_node_fs65.existsSync)(verityDir)) return true;
39091
+ if ((0, import_node_fs65.existsSync)(gateDir) && (0, import_node_fs65.existsSync)(verityDir)) {
39092
+ if ((0, import_node_fs65.existsSync)((0, import_node_path50.join)(gateDir, "credentials")) && !(0, import_node_fs65.existsSync)((0, import_node_path50.join)(verityDir, "credentials"))) {
38927
39093
  return true;
38928
39094
  }
38929
- if ((0, import_node_fs64.existsSync)((0, import_node_path49.join)(gateDir, "memory")) && !(0, import_node_fs64.existsSync)((0, import_node_path49.join)(verityDir, "memory"))) {
39095
+ if ((0, import_node_fs65.existsSync)((0, import_node_path50.join)(gateDir, "memory")) && !(0, import_node_fs65.existsSync)((0, import_node_path50.join)(verityDir, "memory"))) {
38930
39096
  return true;
38931
39097
  }
38932
39098
  }
38933
- const claudeMd = (0, import_node_path49.join)(root, "CLAUDE.md");
38934
- if ((0, import_node_fs64.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
39099
+ const claudeMd = (0, import_node_path50.join)(root, "CLAUDE.md");
39100
+ if ((0, import_node_fs65.existsSync)(claudeMd) && hasLegacyMemoryBlock(readFileSyncSafe(claudeMd))) {
38935
39101
  return true;
38936
39102
  }
38937
- if ((0, import_node_fs64.existsSync)((0, import_node_path49.join)(root, "GATE.md")) && !(0, import_node_fs64.existsSync)((0, import_node_path49.join)(root, "VERITY.md"))) {
39103
+ if ((0, import_node_fs65.existsSync)((0, import_node_path50.join)(root, "GATE.md")) && !(0, import_node_fs65.existsSync)((0, import_node_path50.join)(root, "VERITY.md"))) {
38938
39104
  return true;
38939
39105
  }
38940
39106
  if (await hasLegacyHooksAt(root)) return true;
@@ -39215,11 +39381,11 @@ async function promptMultiSelect(question, choices, fallback) {
39215
39381
  }
39216
39382
 
39217
39383
  // src/lib/prove/lean-install.ts
39218
- var import_node_fs65 = require("node:fs");
39384
+ var import_node_fs66 = require("node:fs");
39219
39385
  var import_node_crypto21 = require("node:crypto");
39220
39386
  var import_node_child_process18 = require("node:child_process");
39221
39387
  var import_node_os10 = require("node:os");
39222
- var import_node_path50 = require("node:path");
39388
+ var import_node_path51 = require("node:path");
39223
39389
  var import_promises18 = require("node:stream/promises");
39224
39390
  var import_node_stream = require("node:stream");
39225
39391
  var RELEASES = "https://releases.lean-lang.org/lean4";
@@ -39230,10 +39396,10 @@ function freeBytes(dir) {
39230
39396
  let d = dir;
39231
39397
  for (let i2 = 0; i2 < 64; i2++) {
39232
39398
  try {
39233
- const st = (0, import_node_fs65.statfsSync)(d);
39399
+ const st = (0, import_node_fs66.statfsSync)(d);
39234
39400
  return Number(st.bavail) * Number(st.bsize);
39235
39401
  } catch {
39236
- const up = (0, import_node_path50.join)(d, "..");
39402
+ const up = (0, import_node_path51.join)(d, "..");
39237
39403
  if (up === d) return null;
39238
39404
  d = up;
39239
39405
  }
@@ -39255,7 +39421,7 @@ function expectedSha256(asset, version = pinnedVersion()) {
39255
39421
  function sha256File(path) {
39256
39422
  return new Promise((resolve9, reject) => {
39257
39423
  const hash = (0, import_node_crypto21.createHash)("sha256");
39258
- (0, import_node_fs65.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve9(hash.digest("hex"))).on("error", reject);
39424
+ (0, import_node_fs66.createReadStream)(path).on("data", (chunk) => hash.update(chunk)).on("end", () => resolve9(hash.digest("hex"))).on("error", reject);
39259
39425
  });
39260
39426
  }
39261
39427
  async function verifyDownload(zip, asset, version = pinnedVersion()) {
@@ -39275,7 +39441,7 @@ function leanAssetName(version = pinnedVersion()) {
39275
39441
  return suffix ? `lean-${v}-${suffix}.zip` : null;
39276
39442
  }
39277
39443
  function pinnedVersionDir(env = process.env) {
39278
- return (0, import_node_path50.join)(verityLeanHome(env), pinnedVersion());
39444
+ return (0, import_node_path51.join)(verityLeanHome(env), pinnedVersion());
39279
39445
  }
39280
39446
  function lakeBinary() {
39281
39447
  return (0, import_node_os10.platform)() === "win32" ? "lake.exe" : "lake";
@@ -39286,12 +39452,12 @@ function unzip(zip, dest) {
39286
39452
  for (const [cmd, args2] of attempts) {
39287
39453
  try {
39288
39454
  (0, import_node_child_process18.execFileSync)(cmd, args2, { stdio: ["ignore", "ignore", "pipe"], timeout: 15 * 6e4 });
39289
- if ((0, import_node_fs65.readdirSync)(dest).length > 0) return { ok: true, via: cmd };
39455
+ if ((0, import_node_fs66.readdirSync)(dest).length > 0) return { ok: true, via: cmd };
39290
39456
  errors.push(`${cmd}: produced nothing`);
39291
39457
  } catch (err2) {
39292
39458
  errors.push(`${cmd}: ${String(err2.message).split("\n")[0].slice(0, 120)}`);
39293
39459
  try {
39294
- for (const e of (0, import_node_fs65.readdirSync)(dest)) (0, import_node_fs65.rmSync)((0, import_node_path50.join)(dest, e), { recursive: true, force: true });
39460
+ for (const e of (0, import_node_fs66.readdirSync)(dest)) (0, import_node_fs66.rmSync)((0, import_node_path51.join)(dest, e), { recursive: true, force: true });
39295
39461
  } catch {
39296
39462
  }
39297
39463
  }
@@ -39317,7 +39483,7 @@ async function download(url, dest, onProgress, stallMs = DOWNLOAD_STALL_MS) {
39317
39483
  seen += chunk.length;
39318
39484
  onProgress(seen, total);
39319
39485
  });
39320
- await (0, import_promises18.pipeline)(stream, (0, import_node_fs65.createWriteStream)(dest), { signal: ctrl.signal });
39486
+ await (0, import_promises18.pipeline)(stream, (0, import_node_fs66.createWriteStream)(dest), { signal: ctrl.signal });
39321
39487
  } catch (err2) {
39322
39488
  if (ctrl.signal.aborted) throw new Error(`download stalled: nothing received for ${Math.round(stallMs / 1e3)} s`);
39323
39489
  throw err2;
@@ -39367,10 +39533,10 @@ async function installLean(opts = {}) {
39367
39533
  const gb = (n) => (n / 1024 ** 3).toFixed(1);
39368
39534
  return { ok: false, error: `not enough disk space for Lean: ${gb(free)} GB free where ${home} lives, needs about ${gb(needed)} GB` };
39369
39535
  }
39370
- const tmp = (0, import_node_path50.join)(home, ".tmp");
39371
- (0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
39372
- (0, import_node_fs65.mkdirSync)(tmp, { recursive: true });
39373
- const zip = (0, import_node_path50.join)(tmp, asset);
39536
+ const tmp = (0, import_node_path51.join)(home, ".tmp");
39537
+ (0, import_node_fs66.rmSync)(tmp, { recursive: true, force: true });
39538
+ (0, import_node_fs66.mkdirSync)(tmp, { recursive: true });
39539
+ const zip = (0, import_node_path51.join)(tmp, asset);
39374
39540
  say(`downloading ${url}`);
39375
39541
  let lastPct = -1;
39376
39542
  try {
@@ -39383,40 +39549,40 @@ async function installLean(opts = {}) {
39383
39549
  }
39384
39550
  });
39385
39551
  } catch (err2) {
39386
- (0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
39552
+ (0, import_node_fs66.rmSync)(tmp, { recursive: true, force: true });
39387
39553
  return { ok: false, error: err2.message };
39388
39554
  }
39389
39555
  say("verifying checksum");
39390
39556
  const verified = await verifyDownload(zip, asset);
39391
39557
  if (!verified.ok) {
39392
- (0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
39558
+ (0, import_node_fs66.rmSync)(tmp, { recursive: true, force: true });
39393
39559
  return { ok: false, error: verified.error };
39394
39560
  }
39395
39561
  say("unpacking (this takes a minute)");
39396
- const unpack = (0, import_node_path50.join)(tmp, "unpack");
39397
- (0, import_node_fs65.mkdirSync)(unpack);
39562
+ const unpack = (0, import_node_path51.join)(tmp, "unpack");
39563
+ (0, import_node_fs66.mkdirSync)(unpack);
39398
39564
  const unpacked = unzip(zip, unpack);
39399
39565
  if (!unpacked.ok) {
39400
- (0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
39566
+ (0, import_node_fs66.rmSync)(tmp, { recursive: true, force: true });
39401
39567
  return { ok: false, error: `unpack failed: ${unpacked.error}` };
39402
39568
  }
39403
- const entries = (0, import_node_fs65.readdirSync)(unpack);
39404
- const top = entries.length === 1 && (0, import_node_fs65.statSync)((0, import_node_path50.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path50.join)(unpack, entries[0]) : unpack;
39405
- if (!(0, import_node_fs65.existsSync)((0, import_node_path50.join)(top, "bin", lakeBinary()))) {
39406
- (0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
39569
+ const entries = (0, import_node_fs66.readdirSync)(unpack);
39570
+ const top = entries.length === 1 && (0, import_node_fs66.statSync)((0, import_node_path51.join)(unpack, entries[0])).isDirectory() ? (0, import_node_path51.join)(unpack, entries[0]) : unpack;
39571
+ if (!(0, import_node_fs66.existsSync)((0, import_node_path51.join)(top, "bin", lakeBinary()))) {
39572
+ (0, import_node_fs66.rmSync)(tmp, { recursive: true, force: true });
39407
39573
  return { ok: false, error: "the archive did not contain bin/lake" };
39408
39574
  }
39409
- (0, import_node_fs65.rmSync)(dir, { recursive: true, force: true });
39410
- (0, import_node_fs65.mkdirSync)(home, { recursive: true });
39411
- (0, import_node_fs65.renameSync)(top, dir);
39412
- (0, import_node_fs65.rmSync)(tmp, { recursive: true, force: true });
39575
+ (0, import_node_fs66.rmSync)(dir, { recursive: true, force: true });
39576
+ (0, import_node_fs66.mkdirSync)(home, { recursive: true });
39577
+ (0, import_node_fs66.renameSync)(top, dir);
39578
+ (0, import_node_fs66.rmSync)(tmp, { recursive: true, force: true });
39413
39579
  return { ok: true, dir };
39414
39580
  }
39415
39581
 
39416
39582
  // src/lib/remote-config.ts
39417
- var import_node_fs66 = require("node:fs");
39583
+ var import_node_fs67 = require("node:fs");
39418
39584
  var import_promises19 = require("node:fs/promises");
39419
- var import_node_path51 = require("node:path");
39585
+ var import_node_path52 = require("node:path");
39420
39586
  var import_yaml5 = __toESM2(require_dist());
39421
39587
  var IGNORE_RIDER = "verityignore";
39422
39588
  async function fetchRemoteSetup(opts) {
@@ -39461,7 +39627,7 @@ async function adoptRemoteSetup(found, opts) {
39461
39627
  written.push(STANDARD_FILE);
39462
39628
  if (rider !== null) {
39463
39629
  const localIgnore = projectPath(VERITYIGNORE_FILE);
39464
- if (!(0, import_node_fs66.existsSync)(localIgnore)) {
39630
+ if (!(0, import_node_fs67.existsSync)(localIgnore)) {
39465
39631
  await writeOut(VERITYIGNORE_FILE, rider);
39466
39632
  written.push(VERITYIGNORE_FILE);
39467
39633
  } else {
@@ -39494,7 +39660,7 @@ async function adoptRemoteSetup(found, opts) {
39494
39660
  }
39495
39661
  async function writeOut(relative6, body2) {
39496
39662
  const target = projectPath(relative6);
39497
- await (0, import_promises19.mkdir)((0, import_node_path51.dirname)(target), { recursive: true });
39663
+ await (0, import_promises19.mkdir)((0, import_node_path52.dirname)(target), { recursive: true });
39498
39664
  await (0, import_promises19.writeFile)(target, body2);
39499
39665
  }
39500
39666
  function describeRemote(found) {
@@ -39611,15 +39777,15 @@ async function runOptionalAuth(resolution, opts = {}) {
39611
39777
  }
39612
39778
  function resolveDataDir2() {
39613
39779
  const candidates2 = [
39614
- (0, import_node_path52.join)(__dirname, "..", "data"),
39780
+ (0, import_node_path53.join)(__dirname, "..", "data"),
39615
39781
  // installed: node_modules/@codacy/verity-cli/data
39616
- (0, import_node_path52.join)(__dirname, "..", "..", "data"),
39782
+ (0, import_node_path53.join)(__dirname, "..", "..", "data"),
39617
39783
  // edge case: nested resolution
39618
- (0, import_node_path52.join)(process.cwd(), "cli", "data")
39784
+ (0, import_node_path53.join)(process.cwd(), "cli", "data")
39619
39785
  // local dev: running from repo root
39620
39786
  ];
39621
39787
  for (const candidate of candidates2) {
39622
- if ((0, import_node_fs67.existsSync)((0, import_node_path52.join)(candidate, "skills"))) {
39788
+ if ((0, import_node_fs68.existsSync)((0, import_node_path53.join)(candidate, "skills"))) {
39623
39789
  return candidate;
39624
39790
  }
39625
39791
  }
@@ -39635,9 +39801,9 @@ async function skillIsCurrent(src, dest) {
39635
39801
  const list2 = (dir) => {
39636
39802
  const out2 = [];
39637
39803
  const walk2 = (d, prefix) => {
39638
- for (const e of (0, import_node_fs67.readdirSync)(d, { withFileTypes: true })) {
39804
+ for (const e of (0, import_node_fs68.readdirSync)(d, { withFileTypes: true })) {
39639
39805
  const rel = prefix ? `${prefix}/${e.name}` : e.name;
39640
- if (e.isDirectory()) walk2((0, import_node_path52.join)(d, e.name), rel);
39806
+ if (e.isDirectory()) walk2((0, import_node_path53.join)(d, e.name), rel);
39641
39807
  else if (e.isFile()) out2.push(rel);
39642
39808
  }
39643
39809
  };
@@ -39648,8 +39814,8 @@ async function skillIsCurrent(src, dest) {
39648
39814
  const shipped = list2(src);
39649
39815
  if (JSON.stringify(shipped) !== JSON.stringify(list2(dest))) return false;
39650
39816
  for (const rel of shipped) {
39651
- const a = await (0, import_promises20.readFile)((0, import_node_path52.join)(src, rel), "utf-8");
39652
- const b = await (0, import_promises20.readFile)((0, import_node_path52.join)(dest, rel), "utf-8");
39817
+ const a = await (0, import_promises20.readFile)((0, import_node_path53.join)(src, rel), "utf-8");
39818
+ const b = await (0, import_promises20.readFile)((0, import_node_path53.join)(dest, rel), "utf-8");
39653
39819
  if (a !== b) return false;
39654
39820
  }
39655
39821
  return true;
@@ -39852,7 +40018,7 @@ async function synthesizeLocally(opts) {
39852
40018
  async function healStaleAnalysisConfig(globals) {
39853
40019
  const configPath = projectPath(CODACY_CONFIG_FILE);
39854
40020
  const standardPath = projectPath(STANDARD_FILE);
39855
- if (!(0, import_node_fs67.existsSync)(configPath) || !(0, import_node_fs67.existsSync)(standardPath)) return;
40021
+ if (!(0, import_node_fs68.existsSync)(configPath) || !(0, import_node_fs68.existsSync)(standardPath)) return;
39856
40022
  const validation = validatePatternIds();
39857
40023
  if (validation.status !== "invalid") return;
39858
40024
  printWarn(" Your analysis config names pattern ids that no longer resolve \u2014 those tools were");
@@ -39949,17 +40115,17 @@ async function handoffToSetup(enabled, claudeInstalled) {
39949
40115
  async function installSkills(force, step) {
39950
40116
  step("Installing skills");
39951
40117
  const dataDir = resolveDataDir2();
39952
- const skillsSource = (0, import_node_path52.join)(dataDir, "skills");
40118
+ const skillsSource = (0, import_node_path53.join)(dataDir, "skills");
39953
40119
  const skillsDest = ".claude/skills";
39954
40120
  let skillsInstalled = 0;
39955
40121
  for (const skill of SKILLS) {
39956
- const src = (0, import_node_path52.join)(skillsSource, skill);
39957
- const dest = (0, import_node_path52.join)(skillsDest, skill);
39958
- if (!(0, import_node_fs67.existsSync)(src)) {
40122
+ const src = (0, import_node_path53.join)(skillsSource, skill);
40123
+ const dest = (0, import_node_path53.join)(skillsDest, skill);
40124
+ if (!(0, import_node_fs68.existsSync)(src)) {
39959
40125
  printWarn(` Skill data not found: ${skill}`);
39960
40126
  continue;
39961
40127
  }
39962
- if ((0, import_node_fs67.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
40128
+ if ((0, import_node_fs68.existsSync)(dest) && !force && await skillIsCurrent(src, dest)) {
39963
40129
  skillsInstalled++;
39964
40130
  continue;
39965
40131
  }
@@ -40108,7 +40274,7 @@ async function offerFormalVerification(defaultsOnly, pluginMode) {
40108
40274
  if (!toolchain) {
40109
40275
  const dir = pinnedVersionDir();
40110
40276
  const home = (0, import_node_os11.homedir)();
40111
- const shown = dir.startsWith(home + import_node_path52.sep) ? `~${dir.slice(home.length)}` : dir;
40277
+ const shown = dir.startsWith(home + import_node_path53.sep) ? `~${dir.slice(home.length)}` : dir;
40112
40278
  console.log("");
40113
40279
  console.log(` "yes" installs Lean 4 (${LEAN_DOWNLOAD_SIZE}) into ${shown}`);
40114
40280
  }
@@ -40167,7 +40333,7 @@ function registerInitCommand(program2) {
40167
40333
  const staleMarker = clearStalePluginMarker();
40168
40334
  const pluginMode = opts.plugin === false ? false : opts.pluginMode ?? pluginActiveHere();
40169
40335
  const projectMarkers = [".git", "package.json", "pyproject.toml", "go.mod", "Cargo.toml", "Gemfile", "pom.xml", "build.gradle"];
40170
- const isProject = projectMarkers.some((m) => (0, import_node_fs67.existsSync)(m));
40336
+ const isProject = projectMarkers.some((m) => (0, import_node_fs68.existsSync)(m));
40171
40337
  if (!isProject) {
40172
40338
  printError("No project detected in the current directory.");
40173
40339
  printInfo('Run "verity init" from your project root.');
@@ -40270,7 +40436,7 @@ function registerInitCommand(program2) {
40270
40436
  untrackMemory: opts.untrackMemory === true,
40271
40437
  untrackState: opts.untrackState === true
40272
40438
  });
40273
- const globalVerityDir = (0, import_node_path52.join)(process.env.HOME ?? "", ".verity");
40439
+ const globalVerityDir = (0, import_node_path53.join)(process.env.HOME ?? "", ".verity");
40274
40440
  await (0, import_promises20.mkdir)(globalVerityDir, { recursive: true });
40275
40441
  console.log("");
40276
40442
  step("Wiring Claude Code hooks");
@@ -40345,7 +40511,7 @@ function registerInitCommand(program2) {
40345
40511
  }
40346
40512
  step("Your project's Standard");
40347
40513
  let haveStandard = false;
40348
- if ((0, import_node_fs67.existsSync)(projectPath(STANDARD_FILE))) {
40514
+ if ((0, import_node_fs68.existsSync)(projectPath(STANDARD_FILE))) {
40349
40515
  printInfo(" This project already has .verity/standard.yaml \u2014 keeping it.");
40350
40516
  haveStandard = true;
40351
40517
  } else {
@@ -40375,7 +40541,7 @@ function registerInitCommand(program2) {
40375
40541
  ...telemetryChoice ? { telemetry: telemetryChoice } : {},
40376
40542
  init: {
40377
40543
  completed_at: (/* @__PURE__ */ new Date()).toISOString(),
40378
- cli_version: true ? "0.34.1-experimental.89100b5" : "dev"
40544
+ cli_version: true ? "0.34.1-experimental.c910405" : "dev"
40379
40545
  }
40380
40546
  });
40381
40547
  } catch (err2) {
@@ -40425,8 +40591,8 @@ function registerInitCommand(program2) {
40425
40591
  }
40426
40592
 
40427
40593
  // src/commands/uninstall.ts
40428
- var import_node_fs68 = require("node:fs");
40429
- var import_node_path53 = require("node:path");
40594
+ var import_node_fs69 = require("node:fs");
40595
+ var import_node_path54 = require("node:path");
40430
40596
  function registerUninstallCommand(program2) {
40431
40597
  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) => {
40432
40598
  const dryRun = opts.dryRun ?? false;
@@ -40435,11 +40601,11 @@ function registerUninstallCommand(program2) {
40435
40601
  const actions = [];
40436
40602
  const skillsRoot = projectPath(".claude/skills");
40437
40603
  for (const name2 of PROJECT_SKILL_NAMES) {
40438
- const dir = (0, import_node_path53.join)(skillsRoot, name2);
40439
- if ((0, import_node_fs68.existsSync)(dir)) {
40604
+ const dir = (0, import_node_path54.join)(skillsRoot, name2);
40605
+ if ((0, import_node_fs69.existsSync)(dir)) {
40440
40606
  actions.push({
40441
40607
  label: `Remove .claude/skills/${name2}/`,
40442
- apply: () => (0, import_node_fs68.rmSync)(dir, { recursive: true, force: true })
40608
+ apply: () => (0, import_node_fs69.rmSync)(dir, { recursive: true, force: true })
40443
40609
  });
40444
40610
  }
40445
40611
  }
@@ -40453,24 +40619,24 @@ function registerUninstallCommand(program2) {
40453
40619
  });
40454
40620
  }
40455
40621
  const verityDir = projectPath(VERITY_DIR);
40456
- if ((0, import_node_fs68.existsSync)(verityDir)) {
40622
+ if ((0, import_node_fs69.existsSync)(verityDir)) {
40457
40623
  actions.push({
40458
40624
  label: `Remove ${VERITY_DIR}/`,
40459
- apply: () => (0, import_node_fs68.rmSync)(verityDir, { recursive: true, force: true })
40625
+ apply: () => (0, import_node_fs69.rmSync)(verityDir, { recursive: true, force: true })
40460
40626
  });
40461
40627
  }
40462
40628
  if (!keepVerityMd) {
40463
40629
  const verityMd = projectPath(VERITY_MD_FILE);
40464
- if ((0, import_node_fs68.existsSync)(verityMd)) {
40630
+ if ((0, import_node_fs69.existsSync)(verityMd)) {
40465
40631
  actions.push({
40466
40632
  label: `Remove ${VERITY_MD_FILE}`,
40467
- apply: () => (0, import_node_fs68.rmSync)(verityMd, { force: true })
40633
+ apply: () => (0, import_node_fs69.rmSync)(verityMd, { force: true })
40468
40634
  });
40469
40635
  }
40470
40636
  }
40471
40637
  const cleanupEmptyDir = (path) => {
40472
- if ((0, import_node_fs68.existsSync)(path) && (0, import_node_fs68.statSync)(path).isDirectory() && (0, import_node_fs68.readdirSync)(path).length === 0) {
40473
- (0, import_node_fs68.rmdirSync)(path);
40638
+ if ((0, import_node_fs69.existsSync)(path) && (0, import_node_fs69.statSync)(path).isDirectory() && (0, import_node_fs69.readdirSync)(path).length === 0) {
40639
+ (0, import_node_fs69.rmdirSync)(path);
40474
40640
  }
40475
40641
  };
40476
40642
  actions.push({
@@ -40481,11 +40647,11 @@ function registerUninstallCommand(program2) {
40481
40647
  }
40482
40648
  });
40483
40649
  const home = process.env.HOME ?? "";
40484
- const globalVerityDir = (0, import_node_path53.join)(home, ".verity");
40485
- if (purgeGlobal && (0, import_node_fs68.existsSync)(globalVerityDir)) {
40650
+ const globalVerityDir = (0, import_node_path54.join)(home, ".verity");
40651
+ if (purgeGlobal && (0, import_node_fs69.existsSync)(globalVerityDir)) {
40486
40652
  actions.push({
40487
40653
  label: `Remove ~/.verity/ (global credentials \u2014 reconnect requires re-registration)`,
40488
- apply: () => (0, import_node_fs68.rmSync)(globalVerityDir, { recursive: true, force: true })
40654
+ apply: () => (0, import_node_fs69.rmSync)(globalVerityDir, { recursive: true, force: true })
40489
40655
  });
40490
40656
  }
40491
40657
  if (actions.length === 0) {
@@ -40679,8 +40845,8 @@ function registerTaskCommands(program2) {
40679
40845
  }
40680
40846
 
40681
40847
  // src/commands/reset.ts
40682
- var import_node_fs69 = require("node:fs");
40683
- var import_node_path54 = require("node:path");
40848
+ var import_node_fs70 = require("node:fs");
40849
+ var import_node_path55 = require("node:path");
40684
40850
  function registerResetCommand(program2) {
40685
40851
  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) => {
40686
40852
  const globals = program2.opts();
@@ -40717,11 +40883,11 @@ function registerResetCommand(program2) {
40717
40883
  }
40718
40884
  const cacheDir = projectPath(CACHE_DIR);
40719
40885
  let purged = 0;
40720
- if ((0, import_node_fs69.existsSync)(cacheDir)) {
40721
- for (const entry of (0, import_node_fs69.readdirSync)(cacheDir)) {
40886
+ if ((0, import_node_fs70.existsSync)(cacheDir)) {
40887
+ for (const entry of (0, import_node_fs70.readdirSync)(cacheDir)) {
40722
40888
  if (entry.startsWith("pending-")) {
40723
40889
  try {
40724
- (0, import_node_fs69.unlinkSync)((0, import_node_path54.join)(cacheDir, entry));
40890
+ (0, import_node_fs70.unlinkSync)((0, import_node_path55.join)(cacheDir, entry));
40725
40891
  purged++;
40726
40892
  } catch {
40727
40893
  }
@@ -40736,19 +40902,19 @@ function registerResetCommand(program2) {
40736
40902
  projectPath(`${VERITY_DIR}/.last-analysis`)
40737
40903
  ];
40738
40904
  for (const file of filesToClear) {
40739
- if ((0, import_node_fs69.existsSync)(file)) {
40905
+ if ((0, import_node_fs70.existsSync)(file)) {
40740
40906
  try {
40741
- (0, import_node_fs69.writeFileSync)(file, "");
40907
+ (0, import_node_fs70.writeFileSync)(file, "");
40742
40908
  } catch {
40743
40909
  }
40744
40910
  }
40745
40911
  }
40746
40912
  if (opts.all) {
40747
40913
  const logsDir = projectPath(`${VERITY_DIR}/.logs`);
40748
- if ((0, import_node_fs69.existsSync)(logsDir)) {
40749
- for (const entry of (0, import_node_fs69.readdirSync)(logsDir)) {
40914
+ if ((0, import_node_fs70.existsSync)(logsDir)) {
40915
+ for (const entry of (0, import_node_fs70.readdirSync)(logsDir)) {
40750
40916
  try {
40751
- (0, import_node_fs69.unlinkSync)((0, import_node_path54.join)(logsDir, entry));
40917
+ (0, import_node_fs70.unlinkSync)((0, import_node_path55.join)(logsDir, entry));
40752
40918
  } catch {
40753
40919
  }
40754
40920
  }
@@ -40760,7 +40926,7 @@ function registerResetCommand(program2) {
40760
40926
  }
40761
40927
 
40762
40928
  // src/commands/reflect.ts
40763
- var import_node_fs70 = require("node:fs");
40929
+ var import_node_fs71 = require("node:fs");
40764
40930
 
40765
40931
  // src/lib/reflection-globs.ts
40766
40932
  var MAX_GLOBS = 6;
@@ -40798,7 +40964,7 @@ async function writeNodeToDisk(args2) {
40798
40964
  { treePaths: listTrackedFiles(), recordBaseline: false }
40799
40965
  );
40800
40966
  if (written === 0) return false;
40801
- return (0, import_node_fs70.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
40967
+ return (0, import_node_fs71.existsSync)(projectPath(`${VERITY_DIR}/memory/${args2.filePath}`));
40802
40968
  } catch {
40803
40969
  return false;
40804
40970
  }
@@ -40874,7 +41040,7 @@ function registerReflectCommand(program2) {
40874
41040
  const userInput = input.text;
40875
41041
  if (userInput) {
40876
41042
  const validKinds = ["decision", "gotcha", "pattern", "security", "quality", "intent", "domain", "integration"];
40877
- const kind = validKinds.includes(opts.kind) ? opts.kind : "gotcha";
41043
+ const kind2 = validKinds.includes(opts.kind) ? opts.kind : "gotcha";
40878
41044
  const confirmed = opts.confirmed === true;
40879
41045
  const source2 = confirmed ? "user" : "agent";
40880
41046
  const explicitGlobs = Array.isArray(opts.fileGlobs) ? opts.fileGlobs.map((g) => g.trim()).filter(Boolean) : [];
@@ -40886,7 +41052,7 @@ function registerReflectCommand(program2) {
40886
41052
  serviceUrl,
40887
41053
  token,
40888
41054
  body: {
40889
- kind,
41055
+ kind: kind2,
40890
41056
  title: userInput.slice(0, 200),
40891
41057
  body: userInput,
40892
41058
  domains: [],
@@ -41235,9 +41401,9 @@ function registerRunCommand(program2) {
41235
41401
  }
41236
41402
 
41237
41403
  // src/commands/telemetry.ts
41238
- var import_node_fs71 = require("node:fs");
41404
+ var import_node_fs72 = require("node:fs");
41239
41405
  async function recordTelemetryChoice(choice) {
41240
- if (!(0, import_node_fs71.existsSync)(projectPath(SETUP_STATE_FILE))) return;
41406
+ if (!(0, import_node_fs72.existsSync)(projectPath(SETUP_STATE_FILE))) return;
41241
41407
  try {
41242
41408
  if ((await readSetupState())?.telemetry === choice) return;
41243
41409
  await writeSetupState({ telemetry: choice });
@@ -41314,8 +41480,8 @@ function registerTelemetryCommands(program2) {
41314
41480
  }
41315
41481
 
41316
41482
  // src/commands/prove.ts
41317
- var import_node_fs72 = require("node:fs");
41318
- var import_node_path55 = require("node:path");
41483
+ var import_node_fs73 = require("node:fs");
41484
+ var import_node_path56 = require("node:path");
41319
41485
 
41320
41486
  // src/lib/prove/hint-pool.ts
41321
41487
  var STOP2 = /* @__PURE__ */ new Set([
@@ -41457,7 +41623,7 @@ function registerProveCommand(program2) {
41457
41623
  process.exit(2);
41458
41624
  }
41459
41625
  const limit = Math.max(1, Math.min(50, Number(opts.limit) || 10));
41460
- let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path55.relative)(root, (0, import_node_path55.resolve)(p)) || ".") });
41626
+ let signals = collectRiskSignals(root, { since: opts.since, limit, paths: paths.map((p) => (0, import_node_path56.relative)(root, (0, import_node_path56.resolve)(p)) || ".") });
41461
41627
  if (opts.hint && paths.length === 0) {
41462
41628
  const hit = hintMatches(root, opts.hint);
41463
41629
  if (hit.files.length > 0) {
@@ -41511,7 +41677,7 @@ function registerProveCommand(program2) {
41511
41677
  });
41512
41678
  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) => {
41513
41679
  const root = repoRoot();
41514
- if (!(0, import_node_fs72.existsSync)((0, import_node_path55.join)(root, PROOFS_DIR, "lakefile.toml"))) {
41680
+ if (!(0, import_node_fs73.existsSync)((0, import_node_path56.join)(root, PROOFS_DIR, "lakefile.toml"))) {
41515
41681
  printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
41516
41682
  process.exit(2);
41517
41683
  }
@@ -41535,7 +41701,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
41535
41701
  const reports = [];
41536
41702
  for (const f of files) {
41537
41703
  const report = checkModel(tc, root, f, { timeoutMs: Math.max(1e3, Number(opts.timeout) || 12e4) });
41538
- report.file = (0, import_node_path55.relative)(root, f);
41704
+ report.file = (0, import_node_path56.relative)(root, f);
41539
41705
  reports.push(report);
41540
41706
  try {
41541
41707
  writeResult(root, report);
@@ -41573,7 +41739,7 @@ ${build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).slice(0, 20).j
41573
41739
  printError("Not logged in \u2014 replays run on the Verity service. Run `verity login` first.");
41574
41740
  process.exit(2);
41575
41741
  }
41576
- if (!(0, import_node_fs72.existsSync)((0, import_node_path55.join)(root, PROOFS_DIR, "lakefile.toml"))) {
41742
+ if (!(0, import_node_fs73.existsSync)((0, import_node_path56.join)(root, PROOFS_DIR, "lakefile.toml"))) {
41577
41743
  printError(`No ${PROOFS_DIR}/ project here. Run \`verity prove init\` first.`);
41578
41744
  process.exit(2);
41579
41745
  }
@@ -41604,7 +41770,7 @@ ${report.error ?? ""}`);
41604
41770
  printInfo(opts.property ? `${model} ${opts.property} has no counterexample to replay` : `${model} has no counterexample to replay`);
41605
41771
  return;
41606
41772
  }
41607
- const modelSource = readRegularFileInRoot(root, (0, import_node_path55.relative)(root, file), 512 * 1024);
41773
+ const modelSource = readRegularFileInRoot(root, (0, import_node_path56.relative)(root, file), 512 * 1024);
41608
41774
  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`);
41609
41775
  const outcomes = await mapPool(targets, REPLAY_CONCURRENCY, async (p) => {
41610
41776
  const brief = buildReplayBrief(root, report, p, modelSource.ok ? modelSource.content : "");
@@ -41624,7 +41790,7 @@ ${report.error ?? ""}`);
41624
41790
  });
41625
41791
  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) => {
41626
41792
  const root = repoRoot();
41627
- let files = paths.map((p) => (0, import_node_path55.relative)(root, (0, import_node_path55.resolve)(p)));
41793
+ let files = paths.map((p) => (0, import_node_path56.relative)(root, (0, import_node_path56.resolve)(p)));
41628
41794
  if (files.length === 0) {
41629
41795
  const ahead = runGitSync(root, ["diff", "--name-only", "@{upstream}...HEAD"]);
41630
41796
  const fallback = ahead.ok ? ahead : runGitSync(root, ["diff", "--name-only", "HEAD~1..HEAD"]);
@@ -41634,8 +41800,10 @@ ${report.error ?? ""}`);
41634
41800
  printInfo("No changed files to consider (nothing ahead of upstream). Pass paths explicitly.");
41635
41801
  return;
41636
41802
  }
41637
- const prep = await prepareFormalPhase(root, process.env, await proveAuth(program2) ?? void 0);
41803
+ const auth2 = await proveAuth(program2);
41804
+ const prep = await prepareFormalPhase(root, process.env, auth2 ?? void 0);
41638
41805
  const outcome = prep.ok ? await runFormalPhaseWithin({ root, files, deadlineAt: Date.now() + Math.max(3e4, Number(opts.deadline) || 17e4), deps: prep.deps }).catch((err2) => skippedOutcome("error", String(err2?.message ?? err2).slice(0, 200))) : skippedOutcome(prep.skip, prep.detail);
41806
+ if (auth2) await postPhaseRecord(outcome, { moment: "on-demand", parentRunId: null, pushedFiles: [] }, auth2);
41639
41807
  if (opts.json) {
41640
41808
  printJson(outcome);
41641
41809
  } else {
@@ -41696,7 +41864,7 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
41696
41864
  let revise;
41697
41865
  if (opts.revise) {
41698
41866
  const existing = resolveModelFile(root, opts.revise);
41699
- const src = existing ? readRegularFileInRoot(root, (0, import_node_path55.relative)(root, existing), 64 * 1024) : null;
41867
+ const src = existing ? readRegularFileInRoot(root, (0, import_node_path56.relative)(root, existing), 64 * 1024) : null;
41700
41868
  if (!src || !src.ok || !opts.note) {
41701
41869
  printError("--revise needs an existing model under Models/ and --note - with what the replay showed on stdin");
41702
41870
  process.exit(2);
@@ -41736,8 +41904,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
41736
41904
  });
41737
41905
  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) => {
41738
41906
  const root = repoRoot();
41739
- const rel0 = (0, import_node_path55.relative)(root, (0, import_node_path55.isAbsolute)(file) ? file : (0, import_node_path55.join)(root, file)).replace(/\\/g, "/");
41740
- const rel = rel0.startsWith("..") || (0, import_node_path55.isAbsolute)(rel0) ? null : rel0;
41907
+ const rel0 = (0, import_node_path56.relative)(root, (0, import_node_path56.isAbsolute)(file) ? file : (0, import_node_path56.join)(root, file)).replace(/\\/g, "/");
41908
+ const rel = rel0.startsWith("..") || (0, import_node_path56.isAbsolute)(rel0) ? null : rel0;
41741
41909
  if (!rel) {
41742
41910
  printError(`${file} is not inside this repository`);
41743
41911
  process.exit(2);
@@ -41753,8 +41921,8 @@ ${f.reason ? ` ${terminalText(f.reason, 2e3)}
41753
41921
  });
41754
41922
  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) => {
41755
41923
  const root = repoRoot();
41756
- const rel = (0, import_node_path55.relative)(root, (0, import_node_path55.isAbsolute)(file) ? file : (0, import_node_path55.join)(root, file));
41757
- const digest = rel.startsWith("..") || (0, import_node_path55.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
41924
+ const rel = (0, import_node_path56.relative)(root, (0, import_node_path56.isAbsolute)(file) ? file : (0, import_node_path56.join)(root, file));
41925
+ const digest = rel.startsWith("..") || (0, import_node_path56.isAbsolute)(rel) ? null : sha256InRoot(root, rel);
41758
41926
  if (!digest) {
41759
41927
  printError(`Cannot hash ${file}: it must be a regular file inside this repository (not a symlink)`);
41760
41928
  process.exit(2);
@@ -41788,10 +41956,10 @@ function refreshScaffold(root) {
41788
41956
  }
41789
41957
 
41790
41958
  // src/commands/lean.ts
41791
- var import_node_fs73 = require("node:fs");
41959
+ var import_node_fs74 = require("node:fs");
41792
41960
  var import_node_child_process20 = require("node:child_process");
41793
41961
  var import_node_os12 = require("node:os");
41794
- var import_node_path56 = require("node:path");
41962
+ var import_node_path57 = require("node:path");
41795
41963
  function registerLeanCommand(program2) {
41796
41964
  const lean = program2.command("lean").description("The Lean 4 toolchain formal verification needs (managed download, pinned by this CLI)");
41797
41965
  lean.command("status").option("--json", "Machine-readable output").description("Which toolchain would run, and whether it matches the pinned version").action((opts) => {
@@ -41808,7 +41976,7 @@ function registerLeanCommand(program2) {
41808
41976
  const managed = pinnedVersionDir();
41809
41977
  const matches = version ? version.includes(pin) : false;
41810
41978
  if (opts.json) {
41811
- printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs73.existsSync)((0, import_node_path56.join)(managed, "bin")), asset: leanAssetName() });
41979
+ printJson({ pinned: LEAN_TOOLCHAIN, found: tc?.lake ?? null, version, matches_pin: matches, managed_dir: managed, managed_installed: (0, import_node_fs74.existsSync)((0, import_node_path57.join)(managed, "bin")), asset: leanAssetName() });
41812
41980
  return;
41813
41981
  }
41814
41982
  printInfo(`pinned: ${LEAN_TOOLCHAIN}`);
@@ -41826,7 +41994,7 @@ function registerLeanCommand(program2) {
41826
41994
  process.exit(2);
41827
41995
  }
41828
41996
  const dir = pinnedVersionDir();
41829
- if ((0, import_node_fs73.existsSync)((0, import_node_path56.join)(dir, "bin", "lake")) && !opts.force) {
41997
+ if ((0, import_node_fs74.existsSync)((0, import_node_path57.join)(dir, "bin", "lake")) && !opts.force) {
41830
41998
  printInfo(`already installed at ${dir}`);
41831
41999
  return;
41832
42000
  }
@@ -41862,18 +42030,18 @@ function registerLeanCommand(program2) {
41862
42030
  });
41863
42031
  lean.command("remove").description("Delete the Verity-managed toolchain for the pinned version").action(() => {
41864
42032
  const dir = pinnedVersionDir();
41865
- if (!(0, import_node_fs73.existsSync)(dir)) {
42033
+ if (!(0, import_node_fs74.existsSync)(dir)) {
41866
42034
  printInfo("nothing to remove");
41867
42035
  return;
41868
42036
  }
41869
- (0, import_node_fs73.rmSync)(dir, { recursive: true, force: true });
42037
+ (0, import_node_fs74.rmSync)(dir, { recursive: true, force: true });
41870
42038
  printInfo(`removed ${dir}`);
41871
42039
  });
41872
42040
  }
41873
42041
 
41874
42042
  // src/cli.ts
41875
- program.name("verity").description("CLI for Verity quality gate service").version("0.34.1-experimental.89100b5").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) => {
41876
- installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.1-experimental.89100b5");
42043
+ program.name("verity").description("CLI for Verity quality gate service").version("0.34.1-experimental.c910405").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) => {
42044
+ installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.1-experimental.c910405");
41877
42045
  setUserNamedServiceUrl(program.opts().serviceUrl);
41878
42046
  try {
41879
42047
  await foldLegacyLocalCredential();