@codacy/verity-cli 0.33.3-experimental.46f0715 → 0.33.3-experimental.53cd005
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/verity.js +271 -38
- package/package.json +1 -1
package/bin/verity.js
CHANGED
|
@@ -26771,7 +26771,7 @@ function channelSilence(input) {
|
|
|
26771
26771
|
// src/lib/cli-version.ts
|
|
26772
26772
|
function cliVersion() {
|
|
26773
26773
|
try {
|
|
26774
|
-
return true ? "0.33.3-experimental.
|
|
26774
|
+
return true ? "0.33.3-experimental.53cd005" : "dev";
|
|
26775
26775
|
} catch {
|
|
26776
26776
|
return "dev";
|
|
26777
26777
|
}
|
|
@@ -28487,6 +28487,13 @@ function definitionsIn(root, spec) {
|
|
|
28487
28487
|
} else if (bound && p.type === "pair") {
|
|
28488
28488
|
const key = p.childForFieldName("key");
|
|
28489
28489
|
if (key && (key.type === "property_identifier" || key.type === "identifier")) add(key.text, kind2, p, n, p);
|
|
28490
|
+
} else if (p.type === "arguments" && moduleCall(p.parent)) {
|
|
28491
|
+
const call = p.parent;
|
|
28492
|
+
const route = p.namedChildren[0];
|
|
28493
|
+
const quoted = route && route.id !== n.id && route.type === "string" ? unquote2(route.text) : null;
|
|
28494
|
+
const path = quoted && /^[\w/:.{}*-]{1,60}$/.test(quoted) ? quoted : null;
|
|
28495
|
+
const callee = call.childForFieldName("function").text;
|
|
28496
|
+
add(path ? `${callee} ${path}` : callee, kind2, call.parent, n, call);
|
|
28490
28497
|
}
|
|
28491
28498
|
}
|
|
28492
28499
|
for (const c of n.namedChildren) visit(c);
|
|
@@ -28494,6 +28501,10 @@ function definitionsIn(root, spec) {
|
|
|
28494
28501
|
visit(root);
|
|
28495
28502
|
return out2;
|
|
28496
28503
|
}
|
|
28504
|
+
function moduleCall(call) {
|
|
28505
|
+
const f = call?.type === "call_expression" ? call.childForFieldName("function") : null;
|
|
28506
|
+
return !!f && (f.type === "identifier" || f.type === "member_expression") && f.text.length <= 40 && !f.text.includes("\n") && call.parent?.type === "expression_statement" && call.parent.parent?.type === "program";
|
|
28507
|
+
}
|
|
28497
28508
|
function unquote2(s) {
|
|
28498
28509
|
const body2 = s.replace(/^[rRbBuUfF]{0,2}(?=["'`])/, "");
|
|
28499
28510
|
const q3 = body2.startsWith('"""') || body2.startsWith("'''");
|
|
@@ -28562,6 +28573,25 @@ function factsOf(def, spec, defs, path) {
|
|
|
28562
28573
|
const loops = [];
|
|
28563
28574
|
const tries = [];
|
|
28564
28575
|
const locks = [];
|
|
28576
|
+
const bindings = {};
|
|
28577
|
+
const bind = (n) => {
|
|
28578
|
+
let name2 = null;
|
|
28579
|
+
let value = null;
|
|
28580
|
+
if (n.type === "variable_declarator") {
|
|
28581
|
+
name2 = n.childForFieldName("name");
|
|
28582
|
+
value = n.childForFieldName("value");
|
|
28583
|
+
} else if (n.type === "assignment" && spec.id === "python") {
|
|
28584
|
+
name2 = n.childForFieldName("left");
|
|
28585
|
+
value = n.childForFieldName("right");
|
|
28586
|
+
} else if (n.type === "short_var_declaration") {
|
|
28587
|
+
const l = n.childForFieldName("left"), r = n.childForFieldName("right");
|
|
28588
|
+
if (l?.namedChildren.length === 1 && r?.namedChildren.length === 1) {
|
|
28589
|
+
name2 = l.namedChildren[0];
|
|
28590
|
+
value = r.namedChildren[0];
|
|
28591
|
+
}
|
|
28592
|
+
}
|
|
28593
|
+
if (name2?.type === "identifier" && value && Object.keys(bindings).length < 40 && !(name2.text in bindings)) bindings[name2.text] = cap(value.text, TEXT_CAP);
|
|
28594
|
+
};
|
|
28565
28595
|
const throwsIn = (n) => {
|
|
28566
28596
|
if (spec.throws.has(n.type)) return true;
|
|
28567
28597
|
if (defs.has(n.id) || spec.functionValues.has(n.type)) return false;
|
|
@@ -28571,6 +28601,7 @@ function factsOf(def, spec, defs, path) {
|
|
|
28571
28601
|
const anonymousMember = n.parent?.type === "class_body" && n.parent.parent?.type === "object_creation_expression";
|
|
28572
28602
|
if (n.id !== def.fn.id && !anonymousMember && (defs.has(n.id) || spec.classes.has(n.type) || spec.definitions[n.type])) return;
|
|
28573
28603
|
const t = n.type;
|
|
28604
|
+
bind(n);
|
|
28574
28605
|
const down = (c, next = ctx) => walk2(c, next);
|
|
28575
28606
|
if (spec.calls.has(t)) {
|
|
28576
28607
|
const { receiver, name: name2, args: args2 } = callParts(n, spec);
|
|
@@ -28640,7 +28671,8 @@ function factsOf(def, spec, defs, path) {
|
|
|
28640
28671
|
loops,
|
|
28641
28672
|
tries,
|
|
28642
28673
|
locks: [...new Set(locks)].sort((a, b) => a - b),
|
|
28643
|
-
hasError: def.last.hasError
|
|
28674
|
+
hasError: def.last.hasError,
|
|
28675
|
+
...Object.keys(bindings).length ? { bindings } : {}
|
|
28644
28676
|
};
|
|
28645
28677
|
}
|
|
28646
28678
|
function endOf(def, spec) {
|
|
@@ -28676,6 +28708,54 @@ function outlineOf(rt, path, content, deadlineAt) {
|
|
|
28676
28708
|
tree.delete();
|
|
28677
28709
|
}
|
|
28678
28710
|
}
|
|
28711
|
+
var BLOCKS = /* @__PURE__ */ new Set(["statement_block", "block", "switch_body"]);
|
|
28712
|
+
function regionOf(rt, path, content, fn, changed, maxLines, deadlineAt) {
|
|
28713
|
+
const started = Date.now();
|
|
28714
|
+
const lang = languageOf2(path);
|
|
28715
|
+
if (!lang) return { source: "fallback", reason: "unsupported-language", elapsedMs: 0 };
|
|
28716
|
+
const inside2 = changed.filter((r) => r.from <= fn.end.line && fn.start.line <= r.to);
|
|
28717
|
+
if (inside2.length === 0) return { source: "fallback", reason: "not-in-function", elapsedMs: 0 };
|
|
28718
|
+
const from = Math.max(fn.start.line, Math.min(...inside2.map((r) => r.from)));
|
|
28719
|
+
const to = Math.min(fn.end.line, Math.max(...inside2.map((r) => r.to)));
|
|
28720
|
+
if (to - from + 1 > maxLines) return { source: "fallback", reason: "change-too-wide", elapsedMs: 0 };
|
|
28721
|
+
if (Buffer.byteLength(content) > MAX_PARSE_BYTES) return { source: "fallback", reason: "too-large", elapsedMs: 0 };
|
|
28722
|
+
const tree = parseWithin(rt, lang, content, deadlineAt);
|
|
28723
|
+
if (!tree) return { source: "fallback", reason: "deadline", elapsedMs: Date.now() - started };
|
|
28724
|
+
try {
|
|
28725
|
+
const lines = content.split("\n");
|
|
28726
|
+
let n = tree.rootNode.descendantForPosition({ row: from - 1, column: 0 }, { row: to - 1, column: (lines[to - 1] ?? "").length });
|
|
28727
|
+
let block = null;
|
|
28728
|
+
for (; n && line(n) >= fn.start.line; n = n.parent) {
|
|
28729
|
+
if (BLOCKS.has(n.type) && n.endPosition.row + 1 - line(n) + 1 > maxLines) {
|
|
28730
|
+
block = n;
|
|
28731
|
+
break;
|
|
28732
|
+
}
|
|
28733
|
+
}
|
|
28734
|
+
if (!block) return { source: "fallback", reason: "no-block", elapsedMs: Date.now() - started };
|
|
28735
|
+
const stmts = block.namedChildren.filter((c) => c.type !== "comment");
|
|
28736
|
+
const end = (c) => c.endPosition.row + 1;
|
|
28737
|
+
let lo = stmts.findIndex((c) => end(c) >= from);
|
|
28738
|
+
let hi = stmts.length - 1 - [...stmts].reverse().findIndex((c) => line(c) <= to);
|
|
28739
|
+
if (lo < 0 || hi < lo) return { source: "fallback", reason: "no-block", elapsedMs: Date.now() - started };
|
|
28740
|
+
const fits = (a, b) => end(stmts[b]) - line(stmts[a]) + 1 <= maxLines;
|
|
28741
|
+
if (!fits(lo, hi)) return { source: "fallback", reason: "change-too-wide", elapsedMs: Date.now() - started };
|
|
28742
|
+
for (let grew = true; grew; ) {
|
|
28743
|
+
grew = false;
|
|
28744
|
+
if (lo > 0 && fits(lo - 1, hi)) {
|
|
28745
|
+
lo--;
|
|
28746
|
+
grew = true;
|
|
28747
|
+
}
|
|
28748
|
+
if (hi < stmts.length - 1 && fits(lo, hi + 1)) {
|
|
28749
|
+
hi++;
|
|
28750
|
+
grew = true;
|
|
28751
|
+
}
|
|
28752
|
+
}
|
|
28753
|
+
const holder = block.parent && block.parent.type !== "program" ? block.parent : block;
|
|
28754
|
+
return { source: "tree-sitter", value: { from: line(stmts[lo]), to: end(stmts[hi]), within: cap(holder.text.split("\n")[0].trim(), 60) }, elapsedMs: Date.now() - started };
|
|
28755
|
+
} finally {
|
|
28756
|
+
tree.delete();
|
|
28757
|
+
}
|
|
28758
|
+
}
|
|
28679
28759
|
|
|
28680
28760
|
// src/lib/code/effects.ts
|
|
28681
28761
|
function literalName(literal) {
|
|
@@ -28696,7 +28776,18 @@ function argResource(kind, arg) {
|
|
|
28696
28776
|
const n = literalName(arg.literal);
|
|
28697
28777
|
return n ? { kind, name: n.name, confidence: n.confidence } : { kind, name: null, confidence: "unknown" };
|
|
28698
28778
|
}
|
|
28699
|
-
|
|
28779
|
+
if (SIMPLE_EXPRESSION.test(arg.text) && STABLE_EXPRESSION(arg.text)) return { kind, name: arg.text, confidence: "expression" };
|
|
28780
|
+
const keyed = keyedCall(arg.text);
|
|
28781
|
+
return keyed ? { kind, name: keyed, confidence: "expression" } : { kind, name: null, confidence: "unknown" };
|
|
28782
|
+
}
|
|
28783
|
+
function keyedCall(text) {
|
|
28784
|
+
const t = text.trim();
|
|
28785
|
+
const open = t.indexOf("(");
|
|
28786
|
+
if (open <= 0 || !t.endsWith(")")) return null;
|
|
28787
|
+
const callee = t.slice(0, open);
|
|
28788
|
+
if (!/^[A-Za-z_$][\w$.]*$/.test(callee)) return null;
|
|
28789
|
+
const constant = /\b[A-Z][A-Z0-9_]{2,}\b/.exec(t.slice(open + 1, -1));
|
|
28790
|
+
return constant ? `${callee}(${constant[0]})` : null;
|
|
28700
28791
|
}
|
|
28701
28792
|
function snake(s) {
|
|
28702
28793
|
return s.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^A-Za-z0-9]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
@@ -28932,10 +29023,18 @@ function memory(c, fn, state) {
|
|
|
28932
29023
|
const op = MEMORY_WRITE.has(c.name) ? "write" : MEMORY_READ.has(c.name) ? "read" : null;
|
|
28933
29024
|
return op ? { op, resource: { kind: "memory", name: `${fn.path}#${c.receiver}`, confidence: "literal" }, rule: "memory.module" } : null;
|
|
28934
29025
|
}
|
|
29026
|
+
function resolveLocal(a, bindings) {
|
|
29027
|
+
if (a.literal !== null || !/^[A-Za-z_$][\w$]*$/.test(a.text)) return a;
|
|
29028
|
+
const init2 = bindings[a.text];
|
|
29029
|
+
if (!init2) return a;
|
|
29030
|
+
const quoted = /^(['"`])([^'"`$]*)\1$/.exec(init2.trim());
|
|
29031
|
+
return { ...a, text: init2, literal: quoted ? quoted[2] : null };
|
|
29032
|
+
}
|
|
28935
29033
|
function directEffects(fn, lang, state) {
|
|
28936
29034
|
const out2 = [];
|
|
28937
29035
|
const seen = /* @__PURE__ */ new Set();
|
|
28938
|
-
for (const
|
|
29036
|
+
for (const raw of fn.calls) {
|
|
29037
|
+
const c = fn.bindings ? { ...raw, args: raw.args.map((a) => resolveLocal(a, fn.bindings)) } : raw;
|
|
28939
29038
|
let m = memory(c, fn, state);
|
|
28940
29039
|
if (!m) {
|
|
28941
29040
|
for (const rule of RULES) if (m = rule(c, fn, lang)) break;
|
|
@@ -28993,7 +29092,11 @@ function sameResource(a, b) {
|
|
|
28993
29092
|
function searchTerms(r) {
|
|
28994
29093
|
if (!r.name || r.confidence === "unknown") return [];
|
|
28995
29094
|
if (r.kind === "service" || r.kind === "memory") return [];
|
|
28996
|
-
if (r.confidence === "expression")
|
|
29095
|
+
if (r.confidence === "expression") {
|
|
29096
|
+
const keyed = /^[A-Za-z_$][\w$.]*\(([A-Z][A-Z0-9_]+)\)$/.exec(r.name);
|
|
29097
|
+
if (keyed) return [keyed[1]];
|
|
29098
|
+
return [r.name.endsWith("()") ? r.name.slice(0, -1) : r.name];
|
|
29099
|
+
}
|
|
28997
29100
|
if (r.kind === "table" && r.confidence === "inferred") {
|
|
28998
29101
|
const one = tableKey(r.name);
|
|
28999
29102
|
const plural = (w) => /[^aeiou]y$/.test(w) ? `${w.slice(0, -1)}ies` : /(?:s|x|ch|sh)$/.test(w) ? `${w}es` : `${w}s`;
|
|
@@ -29978,6 +30081,13 @@ function makeCodeMap(rt) {
|
|
|
29978
30081
|
return { source: "fallback", reason: `error: ${String(e?.message ?? e).slice(0, 120)}`, elapsedMs: Date.now() - started };
|
|
29979
30082
|
}
|
|
29980
30083
|
},
|
|
30084
|
+
regionAt(path, content, target, changed, maxLines, deadlineAt = Date.now() + DEFAULT_PARSE_MS) {
|
|
30085
|
+
try {
|
|
30086
|
+
return regionOf(rt, path, content, target, changed, maxLines, deadlineAt);
|
|
30087
|
+
} catch (e) {
|
|
30088
|
+
return { source: "fallback", reason: `error: ${String(e?.message ?? e).slice(0, 120)}`, elapsedMs: 0 };
|
|
30089
|
+
}
|
|
30090
|
+
},
|
|
29981
30091
|
functionContaining(path, content, line2, deadlineAt) {
|
|
29982
30092
|
return pick(outline(path, content, deadlineAt), (fns) => fns.filter((f) => f.start.line <= line2 && line2 <= f.end.line).sort((a, b) => a.end.line - a.start.line - (b.end.line - b.start.line))[0], "no-enclosing-function");
|
|
29983
30093
|
}
|
|
@@ -33206,6 +33316,10 @@ var STRUCTURAL_CATALOGUE = [
|
|
|
33206
33316
|
"check_then_act_is_atomic",
|
|
33207
33317
|
"no_double_effect"
|
|
33208
33318
|
];
|
|
33319
|
+
function combineScore(c) {
|
|
33320
|
+
const f = (x) => Math.max(0.01, Math.min(1, x));
|
|
33321
|
+
return Math.round(Math.pow(f(c.hazard), 0.45) * Math.pow(f(c.critical), 0.35) * Math.pow(f(c.error_prone), 0.2) * 1e3) / 1e3;
|
|
33322
|
+
}
|
|
33209
33323
|
function deterministicOrder(candidates2) {
|
|
33210
33324
|
return candidates2.map((c, i2) => ({ ...c, rank: i2 + 1 }));
|
|
33211
33325
|
}
|
|
@@ -33215,37 +33329,51 @@ var deterministicRanker = {
|
|
|
33215
33329
|
return { ok: true, ranker: "deterministic", ranked: deterministicOrder(candidates2) };
|
|
33216
33330
|
}
|
|
33217
33331
|
};
|
|
33218
|
-
function excerpt(root, file, bytes, readSource, changed, codeMap) {
|
|
33332
|
+
function excerpt(root, file, bytes, readSource, changed, codeMap, codeSource) {
|
|
33219
33333
|
const read2 = readSource ? readSource(file, EXCERPT_SOURCE_CAP_BYTES) : readRegularFileInRoot(root, file, EXCERPT_SOURCE_CAP_BYTES);
|
|
33220
33334
|
if (!read2.ok) return "";
|
|
33221
33335
|
if (changed && changed.length > 0) {
|
|
33222
|
-
const touched = codeMap ? touchedFunctions(codeMap, file, read2.content, changed) : "";
|
|
33336
|
+
const touched = codeMap ? touchedFunctions(codeMap, file, read2.content, changed, { source: codeSource, fixSubjects: (from, to) => fixSubjects(root, file, from, to) }) : "";
|
|
33223
33337
|
return touched + changedExcerpt(read2.content, changed, bytes - touched.length);
|
|
33224
33338
|
}
|
|
33225
33339
|
return read2.content.length > bytes ? read2.content.slice(0, bytes) + "\n\u2026 (truncated)" : read2.content;
|
|
33226
33340
|
}
|
|
33227
|
-
function touchedFunctions(codeMap, file, content, changed) {
|
|
33341
|
+
function touchedFunctions(codeMap, file, content, changed, evidence2 = {}) {
|
|
33228
33342
|
const r = codeMap.outline(file, content);
|
|
33229
33343
|
if (r.source !== "tree-sitter") return "";
|
|
33230
33344
|
const size = (f) => f.end.line - f.start.line;
|
|
33231
33345
|
const names2 = [];
|
|
33346
|
+
const fixes = [];
|
|
33232
33347
|
for (const range of changed) {
|
|
33233
33348
|
const around = r.value.filter((f) => f.start.line <= range.to && range.from <= f.end.line).sort((a, b) => size(a) - size(b));
|
|
33234
33349
|
const hit = around[0];
|
|
33235
33350
|
const outer = hit ? r.value.filter((f) => f !== hit && f.start.line <= hit.start.line && hit.end.line <= f.end.line).sort((a, b) => size(a) - size(b))[0] : void 0;
|
|
33236
|
-
const label2 = hit ? `${hit.qualified} (lines ${hit.start.line}\u2013${hit.end.line}${outer ? `, inside ${outer.qualified}` : ""}${hit ? sharedState(codeMap, file, content, hit) : ""})` : null;
|
|
33237
|
-
if (label2 && !names2.includes(label2))
|
|
33351
|
+
const label2 = hit ? `${hit.qualified} (lines ${hit.start.line}\u2013${hit.end.line}${outer ? `, inside ${outer.qualified}` : ""}${hit ? sharedState(codeMap, file, content, hit, evidence2.source) : ""})` : null;
|
|
33352
|
+
if (label2 && !names2.includes(label2)) {
|
|
33353
|
+
names2.push(label2);
|
|
33354
|
+
for (const s of hit && evidence2.fixSubjects ? evidence2.fixSubjects(hit.start.line, hit.end.line) : []) if (!fixes.includes(s)) fixes.push(s);
|
|
33355
|
+
}
|
|
33238
33356
|
}
|
|
33239
|
-
|
|
33357
|
+
if (names2.length === 0) return "";
|
|
33358
|
+
const history = fixes.length > 0 ? `Fix commits that changed these lines: ${fixes.slice(0, 4).map((s) => `"${s}"`).join("; ")}
|
|
33240
33359
|
` : "";
|
|
33360
|
+
return `Functions this push changed: ${names2.slice(0, 8).join(", ")}
|
|
33361
|
+
${history}`;
|
|
33241
33362
|
}
|
|
33242
|
-
function
|
|
33243
|
-
const r =
|
|
33363
|
+
function fixSubjects(root, file, from, to) {
|
|
33364
|
+
const r = runGitSync(root, ["log", "-n", "40", "--no-patch", "--format=%s", "-L", `${from},${to}:${file}`], { timeoutMs: 2e3, maxBuffer: 1 << 20 });
|
|
33365
|
+
if (!r.ok) return [];
|
|
33366
|
+
return [...new Set(r.stdout.split("\n").map((s) => s.trim()).filter((s) => s && FIX_SUBJECT.test(s)))].slice(0, 4).map((s) => s.slice(0, 120));
|
|
33367
|
+
}
|
|
33368
|
+
function sharedState(codeMap, file, content, fn, source2) {
|
|
33369
|
+
const r = codeMap.access(file, content, fn, source2 ? { source: source2, deadlineAt: Date.now() + 800 } : void 0);
|
|
33244
33370
|
if (r.source !== "tree-sitter") return "";
|
|
33245
33371
|
const notes = [];
|
|
33246
|
-
const others = r.value.accessors.slice(0, 2).map((a) => a.fn.qualified);
|
|
33372
|
+
const others = r.value.accessors.slice(0, 2).map((a) => a.fn.path === file ? a.fn.qualified : `${a.fn.qualified} in ${a.fn.path}`);
|
|
33247
33373
|
if (others.length) notes.push(`shares state with ${others.join(" and ")}`);
|
|
33248
33374
|
if (r.value.signals.checkThenAct.length) notes.push(`reads then writes ${r.value.signals.checkThenAct[0].split(" ")[0]}`);
|
|
33375
|
+
const kinds = [...new Set(r.value.effects.filter((e) => e.resource.name).map((e) => `${e.op} ${e.resource.kind}:${e.resource.name}`))].slice(0, 4);
|
|
33376
|
+
if (kinds.length) notes.push(`effects: ${kinds.join(", ")}`);
|
|
33249
33377
|
return notes.length ? `; ${notes.join("; ")}` : "";
|
|
33250
33378
|
}
|
|
33251
33379
|
function changedExcerpt(content, changed, bytes, context = 30) {
|
|
@@ -33285,25 +33413,27 @@ var LUNA_SCHEMA = {
|
|
|
33285
33413
|
additionalProperties: false,
|
|
33286
33414
|
properties: {
|
|
33287
33415
|
file: { type: "string" },
|
|
33288
|
-
|
|
33416
|
+
critical: { type: "number" },
|
|
33417
|
+
hazard: { type: "number" },
|
|
33418
|
+
error_prone: { type: "number" },
|
|
33289
33419
|
reasons: { type: "array", items: { type: "string" } },
|
|
33290
33420
|
symbol: { type: "string" },
|
|
33291
33421
|
properties: { type: "array", items: { type: "string", enum: [...STRUCTURAL_CATALOGUE] } }
|
|
33292
33422
|
},
|
|
33293
|
-
required: ["file", "
|
|
33423
|
+
required: ["file", "critical", "hazard", "error_prone", "reasons", "symbol", "properties"]
|
|
33294
33424
|
}
|
|
33295
33425
|
}
|
|
33296
33426
|
},
|
|
33297
33427
|
required: ["items"]
|
|
33298
33428
|
};
|
|
33299
33429
|
var LUNA_INSTRUCTIONS = `You decide whether a push deserves a FORMAL MODEL: a Lean 4 transition system explored over every interleaving, retry, failure and crash, then replayed on the real code. It costs the developer about a minute of their push, and blocks it only on a bug reproduced on the real code. It is a scalpel: most pushes deserve NO model.
|
|
33300
|
-
For each file you get its git-history signals (commits, fix commits), risk keyword counts and an excerpt.
|
|
33301
|
-
-
|
|
33302
|
-
-
|
|
33303
|
-
-
|
|
33304
|
-
|
|
33305
|
-
Name the single symbol (function) most worth modelling, and the applicable properties from the catalogue only. Reasons: at most 3, each a short concrete sentence about THIS code
|
|
33306
|
-
When a file lists \`changed\` lines, this is a review of a push: the excerpt is numbered around the changes (changed lines starred). Name the function that CONTAINS a changed line, and score THAT FUNCTION'S CURRENT CODE as a whole, never the edit itself. A one-line change (a log line, a rename) to a function that meets all three still scores high: a latent bug in it is exactly what this is for. A large change to a function that misses one still scores low. An excerpt may open with "Functions this push changed:", from a parser: when it says a changed function "shares state with" another, judge the PAIR \u2014 a function that alone is a single write or an invalidation is error-prone when the other reads and repopulates, or also writes, the same state (a cache invalidated here and refilled there, two writers of one ledger or file); score it as that pair would be scored, but name ONE symbol \u2014 the changed function, never both ("a/b", "a and b" name nothing). "reads then writes" names a check-then-act the parser saw with no transaction or lock around it.`;
|
|
33430
|
+
For each file you get its git-history signals (commits, fix commits), risk keyword counts and an excerpt. Pick the ONE function here most worth a model, and rate it 0-1 on each of three criteria, separately \u2014 the service combines them (a model is worth the minute only when all three hold):
|
|
33431
|
+
- critical: a mistake costs money, data, access or a stuck workflow (payments, balances, stock, ledgers, auth and permissions, jobs and queues, sync, status machines, anything that must happen exactly once or at most once \u2014 duplicated records, nodes, charges, emails or seeds count, and so does state that two processes can leave inconsistent);
|
|
33432
|
+
- hazard: something a model can explore \u2014 two or more effects that can interleave (read then write, check then act), a retry or a redelivery, an external call whose failure path matters, a lock, a lease, a cache, a cursor, a crash window between writes \u2014 or pure arithmetic on money or counts;
|
|
33433
|
+
- error_prone: fix commits in its history (the strongest evidence: this code has already been wrong), high churn, several branches or error paths, a concurrency primitive \u2014 a hazard nobody sees by reading the function once.
|
|
33434
|
+
Rate a criterion LOW (below 0.5) when it is missing: rendering, formatting, configuration, command registration, wiring, types, a single read, a single write with nothing before it, logging, or a function whose correctness is plain from reading it. A crash window alone (an external call, then a local write, where a re-run repairs the state and nothing is lost for good) is not enough for a high score. A model of a function longer than about 150 lines abstracts too much to find anything: name the smaller function inside it that holds the hazard, or score lower.
|
|
33435
|
+
Name the single symbol (function) most worth modelling, and the applicable properties from the catalogue only. Reasons: at most 3, each a short concrete sentence about THIS code \u2014 its hazard, what a mistake costs, its history \u2014 never about the change. Return every file you were given, exactly once.
|
|
33436
|
+
When a file lists \`changed\` lines, this is a review of a push: the excerpt is numbered around the changes (changed lines starred). Name the function that CONTAINS a changed line, and score THAT FUNCTION'S CURRENT CODE as a whole, never the edit itself. A one-line change (a log line, a rename) to a function that meets all three still scores high: a latent bug in it is exactly what this is for. A large change to a function that misses one still scores low. An excerpt may open with "Functions this push changed:", from a parser: when it says a changed function "shares state with" another, judge the PAIR \u2014 a function that alone is a single write or an invalidation is error-prone when the other reads and repopulates, or also writes, the same state (a cache invalidated here and refilled there, two writers of one ledger or file); score it as that pair would be scored, but name ONE symbol \u2014 the changed function, never both ("a/b", "a and b" name nothing). "reads then writes" names a check-then-act the parser saw with no transaction or lock around it. "effects" lists the state the function reads and writes (a table, a file, a cache key, a queue, an outside service). "Fix commits that changed these lines" quotes the history of THIS code: each one is evidence it has been wrong before (error_prone), and its subject often says what a mistake cost (critical) \u2014 a subject about duplicates, lost writes, double charges or stuck jobs is a costly mistake that already happened.`;
|
|
33307
33437
|
var lunaRanker = {
|
|
33308
33438
|
name: "luna",
|
|
33309
33439
|
async rank(candidates2, ctx) {
|
|
@@ -33358,7 +33488,12 @@ var lunaRanker = {
|
|
|
33358
33488
|
const text = (data.output ?? []).flatMap((o) => o.content ?? []).find((c) => c.type === "output_text")?.text;
|
|
33359
33489
|
if (!text) return { ok: false, ranker: "luna", error: "no output_text in response", ranked: fallback };
|
|
33360
33490
|
const parsed = JSON.parse(text);
|
|
33361
|
-
|
|
33491
|
+
const items = parsed.items.map((i2) => {
|
|
33492
|
+
const legacy = i2.critical === void 0 && i2.hazard === void 0 && i2.error_prone === void 0;
|
|
33493
|
+
const criteria = legacy ? { critical: Number(i2.score) || 0, hazard: Number(i2.score) || 0, error_prone: Number(i2.score) || 0 } : { critical: Number(i2.critical) || 0, hazard: Number(i2.hazard) || 0, error_prone: Number(i2.error_prone) || 0 };
|
|
33494
|
+
return { ...i2, criteria, score: legacy ? Number(i2.score) || 0 : combineScore(criteria) };
|
|
33495
|
+
});
|
|
33496
|
+
return { ok: true, ranker: "luna", ranked: applyAnnotations(candidates2, items) };
|
|
33362
33497
|
} catch (err2) {
|
|
33363
33498
|
const msg = err2.name === "AbortError" ? "timed out" : err2.message;
|
|
33364
33499
|
return { ok: false, ranker: "luna", error: msg, ranked: fallback };
|
|
@@ -33382,7 +33517,7 @@ async function rankViaServer(candidates2, ctx, auth2) {
|
|
|
33382
33517
|
fix_commits: c.fixCommits,
|
|
33383
33518
|
risk: c.risk,
|
|
33384
33519
|
lines: c.lines,
|
|
33385
|
-
excerpt: excerpt(ctx.root, c.file, excerptBytes, ctx.readSource, ctx.changedLines?.get(c.file), ctx.codeMap),
|
|
33520
|
+
excerpt: excerpt(ctx.root, c.file, excerptBytes, ctx.readSource, ctx.changedLines?.get(c.file), ctx.codeMap, ctx.codeSource),
|
|
33386
33521
|
...ctx.changedLines?.get(c.file)?.length ? { changed_lines: ctx.changedLines.get(c.file).slice(0, 50) } : {}
|
|
33387
33522
|
})),
|
|
33388
33523
|
...ctx.hint ? { hint: ctx.hint.slice(0, 500) } : {}
|
|
@@ -33402,6 +33537,11 @@ function applyAnnotations(candidates2, items) {
|
|
|
33402
33537
|
const properties = (a.properties ?? []).filter((p) => STRUCTURAL_CATALOGUE.includes(p));
|
|
33403
33538
|
const score = Math.max(0, Math.min(1, Number(a.score) || 0));
|
|
33404
33539
|
const ai = { score, reasons: (a.reasons ?? []).slice(0, 3), properties };
|
|
33540
|
+
if (a.criteria && typeof a.criteria === "object") {
|
|
33541
|
+
const u = (v) => Math.max(0, Math.min(1, Number(v) || 0));
|
|
33542
|
+
ai.criteria = { critical: u(a.criteria.critical), hazard: u(a.criteria.hazard), error_prone: u(a.criteria.error_prone) };
|
|
33543
|
+
}
|
|
33544
|
+
if (a.reasked) ai.reasked = true;
|
|
33405
33545
|
if (a.symbol && a.symbol.trim()) ai.symbol = a.symbol.trim();
|
|
33406
33546
|
return { ...c, rank: 0, ai };
|
|
33407
33547
|
});
|
|
@@ -35728,6 +35868,7 @@ function contextHazard(ctx) {
|
|
|
35728
35868
|
var AUTO_MODELS_DIR = `${MODELS_DIR}/.auto`;
|
|
35729
35869
|
var DEFAULT_MIN_SCORE = 0.7;
|
|
35730
35870
|
var MAX_MODEL_FUNCTION_LINES = 300;
|
|
35871
|
+
var REGION_MIN_SCORE = 0.8;
|
|
35731
35872
|
var REPLAYABLE = /\.(?:ts|tsx|mts|cts|js|jsx|mjs|cjs|py)$/;
|
|
35732
35873
|
var LARGE_PUSH_FILES = 25;
|
|
35733
35874
|
var DAILY_MODEL_CAP = 5;
|
|
@@ -35824,7 +35965,7 @@ function sha256Of(content) {
|
|
|
35824
35965
|
function defaultDeps(opts) {
|
|
35825
35966
|
const env = opts.env ?? process.env;
|
|
35826
35967
|
return {
|
|
35827
|
-
rank: (candidates2, root, changedLines) => lunaRanker.rank(candidates2, { root, auth: opts.auth, env, fetchImpl: opts.fetchImpl, readSource: opts.readSource, codeMap: opts.codeMap, ...changedLines ? { changedLines } : {} }),
|
|
35968
|
+
rank: (candidates2, root, changedLines) => lunaRanker.rank(candidates2, { root, auth: opts.auth, env, fetchImpl: opts.fetchImpl, readSource: opts.readSource, codeMap: opts.codeMap, ...opts.codeSource ? { codeSource: opts.codeSource } : {}, ...changedLines ? { changedLines } : {} }),
|
|
35828
35969
|
// The push phase writes with the FAST tier; `prove generate` asks for DEEP (decision 56).
|
|
35829
35970
|
generate: (target, previous, budgetMs) => generateModel(target, { auth: opts.auth, apiKey: opts.apiKey, env, fetchImpl: opts.fetchImpl, previous, tier: opts.tier ?? "fast", ...budgetMs ? { budgetMs } : {} }),
|
|
35830
35971
|
check: (root, modelFile) => checkModelAsync(opts.toolchain, root, modelFile),
|
|
@@ -35841,8 +35982,10 @@ async function runFormalPhase(input) {
|
|
|
35841
35982
|
const progress = input.progress ?? {};
|
|
35842
35983
|
progress.usage = usage;
|
|
35843
35984
|
progress.step = "select";
|
|
35985
|
+
let candidates2;
|
|
35844
35986
|
const done = (partial) => ({
|
|
35845
35987
|
findings: [],
|
|
35988
|
+
...candidates2 ? { candidates: candidates2 } : {},
|
|
35846
35989
|
...partial,
|
|
35847
35990
|
usage,
|
|
35848
35991
|
durationMs: deps.now() - started
|
|
@@ -35907,17 +36050,42 @@ async function runFormalPhase(input) {
|
|
|
35907
36050
|
const signals = collectRiskSignals(root, { paths: files, limit: 10 });
|
|
35908
36051
|
if (signals.length === 0) return done({ status: "skipped", skip: "no-source-files" });
|
|
35909
36052
|
const largePush = signals.length >= LARGE_PUSH_FILES || files.length >= LARGE_PUSH_FILES * 2;
|
|
35910
|
-
const
|
|
36053
|
+
const mapEligible = (file) => {
|
|
36054
|
+
const changed = input.changedLines?.get(file);
|
|
36055
|
+
if (!deps.codeMap || largePush || !changed?.length) return false;
|
|
36056
|
+
const read2 = readSrc(file, 96 * 1024);
|
|
36057
|
+
if (!read2.ok) return false;
|
|
36058
|
+
const outline = deps.codeMap.outline(file, read2.content);
|
|
36059
|
+
if (outline.source !== "tree-sitter") return false;
|
|
36060
|
+
return outline.value.some((f) => changed.some((r) => f.start.line <= r.to && r.from <= f.end.line) && (() => {
|
|
36061
|
+
const a = deps.codeMap.access(file, read2.content, f);
|
|
36062
|
+
return a.source === "tree-sitter" && a.value.effects.length >= 2;
|
|
36063
|
+
})());
|
|
36064
|
+
};
|
|
36065
|
+
const eligible = signals.filter((s) => isEligible(s, largePush).ok || mapEligible(s.file)).slice(0, 5);
|
|
35911
36066
|
if (eligible.length === 0) {
|
|
35912
36067
|
const best = signals[0];
|
|
35913
36068
|
return done({ status: "skipped", skip: "not-eligible", detail: `${best.file}: ${isEligible(best, largePush).why}` });
|
|
35914
36069
|
}
|
|
35915
36070
|
const ranked = await deps.rank(eligible, root, input.changedLines);
|
|
35916
36071
|
if (ranked.ok) spend(ranked);
|
|
36072
|
+
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)) }));
|
|
35917
36073
|
if (cancelled()) return done({ status: "skipped", skip: "deadline", detail: "cut off after ranking" });
|
|
35918
36074
|
const minScore = input.minScore ?? DEFAULT_MIN_SCORE;
|
|
35919
|
-
|
|
35920
|
-
|
|
36075
|
+
let qualified = ranked.ranked.filter((c) => c.ai && c.ai.score >= minScore);
|
|
36076
|
+
let floor = false;
|
|
36077
|
+
if (qualified.length === 0 && ranked.ok && deps.codeMap && input.changedLines) {
|
|
36078
|
+
const pick = floorCandidate(ranked.ranked, input.changedLines, deps, readSrc, root);
|
|
36079
|
+
if (pick) {
|
|
36080
|
+
qualified = [pick];
|
|
36081
|
+
floor = true;
|
|
36082
|
+
}
|
|
36083
|
+
}
|
|
36084
|
+
if (qualified.length === 0) {
|
|
36085
|
+
const best = ranked.ranked[0];
|
|
36086
|
+
const why2 = best?.ai ? `${best.ai.symbol ?? best.file}${best.ai.criteria ? ` (critical ${best.ai.criteria.critical}, hazard ${best.ai.criteria.hazard}, error-prone ${best.ai.criteria.error_prone})` : ""}${best.ai.reasons[0] ? ` \u2014 ${best.ai.reasons[0].slice(0, 160)}` : ""}` : "";
|
|
36087
|
+
return done({ status: "skipped", skip: "no-candidate", detail: ranked.ok ? `best score ${Math.round((best?.ai?.score ?? 0) * 100)}% of ${eligible.length} eligible${why2 ? `: ${why2}` : ""}` : `rank unavailable: ${ranked.error ?? ""}` });
|
|
36088
|
+
}
|
|
35921
36089
|
let chosen = null;
|
|
35922
36090
|
let why = null;
|
|
35923
36091
|
const note = (skip, detail) => {
|
|
@@ -35934,7 +36102,18 @@ async function runFormalPhase(input) {
|
|
|
35934
36102
|
note("read-failed", `${c.file}: ${read2.reason}`);
|
|
35935
36103
|
continue;
|
|
35936
36104
|
}
|
|
35937
|
-
|
|
36105
|
+
let d = describeTarget(read2.content, c.ai.symbol, c.file, void 0, { codeMap: deps.codeMap, prefer: input.changedLines?.get(c.file) });
|
|
36106
|
+
if (!d.lines && deps.codeMap && input.changedLines?.get(c.file)?.length) {
|
|
36107
|
+
const only = changedFunction(deps.codeMap, c.file, read2.content, input.changedLines.get(c.file));
|
|
36108
|
+
if (only) {
|
|
36109
|
+
const again = describeTarget(read2.content, only, c.file, void 0, { codeMap: deps.codeMap, prefer: input.changedLines.get(c.file) });
|
|
36110
|
+
if (again.lines) {
|
|
36111
|
+
c.ai.reasons = [`the ranker named ${c.ai.symbol}, which is not a function here; the push changed ${only}`, ...c.ai.reasons].slice(0, 4);
|
|
36112
|
+
c.ai.symbol = only;
|
|
36113
|
+
d = again;
|
|
36114
|
+
}
|
|
36115
|
+
}
|
|
36116
|
+
}
|
|
35938
36117
|
if (d.resolved && d.resolved !== c.ai.symbol) c.ai.symbol = d.resolved;
|
|
35939
36118
|
if (input.changedLines) {
|
|
35940
36119
|
const changed = input.changedLines.get(c.file) ?? [];
|
|
@@ -35954,13 +36133,30 @@ async function runFormalPhase(input) {
|
|
|
35954
36133
|
if (d.lines) {
|
|
35955
36134
|
const size = d.lines.to - d.lines.from + 1;
|
|
35956
36135
|
if (size > MAX_MODEL_FUNCTION_LINES) {
|
|
35957
|
-
|
|
35958
|
-
|
|
36136
|
+
const fn = deps.codeMap?.functionAt(c.file, read2.content, c.ai.symbol, input.changedLines?.get(c.file));
|
|
36137
|
+
const region = fn?.source === "tree-sitter" && input.changedLines?.get(c.file)?.length ? deps.codeMap.regionAt(c.file, read2.content, fn.value, input.changedLines.get(c.file), MAX_MODEL_FUNCTION_LINES) : null;
|
|
36138
|
+
if (region?.source !== "tree-sitter") {
|
|
36139
|
+
note("too-large", `${c.ai.symbol}: ${size} lines (at most ${MAX_MODEL_FUNCTION_LINES} are modelled)`);
|
|
36140
|
+
continue;
|
|
36141
|
+
}
|
|
36142
|
+
const { from, to, within } = region.value;
|
|
36143
|
+
const ctx = deps.codeMap ? targetContext({ codeMap: deps.codeMap, codeSource: deps.codeSource, readSource: readSrc, file: c.file, content: read2.content, symbol: c.ai.symbol, prefer: input.changedLines?.get(c.file) }) : null;
|
|
36144
|
+
const inRegion = (ctx?.signals.checkThenAct ?? []).some((x) => {
|
|
36145
|
+
const m = /\(L(\d+)→L(\d+)\)/.exec(x);
|
|
36146
|
+
return !!m && from <= Number(m[1]) && Number(m[2]) <= to;
|
|
36147
|
+
});
|
|
36148
|
+
if (c.ai.score < REGION_MIN_SCORE || !inRegion) {
|
|
36149
|
+
note("too-large", `${c.ai.symbol}: ${size} lines, and no read-then-write of state in lines ${from}\u2013${to} scored ${REGION_MIN_SCORE} or more`);
|
|
36150
|
+
continue;
|
|
36151
|
+
}
|
|
36152
|
+
d = { ...describeTarget(read2.content, c.ai.symbol, c.file, { from, to }), extent: "region" };
|
|
36153
|
+
c.ai.reasons = [`region: lines ${from}\u2013${to} of the ${size}-line ${c.ai.symbol}, in \`${within}\``, ...c.ai.reasons].slice(0, 4);
|
|
35959
36154
|
}
|
|
35960
36155
|
context = deps.codeMap ? targetContext({ codeMap: deps.codeMap, codeSource: deps.codeSource, readSource: readSrc, file: c.file, content: read2.content, symbol: c.ai.symbol, prefer: input.changedLines?.get(c.file) }) : null;
|
|
35961
36156
|
const hazard = hasHazard(functionHazard(d.numbered));
|
|
35962
36157
|
const shared = contextHazard(context);
|
|
35963
|
-
|
|
36158
|
+
const judged = (c.ai.criteria?.hazard ?? 0) >= 0.8;
|
|
36159
|
+
if (!hazard.ok && !shared?.ok && !judged) {
|
|
35964
36160
|
note("no-hazard", `${c.ai.symbol}: ${hazard.why}`);
|
|
35965
36161
|
continue;
|
|
35966
36162
|
}
|
|
@@ -35981,7 +36177,7 @@ async function runFormalPhase(input) {
|
|
|
35981
36177
|
const top = chosen.top;
|
|
35982
36178
|
const sha2562 = sha256Of(chosen.content);
|
|
35983
36179
|
const { lines, numbered: numbered2 } = chosen;
|
|
35984
|
-
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 } : {} };
|
|
36180
|
+
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 } : {} };
|
|
35985
36181
|
progress.target = target;
|
|
35986
36182
|
if (!REPLAYABLE.test(top.file)) return done({ status: "skipped", skip: "replay-unsupported", detail: `${top.file}: replay supports TS/JS and Python`, target });
|
|
35987
36183
|
if (timeLeft() < GENERATE_RESERVE_MS) return done({ status: "skipped", skip: "not-enough-time", detail: `${Math.round(timeLeft() / 1e3)} s left before generation`, target });
|
|
@@ -36203,7 +36399,40 @@ async function prepareFormalPhase(root, env = process.env, auth2, readSource, co
|
|
|
36203
36399
|
const build = await buildLibraryAsync(toolchain, root, 9e4);
|
|
36204
36400
|
if (!build.ok) return { ok: false, skip: "library-build-failed", detail: build.stderr.split("\n").filter((l) => !l.startsWith("trace:")).join(" ").slice(0, 200) };
|
|
36205
36401
|
const loaded = await loadCodeMap(env);
|
|
36206
|
-
|
|
36402
|
+
const source2 = codeSource ?? withoutPaths(worktreeSource(root), isDeniedPath);
|
|
36403
|
+
return { ok: true, deps: { ...defaultDeps({ auth: auth2, apiKey, env, toolchain, readSource, codeMap: loaded.ok ? loaded.map : null, codeSource: source2 }), codeSource: source2 } };
|
|
36404
|
+
}
|
|
36405
|
+
function changedFunction(codeMap, file, content, changed) {
|
|
36406
|
+
const outline = codeMap.outline(file, content);
|
|
36407
|
+
if (outline.source !== "tree-sitter") return null;
|
|
36408
|
+
const size = (f) => f.end.line - f.start.line;
|
|
36409
|
+
const touched = new Set(changed.map((r) => outline.value.filter((f) => f.start.line <= r.to && r.from <= f.end.line).sort((a, b) => size(a) - size(b))[0]?.qualified).filter(Boolean));
|
|
36410
|
+
return touched.size === 1 ? [...touched][0] : null;
|
|
36411
|
+
}
|
|
36412
|
+
function floorCandidate(ranked, changedLines, deps, readSrc, root) {
|
|
36413
|
+
for (const c of ranked.slice(0, 3)) {
|
|
36414
|
+
const changed = changedLines.get(c.file);
|
|
36415
|
+
if (!changed?.length || !deps.codeMap) continue;
|
|
36416
|
+
const read2 = readSrc(c.file, 96 * 1024);
|
|
36417
|
+
if (!read2.ok) continue;
|
|
36418
|
+
const outline = deps.codeMap.outline(c.file, read2.content);
|
|
36419
|
+
if (outline.source !== "tree-sitter") continue;
|
|
36420
|
+
const size = (f) => f.end.line - f.start.line;
|
|
36421
|
+
const touched = [...new Set(changed.map((r) => outline.value.filter((f) => f.start.line <= r.to && r.from <= f.end.line).sort((a, b) => size(a) - size(b))[0]).filter(Boolean))];
|
|
36422
|
+
if ((c.ai?.criteria?.hazard ?? 0) < 0.5) continue;
|
|
36423
|
+
for (const fn of touched.slice(0, 2)) {
|
|
36424
|
+
if (size(fn) + 1 > MAX_MODEL_FUNCTION_LINES) continue;
|
|
36425
|
+
const context = targetContext({ codeMap: deps.codeMap, codeSource: deps.codeSource, readSource: readSrc, file: c.file, content: read2.content, symbol: fn.qualified, prefer: changed });
|
|
36426
|
+
const checkThenAct = context?.signals.checkThenAct ?? [];
|
|
36427
|
+
if (checkThenAct.length === 0) continue;
|
|
36428
|
+
const writers = context?.signals.otherWriters ?? 0;
|
|
36429
|
+
const fixes = writers > 0 ? [] : fixSubjects(root, c.file, fn.start.line, fn.end.line);
|
|
36430
|
+
if (writers === 0 && fixes.length === 0) continue;
|
|
36431
|
+
const why = writers > 0 ? `floor: another function writes the same state (${context?.fields.coAccessors?.map((a) => a.symbol).join(", ") || "found by search"}) and it reads then writes ${checkThenAct[0].split(" ")[0]}` : `floor: fixed before ("${fixes[0]}") and it reads then writes ${checkThenAct[0].split(" ")[0]}`;
|
|
36432
|
+
return { ...c, ai: { score: c.ai?.score ?? 0, symbol: fn.qualified, reasons: [why, ...c.ai?.reasons ?? []].slice(0, 3), properties: c.ai?.properties ?? [], ...c.ai?.criteria ? { criteria: c.ai.criteria } : {} } };
|
|
36433
|
+
}
|
|
36434
|
+
}
|
|
36435
|
+
return null;
|
|
36207
36436
|
}
|
|
36208
36437
|
function runFormalPhaseWithin(input) {
|
|
36209
36438
|
const left = input.deadlineAt - input.deps.now();
|
|
@@ -36772,6 +37001,10 @@ async function runGuard(opts, globals) {
|
|
|
36772
37001
|
extent: formalOutcome.target?.extent ?? null,
|
|
36773
37002
|
// The code map's context for generation: counts only (day 2).
|
|
36774
37003
|
context: formalOutcome.target?.context ?? null,
|
|
37004
|
+
// Why this push was, or was not, modelled (VRT-260): the ranker's scores and criteria per candidate.
|
|
37005
|
+
candidates: (formalOutcome.candidates ?? []).map((c) => ({ file: c.file, symbol: c.symbol, score: c.score, criteria: c.criteria, reasked: c.reasked })),
|
|
37006
|
+
floor: formalOutcome.target?.floor ?? false,
|
|
37007
|
+
detail: formalOutcome.detail ?? null,
|
|
36775
37008
|
rounds: formalOutcome.model?.rounds ?? null,
|
|
36776
37009
|
properties: formalOutcome.properties?.map((p) => `${p.id}:${p.result}`) ?? [],
|
|
36777
37010
|
findings: formalOutcome.findings.map((f) => `${f.property}:${f.verdict}`),
|
|
@@ -39119,7 +39352,7 @@ function registerInitCommand(program2) {
|
|
|
39119
39352
|
...telemetryChoice ? { telemetry: telemetryChoice } : {},
|
|
39120
39353
|
init: {
|
|
39121
39354
|
completed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
39122
|
-
cli_version: true ? "0.33.3-experimental.
|
|
39355
|
+
cli_version: true ? "0.33.3-experimental.53cd005" : "dev"
|
|
39123
39356
|
}
|
|
39124
39357
|
});
|
|
39125
39358
|
} catch (err2) {
|
|
@@ -40581,8 +40814,8 @@ function registerLeanCommand(program2) {
|
|
|
40581
40814
|
}
|
|
40582
40815
|
|
|
40583
40816
|
// src/cli.ts
|
|
40584
|
-
program.name("verity").description("CLI for Verity quality gate service").version("0.33.3-experimental.
|
|
40585
|
-
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.33.3-experimental.
|
|
40817
|
+
program.name("verity").description("CLI for Verity quality gate service").version("0.33.3-experimental.53cd005").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) => {
|
|
40818
|
+
installStderrLog(actionCommand.name(), process.argv.slice(2), "0.33.3-experimental.53cd005");
|
|
40586
40819
|
setUserNamedServiceUrl(program.opts().serviceUrl);
|
|
40587
40820
|
try {
|
|
40588
40821
|
await foldLegacyLocalCredential();
|
package/package.json
CHANGED