loki-mode 11.17.19 → 11.17.21

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 (73) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/autonomy/lib/functional-verify.py +141 -3
  4. package/autonomy/loki +2 -0
  5. package/dashboard/__init__.py +1 -1
  6. package/docs/CLI-REFERENCE.md +1 -1
  7. package/docs/INSTALLATION.md +1 -1
  8. package/docs/v10/BOARD.md +15 -15
  9. package/docs/v10/CLI-MODERN.md +1 -1
  10. package/docs/v10/FAILURE-CLASSES.md +7 -0
  11. package/docs/v10/PROGRESS.md +7 -0
  12. package/loki-ts/dist/loki.js +926 -922
  13. package/mcp/__init__.py +1 -1
  14. package/package.json +2 -2
  15. package/packages/control-plane/dist/server.js +393 -324
  16. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  17. package/web-app/dist/assets/{AdminPage-Dc62a8CS.js → AdminPage-DGg_5Yos.js} +1 -1
  18. package/web-app/dist/assets/{Avatar-3Z6DLFQZ.js → Avatar-BIDvM3U5.js} +1 -1
  19. package/web-app/dist/assets/{Badge-mkuAR2TD.js → Badge-AsUMPLOU.js} +1 -1
  20. package/web-app/dist/assets/{Button-EQyd4r_R.js → Button-DodbV8If.js} +1 -1
  21. package/web-app/dist/assets/{CockpitPage-BtlAhPdm.js → CockpitPage-BxL2zTsP.js} +1 -1
  22. package/web-app/dist/assets/{ComparePage-BbbQ5kC5.js → ComparePage-O1iC9fvU.js} +1 -1
  23. package/web-app/dist/assets/{ErrorBoundary-VIK-1yJA.js → ErrorBoundary-Cll1sP40.js} +1 -1
  24. package/web-app/dist/assets/{EvidenceReceiptPanel-B9EPySH2.js → EvidenceReceiptPanel-DXlOEyn9.js} +1 -1
  25. package/web-app/dist/assets/{GitHubIssuesPanel-DrxLIcV6.js → GitHubIssuesPanel-DbbqZGUy.js} +1 -1
  26. package/web-app/dist/assets/{GitHubPRsPanel-BNuKtoKu.js → GitHubPRsPanel-B6XhdcJp.js} +1 -1
  27. package/web-app/dist/assets/{HomePage-sZJBAvuK.js → HomePage-DenelbJm.js} +2 -2
  28. package/web-app/dist/assets/{LoginPage-BNe7doQt.js → LoginPage-MF65tKQb.js} +1 -1
  29. package/web-app/dist/assets/{MagicPage-Djh-aWoE.js → MagicPage-Caa_kRza.js} +1 -1
  30. package/web-app/dist/assets/{MetricsPage-B5RoFk1f.js → MetricsPage-BVSJe-I6.js} +1 -1
  31. package/web-app/dist/assets/{NotFoundPage-BiG9Qx-K.js → NotFoundPage-BPTMfi71.js} +1 -1
  32. package/web-app/dist/assets/{ProjectPage-rQZIHvO1.js → ProjectPage-BbnEno5f.js} +3 -3
  33. package/web-app/dist/assets/{ProjectsPage-Br37M7yx.js → ProjectsPage-CYL7Eh40.js} +1 -1
  34. package/web-app/dist/assets/{SettingsPage-DxEcGRRT.js → SettingsPage-D5rk0Q-i.js} +1 -1
  35. package/web-app/dist/assets/{ShowcasePage-BQ_cOsd8.js → ShowcasePage-Cgsx2N4V.js} +1 -1
  36. package/web-app/dist/assets/{SystemSettingsPage-CJuMeLfn.js → SystemSettingsPage-DKPw7kf7.js} +1 -1
  37. package/web-app/dist/assets/{TeamsPage-CxNvYxl0.js → TeamsPage-BOQyzfGG.js} +1 -1
  38. package/web-app/dist/assets/{TemplatesPage-CowBuPlo.js → TemplatesPage-C85kNfws.js} +1 -1
  39. package/web-app/dist/assets/{TerminalOutput-Bs0qzgnx.js → TerminalOutput-CaZ75acm.js} +1 -1
  40. package/web-app/dist/assets/{activity-BZBTb6gx.js → activity-_vZZ0q95.js} +1 -1
  41. package/web-app/dist/assets/{bell-DWQ-mGsX.js → bell-BepNateL.js} +1 -1
  42. package/web-app/dist/assets/{bot-Cp-aoJki.js → bot-CLPO5bfI.js} +1 -1
  43. package/web-app/dist/assets/{check-CyFL_qpg.js → check-Cw2ZY8Hd.js} +1 -1
  44. package/web-app/dist/assets/{chevron-left-CSpNuW_B.js → chevron-left-CNkV8_tB.js} +1 -1
  45. package/web-app/dist/assets/{circle-alert-BLXbl8kD.js → circle-alert-CBgwfRV4.js} +1 -1
  46. package/web-app/dist/assets/{clock-BBWu569k.js → clock-Kbd5g1Q4.js} +1 -1
  47. package/web-app/dist/assets/{cloud-Ce7Luvrn.js → cloud-BUHvBaGU.js} +1 -1
  48. package/web-app/dist/assets/{code-xml-C_ID1rox.js → code-xml-BFtb44h7.js} +1 -1
  49. package/web-app/dist/assets/{database-_ed-qaFL.js → database-BKTm6rSV.js} +1 -1
  50. package/web-app/dist/assets/{dollar-sign-CYnJuf7T.js → dollar-sign-CxSlnHdr.js} +1 -1
  51. package/web-app/dist/assets/{file-code-corner-jBR2MosN.js → file-code-corner-CzODg9ft.js} +1 -1
  52. package/web-app/dist/assets/{file-plus-DObnySLq.js → file-plus-DwR8w4_g.js} +1 -1
  53. package/web-app/dist/assets/{globe-CBYgMBCX.js → globe-BN26QQLG.js} +1 -1
  54. package/web-app/dist/assets/{hammer-Aopfj9DH.js → hammer-BMGuBFj7.js} +1 -1
  55. package/web-app/dist/assets/{index-Az6c4mLi.js → index-RYEDj5dp.js} +3 -3
  56. package/web-app/dist/assets/{layers-RU1n4mJF.js → layers-Bih4Qqbx.js} +1 -1
  57. package/web-app/dist/assets/{loader-circle-vkUFjVTs.js → loader-circle-DTh3fBtD.js} +1 -1
  58. package/web-app/dist/assets/{lock-DX7cm7nZ.js → lock-B77al7oQ.js} +1 -1
  59. package/web-app/dist/assets/{package-rQet8lbL.js → package-BMcYmquO.js} +1 -1
  60. package/web-app/dist/assets/{plus-B6lq3pKQ.js → plus-D40JVGe8.js} +1 -1
  61. package/web-app/dist/assets/{refresh-cw-C5pY6vxn.js → refresh-cw-BzmtMb8b.js} +1 -1
  62. package/web-app/dist/assets/{rotate-ccw-B_66hj0H.js → rotate-ccw-B0-EyBz6.js} +1 -1
  63. package/web-app/dist/assets/{scroll-text-DoY2VPSX.js → scroll-text-BQNWKEf4.js} +1 -1
  64. package/web-app/dist/assets/{server-Cur2b1Py.js → server-DrTKOH08.js} +1 -1
  65. package/web-app/dist/assets/{shield-alert-ZxlmrPzT.js → shield-alert-bacDs6zS.js} +1 -1
  66. package/web-app/dist/assets/{thumbs-up-CO6PAF2d.js → thumbs-up-CKbEwA0r.js} +1 -1
  67. package/web-app/dist/assets/{trash-2-KkO1Q-C7.js → trash-2-BeWrrpHd.js} +1 -1
  68. package/web-app/dist/assets/{trending-down-eak_OVU-.js → trending-down-UfhUQ_MW.js} +1 -1
  69. package/web-app/dist/assets/{trending-up-X0avjdBr.js → trending-up-CLkxjmYM.js} +1 -1
  70. package/web-app/dist/assets/{upload-CMNuZ7nb.js → upload-DdaprL3w.js} +1 -1
  71. package/web-app/dist/assets/{usePolling-BOF9VJY_.js → usePolling-Btjcs4pC.js} +1 -1
  72. package/web-app/dist/assets/{user-CemBNbFR.js → user-DhyL9aMl.js} +1 -1
  73. package/web-app/dist/index.html +1 -1
@@ -9674,6 +9674,19 @@ var init_test_file_text = __esm(() => {
9674
9674
  });
9675
9675
 
9676
9676
  // ../../loki-ts/src/engine10/testmap.ts
9677
+ import { existsSync as existsSync22, readdirSync as readdirSync13, readFileSync as readFileSync28, realpathSync as realpathSync16 } from "fs";
9678
+ import { basename as basename10, extname, isAbsolute as isAbsolute2, join as join37, relative, sep as sep10 } from "path";
9679
+ function projectInterpreter(root) {
9680
+ const ve = process.env["VIRTUAL_ENV"], inRepo = (p) => {
9681
+ try {
9682
+ const r = relative(realpathSync16(root), realpathSync16(p));
9683
+ return r !== "" && !r.startsWith("..") && !isAbsolute2(r);
9684
+ } catch {
9685
+ return false;
9686
+ }
9687
+ };
9688
+ return [join37(root, ".venv", "bin", "python"), join37(root, "venv", "bin", "python"), ...ve && inRepo(ve) ? [join37(ve, "bin", "python")] : []].some(existsSync22) ? "project" : "system";
9689
+ }
9677
9690
  var SKIP_DIRS;
9678
9691
  var init_testmap = __esm(() => {
9679
9692
  init_resolve();
@@ -9697,8 +9710,8 @@ var init_testmap = __esm(() => {
9697
9710
  });
9698
9711
 
9699
9712
  // ../../loki-ts/src/util/check_result.ts
9700
- import { mkdirSync as mkdirSync13, readFileSync as readFileSync28, renameSync as renameSync8, writeFileSync as writeFileSync16 } from "fs";
9701
- import { basename as basename10, join as join37 } from "path";
9713
+ import { mkdirSync as mkdirSync13, readFileSync as readFileSync29, renameSync as renameSync8, writeFileSync as writeFileSync16 } from "fs";
9714
+ import { basename as basename11, join as join38 } from "path";
9702
9715
  function plainTestEnv(base = process.env) {
9703
9716
  const e = {};
9704
9717
  for (const [k, v] of Object.entries(tokenFreeEnv(base)))
@@ -9716,7 +9729,7 @@ function ran(raw2, path, ok) {
9716
9729
  if (blk) {
9717
9730
  const c = n2(blk, /(?:#|\u2139) pass (\d+)/) + n2(blk, /(?:#|\u2139) fail (\d+)/);
9718
9731
  const nm = out2.match(/^(?:ok \d+ - |\u2714 )(\S+\.[cm]?[jt]s)(?: \(|$)/m)?.[1];
9719
- return c === 1 && nm && (!path || basename10(nm) === basename10(path)) ? 0 : c;
9732
+ return c === 1 && nm && (!path || basename11(nm) === basename11(path)) ? 0 : c;
9720
9733
  }
9721
9734
  const cg = cargoTrailer(out2);
9722
9735
  if (cg.length)
@@ -9807,16 +9820,16 @@ function goRunner(cmd, args) {
9807
9820
  let k = 0;
9808
9821
  for (;k < t.length; k++) {
9809
9822
  const x = t[k];
9810
- if (/^[A-Za-z_]\w*=/.test(x) || /^(?:env|command|exec|time|nohup)$/.test(basename10(x)))
9823
+ if (/^[A-Za-z_]\w*=/.test(x) || /^(?:env|command|exec|time|nohup)$/.test(basename11(x)))
9811
9824
  continue;
9812
- if (/^-/.test(x) && k > 0 && basename10(t[k - 1]) === "env") {
9825
+ if (/^-/.test(x) && k > 0 && basename11(t[k - 1]) === "env") {
9813
9826
  if (x === "-u" || x === "-C" || x === "-S")
9814
9827
  k++;
9815
9828
  continue;
9816
9829
  }
9817
9830
  break;
9818
9831
  }
9819
- if (t[k] !== undefined && basename10(t[k]) === "go")
9832
+ if (t[k] !== undefined && basename11(t[k]) === "go")
9820
9833
  return { runner: "go" };
9821
9834
  }
9822
9835
  return {};
@@ -9993,7 +10006,7 @@ function diffFiles(repoDir, baseSha) {
9993
10006
  return f;
9994
10007
  let n2 = 0;
9995
10008
  try {
9996
- n2 = readFileSync28(join37(repoDir, path), "utf8").split(`
10009
+ n2 = readFileSync29(join38(repoDir, path), "utf8").split(`
9997
10010
  `).length;
9998
10011
  } catch {}
9999
10012
  return { path, added: n2, deleted: 0, status: "added" };
@@ -10001,7 +10014,7 @@ function diffFiles(repoDir, baseSha) {
10001
10014
  }
10002
10015
  function recordRisk(repoDir, a) {
10003
10016
  try {
10004
- const dir = join37(repoDir, ".loki", "state"), p = join37(dir, "risk-tier.json");
10017
+ const dir = join38(repoDir, ".loki", "state"), p = join38(dir, "risk-tier.json");
10005
10018
  mkdirSync13(dir, { recursive: true });
10006
10019
  writeFileSync16(`${p}.tmp`, JSON.stringify(a, null, 2) + `
10007
10020
  `);
@@ -10011,12 +10024,54 @@ function recordRisk(repoDir, a) {
10011
10024
  return null;
10012
10025
  }
10013
10026
  }
10027
+ function truncateBytes(s, cap) {
10028
+ const buf = Buffer.from(s, "utf8");
10029
+ return buf.length <= cap ? s : buf.subarray(0, Math.max(0, cap)).toString("utf8").replace(/\uFFFD$/, "");
10030
+ }
10031
+ function failureExcerpt(out2, repoDir = "", cap = EXCERPT_GROUP_CAP) {
10032
+ let t = stripAnsi(out2.slice(-65536)).replace(/\r/g, "");
10033
+ if (repoDir)
10034
+ t = t.split(repoDir.replace(/\/+$/, "") + "/").join("");
10035
+ const lines = t.split(`
10036
+ `).map((l) => l.replace(/\s+$/, ""));
10037
+ const pick = new Set;
10038
+ const take = (i, n2 = 1) => {
10039
+ for (let k = 0;k < n2 && i + k < lines.length; k++)
10040
+ if (lines[i + k].trim())
10041
+ pick.add(i + k);
10042
+ };
10043
+ lines.forEach((l, i) => {
10044
+ if (/^E\s/.test(l))
10045
+ take(i);
10046
+ else if (/^\s*(Expected|Received)\b/.test(l) || /^\s*expect\(.*\)\.\w+/.test(l))
10047
+ take(i);
10048
+ else if (/^[\w./@-]+\.py:\d+: /.test(l))
10049
+ take(i);
10050
+ else if (/AssertionError|^\s*(expected|actual)\b.*[:=]|^\s*(not ok|FAILED)\b/.test(l))
10051
+ take(i, 3);
10052
+ else if (/^\s*--- FAIL/.test(l))
10053
+ take(i, 4);
10054
+ else if (/^[\w./@-]+\.\w+(\(\d+,\d+\)|:\d+(:\d+)?)[:\s].*\b(error|TS\d+|[A-Z]{1,3}\d{3,4})\b/.test(l))
10055
+ take(i);
10056
+ });
10057
+ const lastFrame = lines.map((l, i) => /^[\w./@-]+\.py:\d+: /.test(l) ? i : -1).filter((i) => i >= 0).pop();
10058
+ if (lastFrame !== undefined && [...pick].some((i) => /^E\s/.test(lines[i])))
10059
+ take(lastFrame);
10060
+ let body = [...pick].sort((a, b) => a - b).map((i) => lines[i]).join(`
10061
+ `);
10062
+ if (!body)
10063
+ body = lines.filter((l) => l.trim()).slice(-6).join(`
10064
+ `);
10065
+ body = redactSecrets(body);
10066
+ return truncateBytes(body, cap);
10067
+ }
10014
10068
  var NO_TESTS_REASON = "no tests executed", GO_EXIT0_REASON = "test count could not be confirmed: go test output is produced by the code under test and cannot confirm execution (a Go exit 0 is never a pass)", UNCONFIRMED_REASON = "test count could not be confirmed", FAIL_EVIDENCE, GO_FAIL_EVIDENCE, UNMEASURED_REASON = "executed count unmeasured (Loki could not parse the runner summary, harness-owned)", stripAnsi = (s) => s.replace(/\u001b\][^\u0007\u001b]*(?:\u0007|\u001b\\)/g, "").replace(/(?:\u001b\[|\u009b)[0-9;?]*[ -\/]*[@-~]/g, "").replace(/\r\n?/g, `
10015
10069
  `), tailLines = (out2) => out2.split(`
10016
- `).filter((x) => x.trim()).slice(-12), GO_PKG_RE, isExecutedProof = (c) => c.result === "pass" && typeof c.n === "number" && c.n > 0, hasExecutedProof = (checks) => checks.some(isExecutedProof), LLM_JUDGES, NON_RUNNER, SENSITIVE, API, TEST_CFG, RANK2, FILES_MEDIUM = 4, FILES_HIGH = 15, LINES_MEDIUM = 100, LINES_HIGH = 500, RAN_ALWAYS, PLAN, LOW_SKIPPED, deferredOf = (tier, selected, executed) => (tier === "low" ? LOW_SKIPPED : selected).filter((c) => !RAN_ALWAYS.includes(c) && !executed.includes(c));
10070
+ `).filter((x) => x.trim()).slice(-12), GO_PKG_RE, isExecutedProof = (c) => c.result === "pass" && typeof c.n === "number" && c.n > 0, hasExecutedProof = (checks) => checks.some(isExecutedProof), LLM_JUDGES, NON_RUNNER, SENSITIVE, API, TEST_CFG, RANK2, FILES_MEDIUM = 4, FILES_HIGH = 15, LINES_MEDIUM = 100, LINES_HIGH = 500, RAN_ALWAYS, PLAN, LOW_SKIPPED, deferredOf = (tier, selected, executed) => (tier === "low" ? LOW_SKIPPED : selected).filter((c) => !RAN_ALWAYS.includes(c) && !executed.includes(c)), EXCERPT_GROUP_CAP = 1500, EXCERPT_TOTAL_CAP = 6144;
10017
10071
  var init_check_result = __esm(() => {
10018
10072
  init_testmap();
10019
10073
  init_safe_git();
10074
+ init_redact();
10020
10075
  FAIL_EVIDENCE = /\[(?:build|setup) failed\]|^--- FAIL|^[\w./-]+\.go:\d+:\d+: \S|\b[1-9]\d* (?:failed|errors?)\b/m;
10021
10076
  GO_FAIL_EVIDENCE = /^FAIL\t\S+\t[\d.]+s$|^panic: /m;
10022
10077
  GO_PKG_RE = /^(?:ok|FAIL|\?)\s+\S+\s+(?:\(cached\)|[\d.]+s\b|\[(?:no test files|build failed|setup failed)\])/;
@@ -10062,11 +10117,11 @@ var init_state = __esm(() => {
10062
10117
  });
10063
10118
 
10064
10119
  // ../../loki-ts/src/runner/repo_profile.ts
10065
- import { existsSync as existsSync22, readFileSync as readFileSync29, mkdirSync as mkdirSync14, readdirSync as readdirSync13, renameSync as renameSync9, rmSync as rmSync8, writeFileSync as writeFileSync17 } from "fs";
10066
- import { basename as basename11, join as join38, resolve as resolve13, isAbsolute as isAbsolute2 } from "path";
10120
+ import { existsSync as existsSync23, readFileSync as readFileSync30, mkdirSync as mkdirSync14, readdirSync as readdirSync14, renameSync as renameSync9, rmSync as rmSync8, writeFileSync as writeFileSync17 } from "fs";
10121
+ import { basename as basename12, join as join39, resolve as resolve13, isAbsolute as isAbsolute3 } from "path";
10067
10122
  function loadProfile(repoDir) {
10068
10123
  try {
10069
- const p = JSON.parse(readFileSync29(commandProfilePath(repoDir), "utf8"));
10124
+ const p = JSON.parse(readFileSync30(commandProfilePath(repoDir), "utf8"));
10070
10125
  return p?.version === 1 && Array.isArray(p.commands) && p.baseline ? p : null;
10071
10126
  } catch {
10072
10127
  return null;
@@ -10157,7 +10212,7 @@ async function staticPreExisting(tool, prefix, files, io) {
10157
10212
  }
10158
10213
  return attributeStatic(tool, head.out, baseOut, 1).preExisting;
10159
10214
  }
10160
- var commandProfilePath = (repoDir) => join38(repoDir, ".loki", "state", "repo-profile.json"), STATIC_DIAG, STATIC_NOISE, STATIC_SUMMARY;
10215
+ var commandProfilePath = (repoDir) => join39(repoDir, ".loki", "state", "repo-profile.json"), STATIC_DIAG, STATIC_NOISE, STATIC_SUMMARY;
10161
10216
  var init_repo_profile = __esm(() => {
10162
10217
  init_failures();
10163
10218
  init_check_result();
@@ -10199,14 +10254,14 @@ var init_context = __esm(() => {
10199
10254
  });
10200
10255
 
10201
10256
  // ../../loki-ts/src/util/steer.ts
10202
- import { appendFileSync as appendFileSync2, closeSync as closeSync8, constants as constants2, fstatSync as fstatSync6, readdirSync as readdirSync14, lstatSync as lstatSync9, mkdirSync as mkdirSync15, linkSync as linkSync2, openSync as openSync8, readFileSync as readFileSync30, readSync as readSync7, renameSync as renameSync10, statSync as statSync15, lutimesSync, rmSync as rmSync9, unlinkSync as unlinkSync5, writeFileSync as writeFileSync18, existsSync as existsSync23 } from "fs";
10257
+ import { appendFileSync as appendFileSync2, closeSync as closeSync8, constants as constants2, fstatSync as fstatSync6, readdirSync as readdirSync15, lstatSync as lstatSync9, mkdirSync as mkdirSync15, linkSync as linkSync2, openSync as openSync8, readFileSync as readFileSync31, readSync as readSync7, renameSync as renameSync10, statSync as statSync15, lutimesSync, rmSync as rmSync9, unlinkSync as unlinkSync5, writeFileSync as writeFileSync18, existsSync as existsSync24 } from "fs";
10203
10258
  import { createHash as createHash9, randomBytes as randomBytes4 } from "crypto";
10204
- import { basename as basename12, join as join39 } from "path";
10259
+ import { basename as basename13, join as join40 } from "path";
10205
10260
  function archiveTo(logs, prefix, src, link = linkSync2, onLinked) {
10206
10261
  for (let i = 0;; i++) {
10207
10262
  const name = i === 0 ? `${prefix}.md` : `${prefix}-${i}.md`;
10208
10263
  try {
10209
- link(src, join39(logs, name));
10264
+ link(src, join40(logs, name));
10210
10265
  } catch (e) {
10211
10266
  const code = e.code;
10212
10267
  if (code === "EEXIST")
@@ -10214,7 +10269,7 @@ function archiveTo(logs, prefix, src, link = linkSync2, onLinked) {
10214
10269
  if (code !== "EPERM" && code !== "ENOTSUP" && code !== "EXDEV" && code !== "EMLINK")
10215
10270
  throw e;
10216
10271
  const name2 = `${prefix}-${randomBytes4(4).toString("hex")}.md`;
10217
- renameSync10(src, join39(logs, name2));
10272
+ renameSync10(src, join40(logs, name2));
10218
10273
  onLinked?.(name2);
10219
10274
  return name2;
10220
10275
  }
@@ -10229,14 +10284,14 @@ function orphanAlreadyArchived(logs, claim) {
10229
10284
  const c = lstatSync9(claim);
10230
10285
  if (!c.isFile())
10231
10286
  return false;
10232
- for (const a of readdirSync14(logs)) {
10287
+ for (const a of readdirSync15(logs)) {
10233
10288
  if (!/^human-input-.*\.md$/.test(a))
10234
10289
  continue;
10235
10290
  try {
10236
- const s = statSync15(join39(logs, a));
10291
+ const s = statSync15(join40(logs, a));
10237
10292
  if (s.ino !== c.ino || s.dev !== c.dev)
10238
10293
  continue;
10239
- if (/^human-input-(ORPHAN|REJECTED)-/.test(a) || existsSync23(appliedMarker(logs, a)))
10294
+ if (/^human-input-(ORPHAN|REJECTED)-/.test(a) || existsSync24(appliedMarker(logs, a)))
10240
10295
  return true;
10241
10296
  } catch {}
10242
10297
  }
@@ -10245,7 +10300,7 @@ function orphanAlreadyArchived(logs, claim) {
10245
10300
  function sweepOrphans(logs, stamp2, unapplied, link, nowMs = Date.now()) {
10246
10301
  let names;
10247
10302
  try {
10248
- names = readdirSync14(logs);
10303
+ names = readdirSync15(logs);
10249
10304
  } catch {
10250
10305
  return;
10251
10306
  }
@@ -10253,7 +10308,7 @@ function sweepOrphans(logs, stamp2, unapplied, link, nowMs = Date.now()) {
10253
10308
  for (const n2 of names)
10254
10309
  if (n2.startsWith(".applied-") && !present.has(n2.slice(".applied-".length))) {
10255
10310
  try {
10256
- unlinkSync5(join39(logs, n2));
10311
+ unlinkSync5(join40(logs, n2));
10257
10312
  } catch {}
10258
10313
  }
10259
10314
  for (const n2 of names) {
@@ -10270,7 +10325,7 @@ function sweepOrphans(logs, stamp2, unapplied, link, nowMs = Date.now()) {
10270
10325
  if (alive) {
10271
10326
  let ageMs = 0;
10272
10327
  try {
10273
- ageMs = nowMs - statSync15(join39(logs, n2)).mtimeMs;
10328
+ ageMs = nowMs - statSync15(join40(logs, n2)).mtimeMs;
10274
10329
  } catch {
10275
10330
  continue;
10276
10331
  }
@@ -10278,11 +10333,11 @@ function sweepOrphans(logs, stamp2, unapplied, link, nowMs = Date.now()) {
10278
10333
  continue;
10279
10334
  }
10280
10335
  try {
10281
- if (orphanAlreadyArchived(logs, join39(logs, n2))) {
10282
- unlinkSync5(join39(logs, n2));
10336
+ if (orphanAlreadyArchived(logs, join40(logs, n2))) {
10337
+ unlinkSync5(join40(logs, n2));
10283
10338
  continue;
10284
10339
  }
10285
- archiveTo(logs, `human-input-ORPHAN-${stamp2}`, join39(logs, n2), link);
10340
+ archiveTo(logs, `human-input-ORPHAN-${stamp2}`, join40(logs, n2), link);
10286
10341
  unapplied("orphaned claim");
10287
10342
  } catch (e) {
10288
10343
  if (e.code === "ENOENT")
@@ -10294,17 +10349,17 @@ function sweepOrphans(logs, stamp2, unapplied, link, nowMs = Date.now()) {
10294
10349
  function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, hooks2) {
10295
10350
  if (/^(0|false)$/i.test(env.LOKI_PROMPT_INJECTION ?? ""))
10296
10351
  return null;
10297
- const f = join39(repoDir, ".loki", "HUMAN_INPUT.md");
10352
+ const f = join40(repoDir, ".loki", "HUMAN_INPUT.md");
10298
10353
  const unapplied = (reason) => {
10299
10354
  sink?.push({ rev: 0, source: null, actor: null, sha: "", at: now2().getTime(), unapplied: true, reason });
10300
10355
  };
10301
10356
  let fd = -1, claimed = "";
10302
10357
  try {
10303
- const logs = join39(repoDir, ".loki", "logs");
10358
+ const logs = join40(repoDir, ".loki", "logs");
10304
10359
  mkdirSync15(logs, { recursive: true });
10305
10360
  const stamp2 = now2().toISOString().replace(/[-:]/g, "").replace(/\..*/, "");
10306
10361
  sweepOrphans(logs, stamp2, unapplied, hooks2?.link, now2().getTime());
10307
- claimed = join39(logs, `.claim-${process.pid}-${randomBytes4(6).toString("hex")}`);
10362
+ claimed = join40(logs, `.claim-${process.pid}-${randomBytes4(6).toString("hex")}`);
10308
10363
  try {
10309
10364
  renameSync10(f, claimed);
10310
10365
  } catch (e) {
@@ -10395,10 +10450,10 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
10395
10450
  } catch {
10396
10451
  if (claimed) {
10397
10452
  try {
10398
- archiveTo(join39(repoDir, ".loki", "logs"), `human-input-${now2().toISOString().replace(/[-:]/g, "").replace(/\..*/, "")}`, claimed, hooks2?.link);
10453
+ archiveTo(join40(repoDir, ".loki", "logs"), `human-input-${now2().toISOString().replace(/[-:]/g, "").replace(/\..*/, "")}`, claimed, hooks2?.link);
10399
10454
  unapplied("logs dir unwritable or file unreadable");
10400
10455
  } catch {
10401
- unapplied(`steer stranded at .loki/logs/${basename12(claimed)}`);
10456
+ unapplied(`steer stranded at .loki/logs/${basename13(claimed)}`);
10402
10457
  }
10403
10458
  } else
10404
10459
  try {
@@ -10414,10 +10469,10 @@ function consumeSteer(repoDir, env = process.env, now2 = () => new Date, sink, h
10414
10469
  }
10415
10470
  }
10416
10471
  function recordRevisions(repoDir, text2, archived, at) {
10417
- const file = join39(repoDir, ".loki", "intent-revisions.jsonl");
10472
+ const file = join40(repoDir, ".loki", "intent-revisions.jsonl");
10418
10473
  let last = 0;
10419
10474
  try {
10420
- for (const l of readFileSync30(file, "utf8").split(`
10475
+ for (const l of readFileSync31(file, "utf8").split(`
10421
10476
  `)) {
10422
10477
  try {
10423
10478
  last = Math.max(last, Number(JSON.parse(l).rev) || 0);
@@ -10471,7 +10526,7 @@ function staleAtSeal(repoDir, ctx) {
10471
10526
  const frozen = ctx.outputs === undefined || ctx.outputs().wall !== undefined || ctx.wallSealed === true;
10472
10527
  return [...new Set([...staleWallRevisions(ctx.intentRevisions, frozen ? ctx.timeline : []), ...late])];
10473
10528
  }
10474
- var STEER_MAX_BYTES, STEER_STAGES, STEER_CLAIM_MAX_AGE_MS, appliedMarker = (logs, archive) => join39(logs, `.applied-${archive}`), REV_HDR, STEER_REMEDY;
10529
+ var STEER_MAX_BYTES, STEER_STAGES, STEER_CLAIM_MAX_AGE_MS, appliedMarker = (logs, archive) => join40(logs, `.applied-${archive}`), REV_HDR, STEER_REMEDY;
10475
10530
  var init_steer = __esm(() => {
10476
10531
  init_context();
10477
10532
  STEER_MAX_BYTES = 1024 * 1024;
@@ -10534,18 +10589,18 @@ var init_seal_drift = __esm(() => {
10534
10589
  });
10535
10590
 
10536
10591
  // ../../loki-ts/src/util/spec_file.ts
10537
- import { isAbsolute as isAbsolute3, join as join40, relative } from "path";
10592
+ import { isAbsolute as isAbsolute4, join as join41, relative as relative2 } from "path";
10538
10593
  function specReceiptBlock(env) {
10539
10594
  const { LOKI_E10_SPEC_PATH: p, LOKI_E10_SPEC_SHA256: sha2 } = env;
10540
10595
  if (!p || !sha2)
10541
10596
  return {};
10542
- const rel = isAbsolute3(p) && env.LOKI_E10_REPO_DIR ? relative(env.LOKI_E10_REPO_DIR, p) : p;
10597
+ const rel = isAbsolute4(p) && env.LOKI_E10_REPO_DIR ? relative2(env.LOKI_E10_REPO_DIR, p) : p;
10543
10598
  return { spec: { path: rel, sha256: sha2 } };
10544
10599
  }
10545
10600
  var SPEC_DIR;
10546
10601
  var init_spec_file = __esm(() => {
10547
10602
  init_types();
10548
- SPEC_DIR = join40(".loki", "specs");
10603
+ SPEC_DIR = join41(".loki", "specs");
10549
10604
  });
10550
10605
 
10551
10606
  // ../../loki-ts/src/engine10/pr_body.ts
@@ -10565,11 +10620,11 @@ var init_run_cap = __esm(() => {
10565
10620
  });
10566
10621
 
10567
10622
  // ../../loki-ts/src/util/mutation_proof.ts
10568
- import { existsSync as existsSync24, mkdirSync as mkdirSync16, mkdtempSync as mkdtempSync3, readFileSync as readFileSync31, rmSync as rmSync10, symlinkSync, writeFileSync as writeFileSync19 } from "fs";
10623
+ import { existsSync as existsSync25, mkdirSync as mkdirSync16, mkdtempSync as mkdtempSync3, readFileSync as readFileSync32, rmSync as rmSync10, symlinkSync, writeFileSync as writeFileSync19 } from "fs";
10569
10624
  import { tmpdir as tmpdir4 } from "os";
10570
- import { basename as basename13, dirname as dirname13, isAbsolute as isAbsolute4, join as join41, relative as relative2 } from "path";
10625
+ import { basename as basename14, dirname as dirname13, isAbsolute as isAbsolute5, join as join42, relative as relative3 } from "path";
10571
10626
  function mutationProof(i) {
10572
- const rels = i.wallFiles.map((f) => isAbsolute4(f.path) ? relative2(i.repoDir, f.path) : f.path);
10627
+ const rels = i.wallFiles.map((f) => isAbsolute5(f.path) ? relative3(i.repoDir, f.path) : f.path);
10573
10628
  if (rels.length === 0)
10574
10629
  return np("no Wall tests");
10575
10630
  const tests = rels.flatMap((rel) => {
@@ -10585,26 +10640,26 @@ function mutationProof(i) {
10585
10640
  const deadline = Date.now() + budgetS * 1000, remaining = () => deadline - Date.now();
10586
10641
  let parent = null, wt = null, added = false;
10587
10642
  try {
10588
- parent = mkdtempSync3(join41(tmpdir4(), "loki-mutproof-"));
10589
- wt = join41(parent, "wt");
10643
+ parent = mkdtempSync3(join42(tmpdir4(), "loki-mutproof-"));
10644
+ wt = join42(parent, "wt");
10590
10645
  const add3 = git(i.repoDir, ["worktree", "add", "--detach", wt, i.baseSha], Math.max(1000, Math.min(30000, remaining())));
10591
- added = existsSync24(wt) || add3.status === 0;
10646
+ added = existsSync25(wt) || add3.status === 0;
10592
10647
  if (add3.status !== 0)
10593
10648
  return np("could not create the base worktree");
10594
10649
  for (const rel of rels) {
10595
- const sealed = join41(i.runDir, "wall", basename13(rel)), src = existsSync24(sealed) ? sealed : join41(i.repoDir, rel);
10596
- if (!existsSync24(src))
10650
+ const sealed = join42(i.runDir, "wall", basename14(rel)), src = existsSync25(sealed) ? sealed : join42(i.repoDir, rel);
10651
+ if (!existsSync25(src))
10597
10652
  return np(`Wall file missing: ${rel}`);
10598
- mkdirSync16(dirname13(join41(wt, rel)), { recursive: true });
10599
- writeFileSync19(join41(wt, rel), readFileSync31(src));
10653
+ mkdirSync16(dirname13(join42(wt, rel)), { recursive: true });
10654
+ writeFileSync19(join42(wt, rel), readFileSync32(src));
10600
10655
  }
10601
10656
  for (const rel of rels) {
10602
10657
  const parts = rel.split("/").slice(0, -1);
10603
10658
  for (let n2 = 0;n2 <= parts.length; n2++) {
10604
10659
  const anc = parts.slice(0, n2).join("/");
10605
10660
  for (const d of DEP_DIRS) {
10606
- const src = join41(i.repoDir, anc, d), dst = join41(wt, anc, d);
10607
- if (existsSync24(src) && !existsSync24(dst)) {
10661
+ const src = join42(i.repoDir, anc, d), dst = join42(wt, anc, d);
10662
+ if (existsSync25(src) && !existsSync25(dst)) {
10608
10663
  try {
10609
10664
  symlinkSync(src, dst);
10610
10665
  } catch {}
@@ -10732,7 +10787,7 @@ var init_shell = __esm(() => {
10732
10787
  });
10733
10788
 
10734
10789
  // ../../loki-ts/src/util/python.ts
10735
- import { accessSync, constants as constants3, existsSync as existsSync25, mkdtempSync as mkdtempSync4, readFileSync as readFileSync32, realpathSync as realpathSync16, rmSync as rmSync11, statSync as statSync16 } from "fs";
10790
+ import { accessSync, constants as constants3, existsSync as existsSync26, mkdtempSync as mkdtempSync4, readFileSync as readFileSync33, realpathSync as realpathSync17, rmSync as rmSync11, statSync as statSync16 } from "fs";
10736
10791
  import { spawnSync as spawnSync2 } from "child_process";
10737
10792
  import { tmpdir as tmpdir5 } from "os";
10738
10793
  function resolvePython3() {
@@ -11073,7 +11128,7 @@ var init_wall_manifest = __esm(() => {
11073
11128
 
11074
11129
  // ../../loki-ts/src/features/wall_manifest_wire.ts
11075
11130
  import { createHash as createHash11 } from "crypto";
11076
- import { basename as basename14, dirname as dirname14 } from "path";
11131
+ import { basename as basename15, dirname as dirname14 } from "path";
11077
11132
  function blobEntries(ls) {
11078
11133
  const out2 = [];
11079
11134
  for (const raw2 of ls.toString("latin1").split("\x00")) {
@@ -11103,12 +11158,12 @@ function wallManifestFor(repoDir, tree, task, env = process.env) {
11103
11158
  return null;
11104
11159
  const low = task.toLowerCase().replace(/\\/g, "/");
11105
11160
  const token = (n2) => new RegExp(`(?<![A-Za-z0-9_])${n2.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![A-Za-z0-9_])`).test(low);
11106
- const dirModule = (e) => /^(index|__init__|mod|main)\.[^.]+$/.test(basename14(e.path)) && e.path.includes("/") && token(dirname14(e.path));
11107
- const matched = all.filter((e) => SOURCE.test(e.path) && (token(basename14(e.path)) || token(e.path) || token(basename14(e.path).replace(/\.[^.]*$/, "")) || dirModule(e)));
11161
+ const dirModule = (e) => /^(index|__init__|mod|main)\.[^.]+$/.test(basename15(e.path)) && e.path.includes("/") && token(dirname14(e.path));
11162
+ const matched = all.filter((e) => SOURCE.test(e.path) && (token(basename15(e.path)) || token(e.path) || token(basename15(e.path).replace(/\.[^.]*$/, "")) || dirModule(e)));
11108
11163
  const spans = (p) => [...low.matchAll(new RegExp(`(?<![A-Za-z0-9_])${p.toLowerCase().replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![A-Za-z0-9_])`, "g"))].map((m) => [m.index, m.index + m[0].length]);
11109
11164
  const occ = new Map(matched.map((e) => [e, spans(e.path)]));
11110
11165
  const exact = (e) => occ.get(e).some(([s, t]) => !matched.some((o) => o !== e && o.path.length > e.path.length && occ.get(o).some(([s2, t2]) => s2 <= s && t <= t2)));
11111
- const byPath2 = matched.filter(exact).sort((a, b) => b.path.length - a.path.length), byBase = matched.filter((e) => !byPath2.includes(e) && token(basename14(e.path)));
11166
+ const byPath2 = matched.filter(exact).sort((a, b) => b.path.length - a.path.length), byBase = matched.filter((e) => !byPath2.includes(e) && token(basename15(e.path)));
11112
11167
  const named = [...byPath2, ...byBase, ...matched.filter((e) => !byPath2.includes(e) && !byBase.includes(e))].slice(0, MAX_NAMED);
11113
11168
  const tests = all.filter((e) => TESTISH.test(e.path)).slice(0, MAX_FILES), listed = tests.filter((e) => !SOURCE.test(e.path));
11114
11169
  const want = [...new Set([...all.filter((e) => CONFIG.test(e.path)), ...tests.filter((e) => SOURCE.test(e.path)), ...named])];
@@ -11165,9 +11220,9 @@ Example: test('name', () => { assert.strictEqual(fn(1), 2); }); Run: node --tes
11165
11220
 
11166
11221
  // ../../loki-ts/src/util/holdout.ts
11167
11222
  import { createHash as createHash12 } from "crypto";
11168
- import { appendFileSync as appendFileSync3, copyFileSync as copyFileSync2, existsSync as existsSync26, mkdirSync as mkdirSync17, readFileSync as readFileSync33, rmSync as rmSync12, writeFileSync as writeFileSync20 } from "fs";
11223
+ import { appendFileSync as appendFileSync3, copyFileSync as copyFileSync2, existsSync as existsSync27, mkdirSync as mkdirSync17, readFileSync as readFileSync34, rmSync as rmSync12, writeFileSync as writeFileSync20 } from "fs";
11169
11224
  import { tmpdir as tmpdir6 } from "os";
11170
- import { basename as basename15, join as join42, relative as relative3 } from "path";
11225
+ import { basename as basename16, join as join43, relative as relative4 } from "path";
11171
11226
  function wallHoldoutRatio(env = process.env) {
11172
11227
  if (env["LOKI_WALL_HOLDOUT"]?.trim() === "0")
11173
11228
  return 0;
@@ -11195,32 +11250,32 @@ function stashHoldout(o) {
11195
11250
  rmSync12(dir, { recursive: true, force: true });
11196
11251
  mkdirSync17(dir, { recursive: true, mode: 448 });
11197
11252
  const files = held.map((name) => {
11198
- copyFileSync2(join42(o.srcDir, name), join42(dir, name));
11199
- rmSync12(join42(o.srcDir, name), { force: true });
11200
- return { name, runner: o.runnerOf(name), sha256: sha2(readFileSync33(join42(dir, name), "utf8")) };
11253
+ copyFileSync2(join43(o.srcDir, name), join43(dir, name));
11254
+ rmSync12(join43(o.srcDir, name), { force: true });
11255
+ return { name, runner: o.runnerOf(name), sha256: sha2(readFileSync34(join43(dir, name), "utf8")) };
11201
11256
  });
11202
- writeFileSync20(join42(dir, MANIFEST), JSON.stringify({ targetDir: o.targetDir, files }));
11257
+ writeFileSync20(join43(dir, MANIFEST), JSON.stringify({ targetDir: o.targetDir, files }));
11203
11258
  return { dir, names: new Set(held) };
11204
11259
  }
11205
11260
  function stageHoldout(dir, repoDir) {
11206
11261
  const put = [], tests = [], missing = [];
11207
11262
  let man = null;
11208
11263
  try {
11209
- man = JSON.parse(readFileSync33(join42(dir, MANIFEST), "utf8"));
11264
+ man = JSON.parse(readFileSync34(join43(dir, MANIFEST), "utf8"));
11210
11265
  } catch {}
11211
11266
  if (!man)
11212
- return { tests, missing: [`holdout store unreadable: ${basename15(dir)}`], cleanup: () => {} };
11267
+ return { tests, missing: [`holdout store unreadable: ${basename16(dir)}`], cleanup: () => {} };
11213
11268
  mkdirSync17(man.targetDir, { recursive: true });
11214
11269
  man.files.forEach((f, i) => {
11215
- const src = join42(dir, f.name);
11216
- if (!existsSync26(src) || sha2(readFileSync33(src, "utf8")) !== f.sha256) {
11270
+ const src = join43(dir, f.name);
11271
+ if (!existsSync27(src) || sha2(readFileSync34(src, "utf8")) !== f.sha256) {
11217
11272
  missing.push(`holdout ${i + 1} missing or altered`);
11218
11273
  return;
11219
11274
  }
11220
- const dest = join42(man.targetDir, `loki_wall_holdout_${i + 1}${f.name.slice(f.name.indexOf("."))}`);
11275
+ const dest = join43(man.targetDir, `loki_wall_holdout_${i + 1}${f.name.slice(f.name.indexOf("."))}`);
11221
11276
  copyFileSync2(src, dest);
11222
11277
  put.push(dest);
11223
- tests.push({ runner: f.runner, path: relative3(repoDir, dest) });
11278
+ tests.push({ runner: f.runner, path: relative4(repoDir, dest) });
11224
11279
  });
11225
11280
  return { tests, missing, cleanup: () => {
11226
11281
  for (const p of put)
@@ -11230,16 +11285,16 @@ function stageHoldout(dir, repoDir) {
11230
11285
  function recordHoldoutTriage(runDir, entry) {
11231
11286
  try {
11232
11287
  mkdirSync17(runDir, { recursive: true });
11233
- appendFileSync3(join42(runDir, HOLDOUT_TRIAGE_FILE), JSON.stringify(entry) + `
11288
+ appendFileSync3(join43(runDir, HOLDOUT_TRIAGE_FILE), JSON.stringify(entry) + `
11234
11289
  `, { mode: 384 });
11235
11290
  } catch {}
11236
11291
  }
11237
- var sha2 = (s) => createHash12("sha256").update(s).digest("hex"), WALL_HOLDOUT_DEFAULT_RATIO = 0.2, isHoldoutCheck = (name) => name.startsWith("holdout:"), holdoutDirFor = (runId, repoDir) => join42(tmpdir6(), `loki-e10-holdout-${sha2(`${runId}:${repoDir}`).slice(0, 16)}`), MANIFEST = "manifest.json", WALL_HOLDOUT_MIN = 5, HOLDOUT_TRIAGE_FILE = "holdout-triage.jsonl";
11292
+ var sha2 = (s) => createHash12("sha256").update(s).digest("hex"), WALL_HOLDOUT_DEFAULT_RATIO = 0.2, isHoldoutCheck = (name) => name.startsWith("holdout:"), holdoutDirFor = (runId, repoDir) => join43(tmpdir6(), `loki-e10-holdout-${sha2(`${runId}:${repoDir}`).slice(0, 16)}`), MANIFEST = "manifest.json", WALL_HOLDOUT_MIN = 5, HOLDOUT_TRIAGE_FILE = "holdout-triage.jsonl";
11238
11293
  var init_holdout = () => {};
11239
11294
 
11240
11295
  // ../../loki-ts/src/features/runner_config.ts
11241
- import { readFileSync as readFileSync34 } from "fs";
11242
- import { dirname as dirname15, join as join43, normalize as normalize2 } from "path";
11296
+ import { readFileSync as readFileSync35 } from "fs";
11297
+ import { dirname as dirname15, join as join44, normalize as normalize2 } from "path";
11243
11298
  function tomlKey2(s, i = 0, eq2 = true) {
11244
11299
  const parts = [], ws = () => {
11245
11300
  while (/\s/.test(s[i] ?? "x"))
@@ -11516,8 +11571,8 @@ function referenced(cfg, text2) {
11516
11571
  }
11517
11572
  const dir = dirname15(cfg), explicit = ROOT_DIR.exec(text2), roots = [dir];
11518
11573
  if (explicit)
11519
- roots.push("", ...explicit[1] ? [join43(dir, explicit[1])] : []);
11520
- return [...raw2.flatMap((r) => r.startsWith("/") ? [normalize2(r.slice(1))] : roots.map((root) => normalize2(join43(root, r.replace(/^<rootDir>\/?/, ""))))), ...patchedTargets(cfg, text2).map((t) => normalize2(join43(dir, t)))];
11574
+ roots.push("", ...explicit[1] ? [join44(dir, explicit[1])] : []);
11575
+ return [...raw2.flatMap((r) => r.startsWith("/") ? [normalize2(r.slice(1))] : roots.map((root) => normalize2(join44(root, r.replace(/^<rootDir>\/?/, ""))))), ...patchedTargets(cfg, text2).map((t) => normalize2(join44(dir, t)))];
11521
11576
  }
11522
11577
  function runnerConfigNotes(repoDir, baseSha, head, changed, signal) {
11523
11578
  const notes = new Set, ch = new Set(changed.map((c) => normalize2(c)));
@@ -11597,7 +11652,7 @@ var PKG_KEYS, RAW_CONFIGS, RUNNER_CONFIGS, DEP_MAPS, RUNNER_DEP, LOCAL_SPEC, dep
11597
11652
  }
11598
11653
  }, headText = (dir, f) => {
11599
11654
  try {
11600
- return readFileSync34(join43(dir, f), "utf8");
11655
+ return readFileSync35(join44(dir, f), "utf8");
11601
11656
  } catch {
11602
11657
  return "";
11603
11658
  }
@@ -11637,19 +11692,19 @@ var init_runner_config = __esm(() => {
11637
11692
 
11638
11693
  // ../../loki-ts/src/e10ext/assert_delta.ts
11639
11694
  import { execFileSync as execFileSync3 } from "child_process";
11640
- import { mkdtempSync as mkdtempSync5, readFileSync as readFileSync35, rmSync as rmSync13 } from "fs";
11695
+ import { mkdtempSync as mkdtempSync5, readFileSync as readFileSync36, rmSync as rmSync13 } from "fs";
11641
11696
  import { tmpdir as tmpdir7 } from "os";
11642
- import { join as join44 } from "path";
11643
- import { basename as basename16 } from "path";
11697
+ import { join as join45 } from "path";
11698
+ import { basename as basename17 } from "path";
11644
11699
  function classifyAssertDelta(inp) {
11645
- const f = basename16(inp.path);
11700
+ const f = basename17(inp.path);
11646
11701
  if (!/^(test_.*|.*_test)\.py$/.test(f))
11647
11702
  return WEAKENED;
11648
11703
  if (inp.headCounts.run !== inp.baseCounts.run || inp.headCounts.skipped !== inp.baseCounts.skipped)
11649
11704
  return WEAKENED;
11650
11705
  let cwd = "";
11651
11706
  try {
11652
- cwd = mkdtempSync5(join44(tmpdir7(), "loki-ad-"));
11707
+ cwd = mkdtempSync5(join45(tmpdir7(), "loki-ad-"));
11653
11708
  const raw2 = execFileSync3("python3", ["-I", "-c", PY], {
11654
11709
  input: JSON.stringify({ path: inp.path, base: inp.base, head: inp.head, task: inp.task }),
11655
11710
  cwd,
@@ -11680,7 +11735,7 @@ function assertDeltaNotes(repoDir, baseSha, headRef, path, task, baseCounts, hea
11680
11735
  return null;
11681
11736
  try {
11682
11737
  const show = (ref) => safeGit(repoDir, ["show", `${ref}:${path}`]);
11683
- const head = headRef ? show(headRef) : readFileSync35(join44(repoDir, path), "utf8");
11738
+ const head = headRef ? show(headRef) : readFileSync36(join45(repoDir, path), "utf8");
11684
11739
  const r = classifyTestEdit(path, show(baseSha), head, task, baseCounts, headCounts);
11685
11740
  return r[0]?.kind === "literal-only" ? r.map((e) => `assertion value changed (not shown to be required by the task): ${e.file}:${e.line} ${e.old} -> ${e.new}`) : null;
11686
11741
  } catch {
@@ -11887,19 +11942,19 @@ var init_runner_errors = __esm(() => {
11887
11942
 
11888
11943
  // ../../loki-ts/src/runner/load_owner.ts
11889
11944
  import { spawnSync as spawnSync3 } from "child_process";
11890
- import { mkdtempSync as mkdtempSync6, realpathSync as realpathSync17, rmSync as rmSync14 } from "fs";
11945
+ import { mkdtempSync as mkdtempSync6, realpathSync as realpathSync18, rmSync as rmSync14 } from "fs";
11891
11946
  import { tmpdir as tmpdir8 } from "os";
11892
- import { basename as basename17, extname, join as join45 } from "path";
11947
+ import { basename as basename18, extname as extname2, join as join46 } from "path";
11893
11948
  function changedFilesNamed(out2, repoDir, changed) {
11894
11949
  return changed.filter((f) => {
11895
- if (out2.includes(f) || out2.includes(join45(repoDir, f)))
11950
+ if (out2.includes(f) || out2.includes(join46(repoDir, f)))
11896
11951
  return true;
11897
11952
  const segs = f.split("/");
11898
11953
  if (suffixes(segs, 2).some((x) => x !== f && bounded(out2, x, "(?![\\w-])")))
11899
11954
  return true;
11900
- if (extname(f) === ".go" && segs.length > 1 && suffixes(segs.slice(0, -1), 1).some((d) => new RegExp(`(?<=[\\w-])/${esc(d)}(?![\\w./-])`).test(out2)))
11955
+ if (extname2(f) === ".go" && segs.length > 1 && suffixes(segs.slice(0, -1), 1).some((d) => new RegExp(`(?<=[\\w-])/${esc(d)}(?![\\w./-])`).test(out2)))
11901
11956
  return true;
11902
- const stem = basename17(f, extname(f));
11957
+ const stem = basename18(f, extname2(f));
11903
11958
  if (stem.length < 2 || stem === "index" || stem === "__init__")
11904
11959
  return false;
11905
11960
  return new RegExp(`(?<![\\w-])${esc(stem)}(?![\\w-])`).test(out2);
@@ -11909,7 +11964,7 @@ function loadSignature(out2, roots) {
11909
11964
  let o = out2;
11910
11965
  for (const r of roots.flatMap((x) => {
11911
11966
  try {
11912
- return [x, realpathSync17(x)];
11967
+ return [x, realpathSync18(x)];
11913
11968
  } catch {
11914
11969
  return [x];
11915
11970
  }
@@ -12003,7 +12058,7 @@ async function loadErrorIsHarnessOwned(i) {
12003
12058
  return false;
12004
12059
  if (i.args.some((a) => changed.includes(a.replace(/^\.\//, ""))))
12005
12060
  return false;
12006
- const dir = mkdtempSync6(join45(tmpdir8(), "e10-loadown-"));
12061
+ const dir = mkdtempSync6(join46(tmpdir8(), "e10-loadown-"));
12007
12062
  const git3 = (args) => {
12008
12063
  safeGit(i.repoDir, args, { stdio: "ignore" });
12009
12064
  };
@@ -12035,7 +12090,7 @@ var init_load_owner = __esm(() => {
12035
12090
  });
12036
12091
 
12037
12092
  // ../../loki-ts/src/util/wall_owned.ts
12038
- import { isAbsolute as isAbsolute5, join as join46, relative as relative4 } from "path";
12093
+ import { isAbsolute as isAbsolute6, join as join47, relative as relative5 } from "path";
12039
12094
  function failingLocations(raw2, cwd, repoDir) {
12040
12095
  const out2 = raw2.replace(ANSI2, "").replace(/\r\n?/g, `
12041
12096
  `), files = new Set;
@@ -12067,7 +12122,7 @@ function failingLocations(raw2, cwd, repoDir) {
12067
12122
  }
12068
12123
  if (errors2 === 0 || located !== errors2)
12069
12124
  return null;
12070
- return [...files].map((f) => relative4(repoDir, isAbsolute5(f) ? f : join46(cwd, f)));
12125
+ return [...files].map((f) => relative5(repoDir, isAbsolute6(f) ? f : join47(cwd, f)));
12071
12126
  }
12072
12127
  function wallOwnedFailure(raw2, cwd, repoDir, wall) {
12073
12128
  const locs = failingLocations(raw2, cwd, repoDir);
@@ -12081,21 +12136,21 @@ var init_wall_owned = __esm(() => {
12081
12136
  // ../../loki-ts/src/project_graph.ts
12082
12137
  import { createHash as createHash13 } from "crypto";
12083
12138
  import {
12084
- existsSync as existsSync27,
12085
- readdirSync as readdirSync15,
12086
- readFileSync as readFileSync36,
12139
+ existsSync as existsSync28,
12140
+ readdirSync as readdirSync16,
12141
+ readFileSync as readFileSync37,
12087
12142
  statSync as statSync17,
12088
12143
  writeFileSync as writeFileSync21,
12089
12144
  mkdirSync as mkdirSync18
12090
12145
  } from "fs";
12091
- import { basename as basename18, dirname as dirname16, join as join47, resolve as resolve14 } from "path";
12146
+ import { basename as basename19, dirname as dirname16, join as join48, resolve as resolve14 } from "path";
12092
12147
  function readManifest(path) {
12093
- if (!existsSync27(path)) {
12148
+ if (!existsSync28(path)) {
12094
12149
  return null;
12095
12150
  }
12096
12151
  let raw2;
12097
12152
  try {
12098
- raw2 = readFileSync36(path, "utf8");
12153
+ raw2 = readFileSync37(path, "utf8");
12099
12154
  } catch {
12100
12155
  return null;
12101
12156
  }
@@ -12132,7 +12187,7 @@ function resolveMembers(rootDir, declared, selfBasename) {
12132
12187
  const seen = new Set;
12133
12188
  let children;
12134
12189
  try {
12135
- children = readdirSync15(rootDir);
12190
+ children = readdirSync16(rootDir);
12136
12191
  } catch {
12137
12192
  children = [];
12138
12193
  }
@@ -12147,7 +12202,7 @@ function resolveMembers(rootDir, declared, selfBasename) {
12147
12202
  for (const child of children) {
12148
12203
  if (!matchPattern(name, child))
12149
12204
  continue;
12150
- const full = join47(rootDir, child);
12205
+ const full = join48(rootDir, child);
12151
12206
  if (seen.has(full))
12152
12207
  continue;
12153
12208
  let st;
@@ -12164,7 +12219,7 @@ function resolveMembers(rootDir, declared, selfBasename) {
12164
12219
  }
12165
12220
  if (declared.length === 0) {
12166
12221
  for (const child of children) {
12167
- const full = join47(rootDir, child);
12222
+ const full = join48(rootDir, child);
12168
12223
  if (seen.has(full))
12169
12224
  continue;
12170
12225
  let st;
@@ -12175,7 +12230,7 @@ function resolveMembers(rootDir, declared, selfBasename) {
12175
12230
  }
12176
12231
  if (!st.isDirectory())
12177
12232
  continue;
12178
- if (!existsSync27(join47(full, ".loki", "app.json")))
12233
+ if (!existsSync28(join48(full, ".loki", "app.json")))
12179
12234
  continue;
12180
12235
  seen.add(full);
12181
12236
  out2.push(full);
@@ -12196,26 +12251,26 @@ function cacheKey(manifestPaths) {
12196
12251
  }
12197
12252
  function writeCache(targetDir, key, result) {
12198
12253
  try {
12199
- const cacheDir = join47(targetDir, ".loki", "state");
12254
+ const cacheDir = join48(targetDir, ".loki", "state");
12200
12255
  mkdirSync18(cacheDir, { recursive: true });
12201
- const cachePath = join47(cacheDir, "project-graph.json");
12256
+ const cachePath = join48(cacheDir, "project-graph.json");
12202
12257
  writeFileSync21(cachePath, JSON.stringify({ key, result }, null, 2), "utf8");
12203
12258
  } catch {}
12204
12259
  }
12205
12260
  function discoverProjectGraph(targetDir) {
12206
12261
  const absTarget = resolve14(targetDir);
12207
- const targetManifest = join47(absTarget, ".loki", "app.json");
12262
+ const targetManifest = join48(absTarget, ".loki", "app.json");
12208
12263
  const parentDir = dirname16(absTarget);
12209
- const parentManifest = join47(parentDir, ".loki", "app.json");
12264
+ const parentManifest = join48(parentDir, ".loki", "app.json");
12210
12265
  const examined = [];
12211
12266
  let chosenManifest = null;
12212
12267
  let chosenRoot = "";
12213
- if (existsSync27(parentManifest) && parentDir !== absTarget) {
12268
+ if (existsSync28(parentManifest) && parentDir !== absTarget) {
12214
12269
  examined.push(parentManifest);
12215
12270
  chosenManifest = readManifest(parentManifest);
12216
12271
  chosenRoot = parentDir;
12217
12272
  }
12218
- if (!chosenManifest && existsSync27(targetManifest)) {
12273
+ if (!chosenManifest && existsSync28(targetManifest)) {
12219
12274
  examined.push(targetManifest);
12220
12275
  chosenManifest = readManifest(targetManifest);
12221
12276
  chosenRoot = absTarget;
@@ -12223,11 +12278,11 @@ function discoverProjectGraph(targetDir) {
12223
12278
  if (!chosenManifest)
12224
12279
  return null;
12225
12280
  const declared = chosenManifest.members ?? [];
12226
- const members = resolveMembers(chosenRoot, declared, basename18(absTarget));
12281
+ const members = resolveMembers(chosenRoot, declared, basename19(absTarget));
12227
12282
  const filtered = [];
12228
12283
  for (const m of members) {
12229
- const sibManifestPath = join47(m, ".loki", "app.json");
12230
- if (existsSync27(sibManifestPath)) {
12284
+ const sibManifestPath = join48(m, ".loki", "app.json");
12285
+ if (existsSync28(sibManifestPath)) {
12231
12286
  examined.push(sibManifestPath);
12232
12287
  const sibManifest = readManifest(sibManifestPath);
12233
12288
  if (sibManifest && sibManifest.app_id !== chosenManifest.app_id) {
@@ -12355,9 +12410,9 @@ var init_route_block = __esm(() => {
12355
12410
  // ../../loki-ts/src/features/visual_evidence.ts
12356
12411
  import { spawn as spawn7 } from "child_process";
12357
12412
  import { createHash as createHash14, randomBytes as randomBytes5 } from "crypto";
12358
- import { existsSync as existsSync28, lstatSync as lstatSync10, mkdirSync as mkdirSync19, readdirSync as readdirSync16, readFileSync as readFileSync37, writeFileSync as writeFileSync22 } from "fs";
12413
+ import { existsSync as existsSync29, lstatSync as lstatSync10, mkdirSync as mkdirSync19, readdirSync as readdirSync17, readFileSync as readFileSync38, writeFileSync as writeFileSync22 } from "fs";
12359
12414
  import { createServer } from "net";
12360
- import { dirname as dirname17, isAbsolute as isAbsolute6, join as join48, normalize as normalize3, relative as relative5, sep as sep10 } from "path";
12415
+ import { dirname as dirname17, isAbsolute as isAbsolute7, join as join49, normalize as normalize3, relative as relative6, sep as sep11 } from "path";
12361
12416
  function routeFor(file) {
12362
12417
  let r = file.replace(/^(?:.*?\/)?(?:app|pages|src|public)\//, "").replace(/^(?:routes|pages)\//, "");
12363
12418
  r = r.replace(/\.(?:html|jsx|tsx|vue|svelte)$/, "").replace(/\/?(?:page|index|\+page)$/, "");
@@ -12367,7 +12422,7 @@ function hashScreens(runDir, rels) {
12367
12422
  const out2 = [];
12368
12423
  for (const rel of rels) {
12369
12424
  try {
12370
- out2.push({ path: rel, sha256: sha256File(join48(runDir, rel)) });
12425
+ out2.push({ path: rel, sha256: sha256File(join49(runDir, rel)) });
12371
12426
  } catch {}
12372
12427
  }
12373
12428
  return out2;
@@ -12378,16 +12433,16 @@ function checkScreens(runDir, screens) {
12378
12433
  for (const s of screens) {
12379
12434
  if (typeof s?.path !== "string" || typeof s.sha256 !== "string")
12380
12435
  return "evidence_screens entry is malformed";
12381
- if (isAbsolute6(s.path) || normalize3(s.path).startsWith(".."))
12436
+ if (isAbsolute7(s.path) || normalize3(s.path).startsWith(".."))
12382
12437
  return `evidence screenshot path escapes the evidence dir: ${s.path}`;
12383
- const file = join48(runDir, s.path);
12438
+ const file = join49(runDir, s.path);
12384
12439
  let cur = runDir;
12385
- for (const seg of normalize3(s.path).split(sep10)) {
12386
- cur = join48(cur, seg);
12440
+ for (const seg of normalize3(s.path).split(sep11)) {
12441
+ cur = join49(cur, seg);
12387
12442
  if (isSymlink(cur))
12388
12443
  return `evidence screenshot path is a symlink: ${s.path}`;
12389
12444
  }
12390
- if (!existsSync28(file))
12445
+ if (!existsSync29(file))
12391
12446
  return `evidence screenshot is missing: ${s.path}`;
12392
12447
  if (!isRegularFile(file))
12393
12448
  return `evidence screenshot is not a regular file: ${s.path}`;
@@ -12430,11 +12485,11 @@ async function waitUp(url, ms, signal) {
12430
12485
  }
12431
12486
  function openapiPaths(repoDir) {
12432
12487
  for (const f of ["openapi.json", "openapi.yaml", "openapi.yml", "swagger.json"]) {
12433
- const p = join48(repoDir, f);
12434
- if (!existsSync28(p))
12488
+ const p = join49(repoDir, f);
12489
+ if (!existsSync29(p))
12435
12490
  continue;
12436
12491
  try {
12437
- const txt = readFileSync37(p, "utf8");
12492
+ const txt = readFileSync38(p, "utf8");
12438
12493
  const paths = f.endsWith(".json") ? Object.keys(JSON.parse(txt).paths ?? {}) : [...txt.matchAll(/^ {2}(\/[^\s:]*):\s*$/gm)].map((m) => m[1]);
12439
12494
  return paths.filter((x) => !x.includes("{")).slice(0, 10);
12440
12495
  } catch {
@@ -12448,24 +12503,24 @@ async function recordE2eMedia(repoDir, runDir, relDir, base, routes, ms, signal)
12448
12503
  if (!pw || !pkg)
12449
12504
  return { rels: [], skipped: "playwright e2e video and trace skipped: @playwright/test is not installed in the repo" };
12450
12505
  try {
12451
- const dir = join48(runDir, relDir, "e2e");
12506
+ const dir = join49(runDir, relDir, "e2e");
12452
12507
  mkdirSync19(dir, { recursive: true });
12453
- writeFileSync22(join48(dir, "walk.spec.cjs"), e2eSpecSource(pkg, base, routes));
12454
- writeFileSync22(join48(dir, "playwright.config.cjs"), `module.exports = { testDir: ".", testMatch: "walk.spec.cjs", outputDir: "./out", reporter: "null", use: { video: "on", trace: "on" } };
12508
+ writeFileSync22(join49(dir, "walk.spec.cjs"), e2eSpecSource(pkg, base, routes));
12509
+ writeFileSync22(join49(dir, "playwright.config.cjs"), `module.exports = { testDir: ".", testMatch: "walk.spec.cjs", outputDir: "./out", reporter: "null", use: { video: "on", trace: "on" } };
12455
12510
  `);
12456
- if (!await shoot(pw, ["test", "--config", join48(dir, "playwright.config.cjs")], repoDir, ms, signal))
12511
+ if (!await shoot(pw, ["test", "--config", join49(dir, "playwright.config.cjs")], repoDir, ms, signal))
12457
12512
  return { rels: [], skipped: "playwright e2e video and trace skipped: the run failed or timed out" };
12458
12513
  const rels = [];
12459
12514
  const walk = (d) => {
12460
- for (const e of readdirSync16(d, { withFileTypes: true })) {
12461
- const full = join48(d, e.name);
12515
+ for (const e of readdirSync17(d, { withFileTypes: true })) {
12516
+ const full = join49(d, e.name);
12462
12517
  if (e.isDirectory())
12463
12518
  walk(full);
12464
12519
  else if (e.isFile() && /\.(webm|zip)$/.test(e.name))
12465
- rels.push(join48(relDir, "e2e", relative5(dir, full)));
12520
+ rels.push(join49(relDir, "e2e", relative6(dir, full)));
12466
12521
  }
12467
12522
  };
12468
- walk(join48(dir, "out"));
12523
+ walk(join49(dir, "out"));
12469
12524
  return rels.length > 0 ? { rels, skipped: null } : { rels, skipped: "playwright e2e video and trace skipped: no video or trace was produced" };
12470
12525
  } catch (e) {
12471
12526
  return { rels: [], skipped: `playwright e2e video and trace skipped: ${String(e?.message ?? e).slice(0, 120)}` };
@@ -12544,22 +12599,22 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
12544
12599
  if (!visualEvidenceEnabled(opts.env))
12545
12600
  return skip("LOKI_VISUAL_EVIDENCE is 0");
12546
12601
  const api = loadProjectApi(repoDir), boot = isMultiRoot(api) ? api.uiBoot() : null;
12547
- const appDir = boot ? join48(repoDir, boot.boot.cwd) : repoDir;
12548
- const pkgPath = join48(appDir, "package.json");
12602
+ const appDir = boot ? join49(repoDir, boot.boot.cwd) : repoDir;
12603
+ const pkgPath = join49(appDir, "package.json");
12549
12604
  let script = null;
12550
12605
  if (!boot) {
12551
- if (!existsSync28(pkgPath)) {
12552
- const subs = ["backend", "frontend"].filter((d) => existsSync28(join48(repoDir, d, "package.json")));
12606
+ if (!existsSync29(pkgPath)) {
12607
+ const subs = ["backend", "frontend"].filter((d) => existsSync29(join49(repoDir, d, "package.json")));
12553
12608
  const has = (d) => {
12554
12609
  try {
12555
- return pickScript(JSON.parse(readFileSync37(join48(repoDir, d, "package.json"), "utf8"))) !== null;
12610
+ return pickScript(JSON.parse(readFileSync38(join49(repoDir, d, "package.json"), "utf8"))) !== null;
12556
12611
  } catch {
12557
12612
  return false;
12558
12613
  }
12559
12614
  };
12560
12615
  return skip(noRootReason(subs, subs.filter((d) => !has(d))));
12561
12616
  }
12562
- script = pickScript(JSON.parse(readFileSync37(pkgPath, "utf8")));
12617
+ script = pickScript(JSON.parse(readFileSync38(pkgPath, "utf8")));
12563
12618
  if (!script)
12564
12619
  return skip("no dev, preview or start script");
12565
12620
  }
@@ -12586,20 +12641,20 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
12586
12641
  }
12587
12642
  if (!await waitUp(base, left(), signal))
12588
12643
  return skip(aborted() ? "aborted" : `${script} server did not answer within ${Math.round(budget / 1000)}s`);
12589
- const evRoot = join48(runDir, "evidence");
12644
+ const evRoot = join49(runDir, "evidence");
12590
12645
  if (isSymlink(evRoot))
12591
12646
  return skip("evidence dir is a symlink");
12592
12647
  mkdirSync19(evRoot, { recursive: true });
12593
12648
  if (pages.length > 0) {
12594
- const rel0 = join48("evidence", randomBytes5(6).toString("hex"));
12595
- mkdirSync19(join48(runDir, rel0));
12649
+ const rel0 = join49("evidence", randomBytes5(6).toString("hex"));
12650
+ mkdirSync19(join49(runDir, rel0));
12596
12651
  const rels = [];
12597
12652
  for (const route of [...new Set(pages.map(routeFor))].slice(0, opts.maxRoutes ?? MAX_ROUTES)) {
12598
12653
  if (aborted() || left() <= 0)
12599
12654
  break;
12600
- const rel = join48(rel0, `${screenName(route)}.png`);
12601
- const ok = await shoot(pw, ["screenshot", `${base}${route}`, join48(runDir, rel)], appDir, left(), signal);
12602
- if (ok && !aborted() && !isSymlink(join48(runDir, rel)) && existsSync28(join48(runDir, rel)))
12655
+ const rel = join49(rel0, `${screenName(route)}.png`);
12656
+ const ok = await shoot(pw, ["screenshot", `${base}${route}`, join49(runDir, rel)], appDir, left(), signal);
12657
+ if (ok && !aborted() && !isSymlink(join49(runDir, rel)) && existsSync29(join49(runDir, rel)))
12603
12658
  rels.push(rel);
12604
12659
  }
12605
12660
  if (aborted())
@@ -12624,9 +12679,9 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
12624
12679
  }
12625
12680
  if (aborted())
12626
12681
  return skip("aborted");
12627
- const hdir = join48(evRoot, randomBytes5(6).toString("hex"));
12682
+ const hdir = join49(evRoot, randomBytes5(6).toString("hex"));
12628
12683
  mkdirSync19(hdir);
12629
- writeFileSync22(join48(hdir, "http.json"), JSON.stringify(rows, null, 2) + `
12684
+ writeFileSync22(join49(hdir, "http.json"), JSON.stringify(rows, null, 2) + `
12630
12685
  `);
12631
12686
  return { screens: [], http: true, skipped: null };
12632
12687
  } catch (e) {
@@ -12655,12 +12710,12 @@ function receiptScreensProblem(receiptPath, receipt) {
12655
12710
  return `visual evidence failed (LOKI_VISUAL_GATE=1): ${receipt["evidence_failed"]}`;
12656
12711
  return receipt["evidence_screens"] === undefined ? null : checkScreens(dirname17(receiptPath), receipt["evidence_screens"]);
12657
12712
  }
12658
- var visualEvidenceEnabled = (env = process.env) => env["LOKI_VISUAL_EVIDENCE"] !== "0", visualGateEnabled = (env = process.env) => env["LOKI_VISUAL_GATE"] === "1", PAGE_RE, isPageFile = (p) => PAGE_RE.test(p), screenName = (route) => (route === "/" ? "index" : route.slice(1).replace(/[^A-Za-z0-9._-]+/g, "_")) || "index", sha256File = (p) => createHash14("sha256").update(readFileSync37(p)).digest("hex"), playwrightBin = (repoDir) => {
12659
- const bin = join48(repoDir, "node_modules", ".bin", "playwright");
12660
- return existsSync28(bin) ? bin : null;
12713
+ var visualEvidenceEnabled = (env = process.env) => env["LOKI_VISUAL_EVIDENCE"] !== "0", visualGateEnabled = (env = process.env) => env["LOKI_VISUAL_GATE"] === "1", PAGE_RE, isPageFile = (p) => PAGE_RE.test(p), screenName = (route) => (route === "/" ? "index" : route.slice(1).replace(/[^A-Za-z0-9._-]+/g, "_")) || "index", sha256File = (p) => createHash14("sha256").update(readFileSync38(p)).digest("hex"), playwrightBin = (repoDir) => {
12714
+ const bin = join49(repoDir, "node_modules", ".bin", "playwright");
12715
+ return existsSync29(bin) ? bin : null;
12661
12716
  }, playwrightTestPkg = (repoDir) => {
12662
- const d = join48(repoDir, "node_modules", "@playwright", "test");
12663
- return existsSync28(join48(d, "package.json")) ? d : null;
12717
+ const d = join49(repoDir, "node_modules", "@playwright", "test");
12718
+ return existsSync29(join49(d, "package.json")) ? d : null;
12664
12719
  }, e2eSpecSource = (pkgDir, base, routes) => `const { test } = require(${JSON.stringify(pkgDir)});
12665
12720
  test("loki e2e walkthrough", async ({ page }) => {
12666
12721
  for (const r of ${JSON.stringify(routes)}) { await page.goto(${JSON.stringify(base)} + r); await page.waitForLoadState("load"); }
@@ -12703,7 +12758,7 @@ var init_outbox = __esm(() => {
12703
12758
  });
12704
12759
 
12705
12760
  // ../../loki-ts/src/engine10/stages/pr.ts
12706
- import { join as join49 } from "path";
12761
+ import { join as join50 } from "path";
12707
12762
  var DEFAULT_PUSH_SH;
12708
12763
  var init_pr = __esm(() => {
12709
12764
  init_types();
@@ -12720,19 +12775,19 @@ var init_pr = __esm(() => {
12720
12775
  init_run_outputs();
12721
12776
  init_yaml_key();
12722
12777
  init_outbox();
12723
- DEFAULT_PUSH_SH = join49(REPO_ROOT, "autonomy/lib/engine10-push.sh");
12778
+ DEFAULT_PUSH_SH = join50(REPO_ROOT, "autonomy/lib/engine10-push.sh");
12724
12779
  });
12725
12780
 
12726
12781
  // ../../loki-ts/src/util/pr_lessons.ts
12727
- import { existsSync as existsSync29, mkdirSync as mkdirSync20, mkdtempSync as mkdtempSync7, readFileSync as readFileSync38, rmSync as rmSync15, writeFileSync as writeFileSync23 } from "fs";
12728
- import { dirname as dirname18, join as join50 } from "path";
12782
+ import { existsSync as existsSync30, mkdirSync as mkdirSync20, mkdtempSync as mkdtempSync7, readFileSync as readFileSync39, rmSync as rmSync15, writeFileSync as writeFileSync23 } from "fs";
12783
+ import { dirname as dirname18, join as join51 } from "path";
12729
12784
  import { createHash as createHash15 } from "crypto";
12730
12785
  function loadLessons(repoDir) {
12731
12786
  const p = lessonsPath(repoDir);
12732
- if (!existsSync29(p))
12787
+ if (!existsSync30(p))
12733
12788
  return [];
12734
12789
  try {
12735
- const j = JSON.parse(readFileSync38(p, "utf-8"));
12790
+ const j = JSON.parse(readFileSync39(p, "utf-8"));
12736
12791
  return Array.isArray(j.lessons) ? j.lessons : [];
12737
12792
  } catch {
12738
12793
  return [];
@@ -12774,7 +12829,7 @@ function recordRunVerdict(repoDir, runId, verdict) {
12774
12829
  if (dirty)
12775
12830
  save(repoDir, lessons);
12776
12831
  }
12777
- var lessonsPath = (repoDir) => join50(repoDir, ".loki", "memory", "semantic", "pr-lessons.json"), KINDS;
12832
+ var lessonsPath = (repoDir) => join51(repoDir, ".loki", "memory", "semantic", "pr-lessons.json"), KINDS;
12778
12833
  var init_pr_lessons = __esm(() => {
12779
12834
  init_atomic();
12780
12835
  init_safe_git();
@@ -12806,7 +12861,7 @@ var init_attempts = __esm(() => {
12806
12861
  var init_mcp_config = () => {};
12807
12862
 
12808
12863
  // ../../loki-ts/src/providers/claude_flags.ts
12809
- import { existsSync as existsSync30, readFileSync as readFileSync39 } from "fs";
12864
+ import { existsSync as existsSync31, readFileSync as readFileSync40 } from "fs";
12810
12865
  import { resolve as resolvePath, dirname as dirname19 } from "path";
12811
12866
  import { fileURLToPath as fileURLToPath4 } from "url";
12812
12867
  function claudeFlagSupported(flag, helpText) {
@@ -12860,8 +12915,8 @@ function designArchetypesText() {
12860
12915
  ["..", "..", "references", "design-archetypes.md"]
12861
12916
  ]) {
12862
12917
  const p = resolvePath(moduleDir, ...rel);
12863
- if (existsSync30(p))
12864
- return readFileSync39(p, "utf8");
12918
+ if (existsSync31(p))
12919
+ return readFileSync40(p, "utf8");
12865
12920
  }
12866
12921
  } catch {}
12867
12922
  return "";
@@ -12945,14 +13000,14 @@ var init_providers = __esm(() => {
12945
13000
  });
12946
13001
 
12947
13002
  // ../../loki-ts/src/runner/router/route_record.ts
12948
- import { existsSync as existsSync31, lstatSync as lstatSync11, mkdirSync as mkdirSync21, readFileSync as readFileSync40, writeFileSync as writeFileSync24 } from "fs";
12949
- import { join as join51 } from "path";
13003
+ import { existsSync as existsSync32, lstatSync as lstatSync11, mkdirSync as mkdirSync21, readFileSync as readFileSync41, writeFileSync as writeFileSync24 } from "fs";
13004
+ import { join as join52 } from "path";
12950
13005
  function loadRouteRecord(runDir) {
12951
13006
  try {
12952
- const p = join51(runDir, ROUTE_RECORD_FILE);
12953
- if (!existsSync31(p) || !lstatSync11(p).isFile())
13007
+ const p = join52(runDir, ROUTE_RECORD_FILE);
13008
+ if (!existsSync32(p) || !lstatSync11(p).isFile())
12954
13009
  return;
12955
- const v = JSON.parse(readFileSync40(p, "utf8"));
13010
+ const v = JSON.parse(readFileSync41(p, "utf8"));
12956
13011
  return typeof v === "object" && v !== null && !Array.isArray(v) ? v : undefined;
12957
13012
  } catch {
12958
13013
  return;
@@ -13079,7 +13134,7 @@ var init_worker = __esm(() => {
13079
13134
  });
13080
13135
 
13081
13136
  // ../../loki-ts/src/project_model/package_suite.ts
13082
- import { join as join52 } from "path";
13137
+ import { join as join53 } from "path";
13083
13138
  async function runPackageSuites(repoDir, signal, opts, checks, notProven) {
13084
13139
  const api = loadProjectApi(repoDir);
13085
13140
  if (!isMultiRoot(api))
@@ -13090,7 +13145,7 @@ async function runPackageSuites(repoDir, signal, opts, checks, notProven) {
13090
13145
  for (const pkg of withTests) {
13091
13146
  const tc = pkg.commands.test, name = `full suite: ${pkg.name}`, cmd = `(cd ${tc.cwd} && ${tc.cmd})`;
13092
13147
  const started = Date.now();
13093
- const r = await run(["bash", "-c", tc.cmd], { cwd: join52(repoDir, tc.cwd), timeoutMs: opts.timeoutMs, ...opts.path ? { env: { PATH: opts.path } } : {} });
13148
+ const r = await run(["bash", "-c", tc.cmd], { cwd: join53(repoDir, tc.cwd), timeoutMs: opts.timeoutMs, ...opts.path ? { env: { PATH: opts.path } } : {} });
13094
13149
  const duration_s = (Date.now() - started) / 1000;
13095
13150
  if (signal.aborted) {
13096
13151
  checks.push({ name, cmd, result: "not_run", duration_s });
@@ -13099,7 +13154,7 @@ async function runPackageSuites(repoDir, signal, opts, checks, notProven) {
13099
13154
  }
13100
13155
  const out2 = `${r.stdout}
13101
13156
  ${r.stderr}`;
13102
- const lr = r.exitCode === 0 || !opts.baseSha ? undefined : await harnessLoadReason({ repoDir, baseSha: opts.baseSha, out: out2, cmd: "bash", args: ["-c", tc.cmd], signal, cwd: join52(repoDir, tc.cwd), ...opts.path ? { env: { PATH: opts.path } } : {} });
13157
+ const lr = r.exitCode === 0 || !opts.baseSha ? undefined : await harnessLoadReason({ repoDir, baseSha: opts.baseSha, out: out2, cmd: "bash", args: ["-c", tc.cmd], signal, cwd: join53(repoDir, tc.cwd), ...opts.path ? { env: { PATH: opts.path } } : {} });
13103
13158
  if (lr) {
13104
13159
  checks.push({ name, cmd, result: "not_run", duration_s });
13105
13160
  notProven.add(`${lr} (${name}; harness-owned)`);
@@ -13133,14 +13188,14 @@ __export(exports_deep, {
13133
13188
  DEFAULT_SECRET_SCAN_SH: () => DEFAULT_SECRET_SCAN_SH,
13134
13189
  DEFAULT_PUSH_SH: () => DEFAULT_PUSH_SH2
13135
13190
  });
13136
- import { existsSync as existsSync32, mkdirSync as mkdirSync22, mkdtempSync as mkdtempSync8, rmSync as rmSync16, writeFileSync as writeFileSync25 } from "fs";
13191
+ import { existsSync as existsSync33, mkdirSync as mkdirSync22, mkdtempSync as mkdtempSync8, rmSync as rmSync16, writeFileSync as writeFileSync25 } from "fs";
13137
13192
  import { tmpdir as tmpdir9 } from "os";
13138
- import { join as join53 } from "path";
13193
+ import { join as join54 } from "path";
13139
13194
  function sessionCouncil(sessions) {
13140
13195
  return { async run(input, signal) {
13141
- const cwd = mkdtempSync8(join53(tmpdir9(), "loki-deep-council-"));
13196
+ const cwd = mkdtempSync8(join54(tmpdir9(), "loki-deep-council-"));
13142
13197
  try {
13143
- writeFileSync25(join53(cwd, "diff.patch"), input.diff, "utf8");
13198
+ writeFileSync25(join54(cwd, "diff.patch"), input.diff, "utf8");
13144
13199
  const r = await sessions.run({
13145
13200
  stage: "deep",
13146
13201
  tier: "development",
@@ -13250,7 +13305,7 @@ async function runCouncilCheck(ctx, changed, baseSha, signal, opts, checks, notP
13250
13305
  async function runSecretScan(ctx, changed, opts, checks, notProven) {
13251
13306
  const scriptPath = opts.secretScanShPath ?? DEFAULT_SECRET_SCAN_SH;
13252
13307
  const name = "security scan";
13253
- if (!existsSync32(scriptPath)) {
13308
+ if (!existsSync33(scriptPath)) {
13254
13309
  checks.push({ name, cmd: "secret-scan.sh", result: "not_run", duration_s: 0 });
13255
13310
  notProven.add(`not run: ${name} (secret-scan.sh not found)`);
13256
13311
  return;
@@ -13261,7 +13316,7 @@ async function runSecretScan(ctx, changed, opts, checks, notProven) {
13261
13316
  }
13262
13317
  const inline = 'script="$1"; shift; . "$script" || exit 3; hit=0; for f in "$@"; do if _commit_scan_secret_file "$f" || _commit_path_looks_secret "$f"; then printf "%s\\n" "$f"; hit=1; fi; done; exit "$hit"';
13263
13318
  const started = Date.now();
13264
- const r = await run(["bash", "-c", inline, "_", scriptPath, ...changed.map((f) => join53(ctx.repoDir, f))], { cwd: ctx.repoDir, timeoutMs: 30000 });
13319
+ const r = await run(["bash", "-c", inline, "_", scriptPath, ...changed.map((f) => join54(ctx.repoDir, f))], { cwd: ctx.repoDir, timeoutMs: 30000 });
13265
13320
  const durationS = (Date.now() - started) / 1000;
13266
13321
  if (r.exitCode === 3) {
13267
13322
  checks.push({ name, cmd: "secret-scan.sh", result: "not_run", duration_s: durationS });
@@ -13296,7 +13351,7 @@ async function postResults(ctx, opts, checks, notProven, statusState) {
13296
13351
  const prNumber = prUrl ? PR_NUMBER_RE.exec(prUrl)?.[1] : undefined;
13297
13352
  if (prNumber) {
13298
13353
  mkdirSync22(ctx.runDir, { recursive: true });
13299
- const bodyFile = join53(ctx.runDir, "deep-comment.md");
13354
+ const bodyFile = join54(ctx.runDir, "deep-comment.md");
13300
13355
  writeFileSync25(bodyFile, buildCommentBody(checks, notProven, statusState), "utf8");
13301
13356
  const commentResult = await run(["bash", scriptPath, ...commentArgv(prNumber, bodyFile)], { cwd: ctx.repoDir, env, timeoutMs: 30000 });
13302
13357
  if (commentResult.exitCode !== 0)
@@ -13350,7 +13405,7 @@ async function runDeep(ctx, signal, opts = {}) {
13350
13405
  const sig = signReceipt(`${ctx.runId}-deep`, addendumSha256);
13351
13406
  const addendum = { ...addendumBody, addendum_sha256: addendumSha256, verification: { jwt: sig.jwt, kid: sig.kid } };
13352
13407
  mkdirSync22(ctx.runDir, { recursive: true });
13353
- writeFileSync25(join53(ctx.runDir, "receipt-addendum-1.json"), JSON.stringify(addendum, null, 2) + `
13408
+ writeFileSync25(join54(ctx.runDir, "receipt-addendum-1.json"), JSON.stringify(addendum, null, 2) + `
13354
13409
  `);
13355
13410
  const pushNotProven = await postResults(ctx, opts, checks, notProvenList, statusState);
13356
13411
  const allNotProven = [...notProvenList, ...pushNotProven];
@@ -13394,20 +13449,20 @@ var init_deep = __esm(() => {
13394
13449
  });
13395
13450
 
13396
13451
  // ../../loki-ts/src/engine10/stages/verify.ts
13397
- import { existsSync as existsSync33, mkdtempSync as mkdtempSync9, realpathSync as realpathSync18, rmSync as rmSync17 } from "fs";
13452
+ import { existsSync as existsSync34, mkdtempSync as mkdtempSync9, realpathSync as realpathSync19, rmSync as rmSync17 } from "fs";
13398
13453
  import { tmpdir as tmpdir10 } from "os";
13399
- import { dirname as dirname20, isAbsolute as isAbsolute7, join as join54, relative as relative6 } from "path";
13454
+ import { dirname as dirname20, isAbsolute as isAbsolute8, join as join55, relative as relative7 } from "path";
13400
13455
  function resolveTool(repoDir, bin, fallback, lastResort = fallback) {
13401
13456
  const inRepo = (p) => {
13402
13457
  try {
13403
- const r = relative6(realpathSync18(repoDir), realpathSync18(p));
13404
- return r !== "" && !r.startsWith("..") && !isAbsolute7(r);
13458
+ const r = relative7(realpathSync19(repoDir), realpathSync19(p));
13459
+ return r !== "" && !r.startsWith("..") && !isAbsolute8(r);
13405
13460
  } catch {
13406
13461
  return false;
13407
13462
  }
13408
13463
  };
13409
13464
  const venvEnv = process.env["VIRTUAL_ENV"];
13410
- const project = [join54(repoDir, ".venv", "bin", bin), join54(repoDir, "venv", "bin", bin), ...venvEnv && inRepo(venvEnv) ? [join54(venvEnv, "bin", bin)] : []].find(existsSync33);
13465
+ const project = [join55(repoDir, ".venv", "bin", bin), join55(repoDir, "venv", "bin", bin), ...venvEnv && inRepo(venvEnv) ? [join55(venvEnv, "bin", bin)] : []].find(existsSync34);
13411
13466
  return project ? [project, "project"] : [Bun.which(fallback) ? fallback : lastResort, "system"];
13412
13467
  }
13413
13468
  function runnerCmd(t, repoDir) {
@@ -13504,6 +13559,8 @@ async function runCheck(ctx, name, cmd, args, signal, checks, opts = {}) {
13504
13559
  }
13505
13560
  const reason = c.reason;
13506
13561
  const check = { name, cmd: cmdStr, result, duration_s: (Date.now() - started) / 1000, ...result === "fail" ? { first_error: firstError(attempt.out), ids: failIds(attempt.out) } : result === "pass" && kind === "test" ? { n: c.n ?? 0, sk: skipped(attempt.out) } : {}, ...reason ? { reason } : {}, ...c.owner ? { owner: "harness" } : {}, ...opts.interpreter ? { interpreter: opts.interpreter } : {} };
13562
+ if (result === "fail" && !opts.opaque && !isHold(check))
13563
+ excerpts.set(check, failureExcerpt(attempt.out, ctx.repoDir));
13507
13564
  checks.push(check);
13508
13565
  if (opts.opaque && check.result !== "pass" && check.reason)
13509
13566
  recordHoldoutTriage(ctx.runDir, { check: name, result: check.result, reason: check.reason });
@@ -13520,7 +13577,7 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal)
13520
13577
  const sus = pairs.filter(({ c }) => rel.has(c.name) && c.result === "pass");
13521
13578
  if (!(un.some(({ c }) => c.result === "fail" && c.ids?.length) || sus.length) || signal.aborted)
13522
13579
  return out2;
13523
- const dir = mkdtempSync9(join54(tmpdir10(), "e10-base-"));
13580
+ const dir = mkdtempSync9(join55(tmpdir10(), "e10-base-"));
13524
13581
  const git3 = (args) => {
13525
13582
  safeGit(ctx.repoDir, args, { stdio: "ignore", repoDrivers: true });
13526
13583
  };
@@ -13558,7 +13615,7 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal)
13558
13615
  return out2;
13559
13616
  }
13560
13617
  function isLokiModeRepo(repoDir) {
13561
- return existsSync33(join54(repoDir, "scripts", "select-tests.sh"));
13618
+ return existsSync34(join55(repoDir, "scripts", "select-tests.sh"));
13562
13619
  }
13563
13620
  async function runLintChecks(ctx, changed, signal, checks, opts = {}) {
13564
13621
  const { api, ...runOpts } = opts;
@@ -13580,9 +13637,9 @@ async function runLintChecks(ctx, changed, signal, checks, opts = {}) {
13580
13637
  }
13581
13638
  for (const g of groupByPackage(api, ctx.repoDir, changed.filter((f) => /\.(ts|tsx|js|jsx)$/.test(f)))) {
13582
13639
  const sfx = g.root === "." ? "" : `:${g.root}`, co = g.root === "." ? opts : { ...opts, cwd: g.cwd };
13583
- if (existsSync33(join54(g.cwd, "tsconfig.json")))
13640
+ if (existsSync34(join55(g.cwd, "tsconfig.json")))
13584
13641
  await runCheck(ctx, `lint:tsc${sfx}`, "npx", ["tsc", "--noEmit", "-p", "."], signal, checks, { ...co, kind: "static" });
13585
- if (ESLINT_CONFIGS.some((f) => existsSync33(join54(g.cwd, f)))) {
13642
+ if (ESLINT_CONFIGS.some((f) => existsSync34(join55(g.cwd, f)))) {
13586
13643
  const c = await runCheck(ctx, `lint:eslint${sfx}`, "npx", ["eslint", ...g.rel], signal, checks, { ...co, kind: "static" });
13587
13644
  if (await excuseLint(ctx, signal, c, "eslint", "npx", ["eslint"], g.cwd, g.rel, co))
13588
13645
  pre.push(c.name);
@@ -13590,14 +13647,14 @@ async function runLintChecks(ctx, changed, signal, checks, opts = {}) {
13590
13647
  }
13591
13648
  return pre;
13592
13649
  }
13593
- var CHECK_TIMEOUT_MS = 60000, isHold = (c) => isHoldoutCheck(c.name), pubHold = (c) => ({ name: "holdout", cmd: "holdout", result: c.result, duration_s: c.duration_s, ...c.n !== undefined ? { n: c.n } : {}, ...c.sk !== undefined ? { sk: c.sk } : {}, ...c.owner ? { owner: c.owner, reason: "holdout infrastructure failure" } : {} }), testCheckName = (t) => `${t.runner}:${t.path}`, dedupeTests = (tests) => [...new Map(tests.map((t) => [`${t.runner}:${t.path}`, t])).values()], CODE_EXT, ESLINT_CONFIGS, excuseLint = (ctx, signal, c, tool, cmd, prefix, cwd, rel, opts) => c.result !== "fail" || signal.aborted ? Promise.resolve(false) : staticPreExisting(tool, prefix, rel, { run: async (a, stdin) => {
13650
+ var CHECK_TIMEOUT_MS = 60000, excerpts, isHold = (c) => isHoldoutCheck(c.name), pubHold = (c) => ({ name: "holdout", cmd: "holdout", result: c.result, duration_s: c.duration_s, ...c.n !== undefined ? { n: c.n } : {}, ...c.sk !== undefined ? { sk: c.sk } : {}, ...c.owner ? { owner: c.owner, reason: "holdout infrastructure failure" } : {} }), testCheckName = (t) => `${t.runner}:${t.path}`, dedupeTests = (tests) => [...new Map(tests.map((t) => [`${t.runner}:${t.path}`, t])).values()], CODE_EXT, ESLINT_CONFIGS, excuseLint = (ctx, signal, c, tool, cmd, prefix, cwd, rel, opts) => c.result !== "fail" || signal.aborted ? Promise.resolve(false) : staticPreExisting(tool, prefix, rel, { run: async (a, stdin) => {
13594
13651
  if (signal.aborted)
13595
13652
  return null;
13596
13653
  const r = await runOnce2(cmd, a, cwd, AbortSignal.any([signal, AbortSignal.timeout(opts.timeoutMs ?? CHECK_TIMEOUT_MS)]), { ...opts, ...stdin !== undefined ? { stdin } : {} });
13597
13654
  return r.missing || r.cut ? null : r;
13598
13655
  }, base: (f) => {
13599
13656
  try {
13600
- return safeGit(ctx.repoDir, ["show", `${ctx.baseSha}:${relative6(ctx.repoDir, join54(cwd, f))}`], { stdio: ["ignore", "pipe", "ignore"] });
13657
+ return safeGit(ctx.repoDir, ["show", `${ctx.baseSha}:${relative7(ctx.repoDir, join55(cwd, f))}`], { stdio: ["ignore", "pipe", "ignore"] });
13601
13658
  } catch {
13602
13659
  return null;
13603
13660
  }
@@ -13620,6 +13677,7 @@ var init_verify = __esm(() => {
13620
13677
  init_check_result();
13621
13678
  init_check_result();
13622
13679
  init_runner_config();
13680
+ excerpts = new WeakMap;
13623
13681
  CODE_EXT = /\.(?:[cm]?[jt]sx?|py|go)$/;
13624
13682
  ESLINT_CONFIGS = [".eslintrc", ".eslintrc.json", ".eslintrc.js", ".eslintrc.cjs", "eslint.config.js", "eslint.config.mjs", "eslint.config.cjs"];
13625
13683
  verifyStage = {
@@ -13655,7 +13713,7 @@ var init_verify = __esm(() => {
13655
13713
  const impacted = ctx.tests.impacted(map, changed);
13656
13714
  const changedTestFiles = map.tests.filter((t) => changed.includes(t.path));
13657
13715
  const wall = ctx.outputs().wall ?? {};
13658
- const wallPaths = new Set((wall.files ?? []).map((f) => isAbsolute7(f.path) ? relative6(ctx.repoDir, f.path) : f.path));
13716
+ const wallPaths = new Set((wall.files ?? []).map((f) => isAbsolute8(f.path) ? relative7(ctx.repoDir, f.path) : f.path));
13659
13717
  const wallTests = map.tests.filter((t) => wallPaths.has(t.path));
13660
13718
  const intake = ctx.outputs().intake, relevant2 = ctx.tests.impacted(map, namedFiles(intake?.task ?? "", loadRepoMap(intake?.repomap_ref)));
13661
13719
  const tests = dedupeTests([...impacted, ...changedTestFiles, ...wallTests, ...relevant2]);
@@ -13730,7 +13788,13 @@ var init_verify = __esm(() => {
13730
13788
  const covered = (f) => ctx.tests.impacted(map, [f]).some((t) => checks.some((c) => c.name === testCheckName(t) && hasExecutedProof([c])));
13731
13789
  const uncoveredChanged = changed.filter((f) => CODE_EXT.test(f) && !isTestFile(f) && !wallPaths.has(f) && !cfgChanged.includes(f) && !covered(f));
13732
13790
  const flaky = checks.filter((c) => c.result === "flaky").map((c) => isHold(c) ? "holdout" : c.name);
13733
- const failuresGrouped = checks.filter((c) => c.result === "fail" && !preRed.names.includes(c.name) && !isHold(c)).map((c) => ({ signature: c.first_error ? `${c.name} ${c.first_error}` : c.name, count: 1, sample: c.cmd }));
13791
+ let excerptLeft = EXCERPT_TOTAL_CAP;
13792
+ const failuresGrouped = checks.filter((c) => c.result === "fail" && !preRed.names.includes(c.name) && !isHold(c)).map((c) => {
13793
+ const x = isHold(c) ? "" : truncateBytes(excerpts.get(c) ?? "", Math.max(0, excerptLeft));
13794
+ excerptLeft -= Buffer.byteLength(x);
13795
+ return { signature: c.first_error ? `${c.name} ${c.first_error}` : c.name, count: 1, sample: x ? `${c.cmd}
13796
+ ${x}` : c.cmd };
13797
+ });
13734
13798
  const pub = checks.map((c) => isHold(c) ? pubHold(c) : c), holdoutFailed = checks.filter((c) => c.result === "fail" && isHold(c) && !preRed.names.includes(c.name)).length;
13735
13799
  const inBase = (f) => {
13736
13800
  try {
@@ -13755,8 +13819,8 @@ var init_verify = __esm(() => {
13755
13819
  });
13756
13820
 
13757
13821
  // ../../loki-ts/src/project_model/conventions.ts
13758
- import { existsSync as existsSync34, readdirSync as readdirSync17, readFileSync as readFileSync41 } from "fs";
13759
- import { dirname as dirname21, join as join55 } from "path";
13822
+ import { existsSync as existsSync35, readdirSync as readdirSync18, readFileSync as readFileSync42 } from "fs";
13823
+ import { dirname as dirname21, join as join56 } from "path";
13760
13824
  function parseJsonc(text2) {
13761
13825
  let out2 = "", i = 0;
13762
13826
  while (i < text2.length) {
@@ -13791,25 +13855,25 @@ function moduleOf(file, depth = 0) {
13791
13855
  const ext = typeof j.extends === "string" ? j.extends : null;
13792
13856
  if (!ext || !ext.startsWith("."))
13793
13857
  return null;
13794
- const next = join55(dirname21(file), ext.endsWith(".json") ? ext : `${ext}.json`);
13795
- return existsSync34(next) ? moduleOf(next, depth + 1) : null;
13858
+ const next = join56(dirname21(file), ext.endsWith(".json") ? ext : `${ext}.json`);
13859
+ return existsSync35(next) ? moduleOf(next, depth + 1) : null;
13796
13860
  }
13797
13861
  function readPackageConventions(pkgDir, runner = null) {
13798
13862
  let names = [];
13799
13863
  try {
13800
- names = readdirSync17(pkgDir).filter((f) => f.endsWith(".json")).sort((x, y) => x.length - y.length || x.localeCompare(y));
13864
+ names = readdirSync18(pkgDir).filter((f) => f.endsWith(".json")).sort((x, y) => x.length - y.length || x.localeCompare(y));
13801
13865
  } catch {
13802
13866
  return null;
13803
13867
  }
13804
13868
  let packageType = null, tsModule = null;
13805
13869
  for (const n2 of names) {
13806
- const j = readJson4(join55(pkgDir, n2));
13870
+ const j = readJson4(join56(pkgDir, n2));
13807
13871
  if (!j)
13808
13872
  continue;
13809
13873
  if (packageType === null && typeof j.type === "string" && typeof j.name === "string")
13810
13874
  packageType = j.type;
13811
13875
  if (tsModule === null && j.compilerOptions !== undefined)
13812
- tsModule = moduleOf(join55(pkgDir, n2));
13876
+ tsModule = moduleOf(join56(pkgDir, n2));
13813
13877
  }
13814
13878
  if (packageType === null && tsModule === null)
13815
13879
  return null;
@@ -13831,7 +13895,7 @@ function conventionViolation(c, fileName, content) {
13831
13895
  }
13832
13896
  var readJson4 = (p) => {
13833
13897
  try {
13834
- const v = parseJsonc(readFileSync41(p, "utf8"));
13898
+ const v = parseJsonc(readFileSync42(p, "utf8"));
13835
13899
  return v && typeof v === "object" && !Array.isArray(v) ? v : null;
13836
13900
  } catch {
13837
13901
  return null;
@@ -13841,15 +13905,15 @@ var init_conventions = () => {};
13841
13905
 
13842
13906
  // ../../loki-ts/src/engine10/stages/wall.ts
13843
13907
  import { spawnSync as spawnSync4 } from "child_process";
13844
- import { existsSync as existsSync35, mkdirSync as mkdirSync23, mkdtempSync as mkdtempSync10, readFileSync as readFileSync42, readdirSync as readdirSync18, realpathSync as realpathSync19, rmSync as rmSync18, writeFileSync as writeFileSync26 } from "fs";
13908
+ import { existsSync as existsSync36, mkdirSync as mkdirSync23, mkdtempSync as mkdtempSync10, readFileSync as readFileSync43, readdirSync as readdirSync19, realpathSync as realpathSync20, rmSync as rmSync18, writeFileSync as writeFileSync26 } from "fs";
13845
13909
  import { tmpdir as tmpdir11 } from "os";
13846
- import { dirname as dirname22, isAbsolute as isAbsolute8, join as join56, relative as relative7 } from "path";
13910
+ import { dirname as dirname22, isAbsolute as isAbsolute9, join as join57, relative as relative8 } from "path";
13847
13911
  function pytestCollectionIsRed(output, repoDir) {
13848
13912
  if (/ModuleNotFoundError/.test(output))
13849
13913
  return false;
13850
13914
  const real2 = (p) => {
13851
13915
  try {
13852
- return realpathSync19(isAbsolute8(p) ? p : join56(repoDir, p));
13916
+ return realpathSync20(isAbsolute9(p) ? p : join57(repoDir, p));
13853
13917
  } catch {
13854
13918
  return null;
13855
13919
  }
@@ -13886,7 +13950,7 @@ function pytestCollectionIsRed(output, repoDir) {
13886
13950
  }
13887
13951
  function moduleUnderRepo(repoDir, name) {
13888
13952
  const rel = name.replace(/\./g, "/");
13889
- return existsSync35(join56(repoDir, `${rel}.py`)) || existsSync35(join56(repoDir, rel, "__init__.py"));
13953
+ return existsSync36(join57(repoDir, `${rel}.py`)) || existsSync36(join57(repoDir, rel, "__init__.py"));
13890
13954
  }
13891
13955
  function pytestExit1IsRed(output) {
13892
13956
  if (/^!+ _pytest\.outcomes\.Exit\b/m.test(output))
@@ -13985,10 +14049,10 @@ ${acceptance.map((a) => `Acceptance: ${a}`).join(`
13985
14049
  function loadTaskText(ctx, fromPrior) {
13986
14050
  if (fromPrior)
13987
14051
  return fromPrior;
13988
- const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ?? join56(ctx.runDir, "issue.json");
13989
- if (existsSync35(issueJsonPath)) {
14052
+ const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ?? join57(ctx.runDir, "issue.json");
14053
+ if (existsSync36(issueJsonPath)) {
13990
14054
  try {
13991
- const issue = JSON.parse(readFileSync42(issueJsonPath, "utf8"));
14055
+ const issue = JSON.parse(readFileSync43(issueJsonPath, "utf8"));
13992
14056
  const text2 = [issue.title, issue.body].filter((s) => typeof s === "string" && s.length > 0).join(`
13993
14057
 
13994
14058
  `);
@@ -14000,7 +14064,7 @@ function loadTaskText(ctx, fromPrior) {
14000
14064
  }
14001
14065
  function wallTargetDir(repoDir, existingTests) {
14002
14066
  const first = existingTests[0];
14003
- return first ? join56(repoDir, dirname22(first.path)) : join56(repoDir, "tests");
14067
+ return first ? join57(repoDir, dirname22(first.path)) : join57(repoDir, "tests");
14004
14068
  }
14005
14069
  function guessRunner(fileName, runners) {
14006
14070
  if (fileName.endsWith(".py"))
@@ -14028,14 +14092,16 @@ async function wallAuthor(ctx, signal) {
14028
14092
  }
14029
14093
  if (testMap && runners.length === 0 && !(repoMap?.files ?? []).some((p) => /\.(py|go)$/.test(p)))
14030
14094
  return done({ status: "skipped", data: { size: sz.size, files: [], no_runner: true }, reason: "no runnable test command detected: the Wall cannot write a runnable check" });
14095
+ if (testMap && (runners.length === 0 ? (repoMap?.files ?? []).some((p) => p.endsWith(".py")) && !(repoMap?.files ?? []).some((p) => p.endsWith(".go")) : runners.every((r) => r === "pytest")) && projectInterpreter(ctx.repoDir) === "system" && wallHoldoutRatio() === 0)
14096
+ return done({ status: "skipped", data: { size: sz.size, files: [], no_interpreter: true, not_proven: ["Wall skipped: no project test interpreter"] }, reason: "Wall skipped: no project test interpreter" });
14031
14097
  const tree = prior.intake?.tree;
14032
14098
  const repomapText = repoMapText(ctx.repoDir, tree, repomapRef, WALL_MAP_MAX_LINES);
14033
- const targetDir = wallTargetDir(ctx.repoDir, existingTests), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${relative7(ctx.repoDir, targetDir)}/x`);
14034
- const conv2 = readPackageConventions(join56(ctx.repoDir, pkg?.root ?? "."), pkg?.runner ?? null);
14035
- const cwd = mkdtempSync10(join56(tmpdir11(), "loki-e15-wall-"));
14099
+ const targetDir = wallTargetDir(ctx.repoDir, existingTests), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${relative8(ctx.repoDir, targetDir)}/x`);
14100
+ const conv2 = readPackageConventions(join57(ctx.repoDir, pkg?.root ?? "."), pkg?.runner ?? null);
14101
+ const cwd = mkdtempSync10(join57(tmpdir11(), "loki-e15-wall-"));
14036
14102
  const wm = wallManifestFor(ctx.repoDir, tree, task);
14037
14103
  for (const [n2, c] of [["task.md", task], ["repomap.txt", repomapText], ...wm ? [["wall_manifest.txt", wm.text]] : []])
14038
- writeFileSync26(join56(cwd, n2), c, "utf8");
14104
+ writeFileSync26(join57(cwd, n2), c, "utf8");
14039
14105
  const session = await ctx.sessions.run({
14040
14106
  stage: "wall",
14041
14107
  brief: buildWallBrief(task, repomapText, runners, !!wm, conventionsBrief(conv2), unitSpec()?.acceptance ?? []),
@@ -14050,15 +14116,15 @@ async function wallAuthor(ctx, signal) {
14050
14116
  rmSync18(cwd, { recursive: true, force: true });
14051
14117
  return done({ status: "failed", data: {}, reason: "wall session aborted, killed, or timed out", killed: true });
14052
14118
  }
14053
- const all = readdirSync18(cwd).filter((f) => f.startsWith(WALL_PREFIX)), held = stashHoldout({ runId: ctx.runId, repoDir: ctx.repoDir, srcDir: cwd, targetDir, names: all.filter((n2) => !conventionViolation(conv2, n2, readFileSync42(join56(cwd, n2), "utf8"))), runnerOf: (n2) => guessRunner(n2, runners) }), generated = all.filter((n2) => !held?.names.has(n2));
14054
- const sealedDir = join56(ctx.runDir, "wall");
14119
+ const all = readdirSync19(cwd).filter((f) => f.startsWith(WALL_PREFIX)), held = stashHoldout({ runId: ctx.runId, repoDir: ctx.repoDir, srcDir: cwd, targetDir, names: all.filter((n2) => !conventionViolation(conv2, n2, readFileSync43(join57(cwd, n2), "utf8"))), runnerOf: (n2) => guessRunner(n2, runners) }), generated = all.filter((n2) => !held?.names.has(n2));
14120
+ const sealedDir = join57(ctx.runDir, "wall");
14055
14121
  if (generated.length > 0)
14056
14122
  mkdirSync23(sealedDir, { recursive: true });
14057
14123
  const contents = new Map;
14058
14124
  const discarded = [];
14059
14125
  for (const name of generated) {
14060
- const content = readFileSync42(join56(cwd, name), "utf8"), bad = conventionViolation(conv2, name, content);
14061
- writeFileSync26(join56(sealedDir, name), content, "utf8");
14126
+ const content = readFileSync43(join57(cwd, name), "utf8"), bad = conventionViolation(conv2, name, content);
14127
+ writeFileSync26(join57(sealedDir, name), content, "utf8");
14062
14128
  if (bad)
14063
14129
  discarded.push({ file: name, reason: `${bad}; wall test did not compile under the package config` });
14064
14130
  else
@@ -14078,18 +14144,18 @@ function installWall(ctx, a, baseDir, opts = {}) {
14078
14144
  const content = contents.get(name);
14079
14145
  if (content === undefined)
14080
14146
  continue;
14081
- const dest = join56(targetDir, name), runner = guessRunner(name, runners);
14147
+ const dest = join57(targetDir, name), runner = guessRunner(name, runners);
14082
14148
  writeFileSync26(dest, content, "utf8");
14083
14149
  sealedFiles.push({ path: dest, sha256: sha2562(content) });
14084
14150
  readOnlyFiles.push({ path: dest, content });
14085
14151
  if (runner)
14086
- wallTests.push({ runner, path: relative7(ctx.repoDir, dest) });
14152
+ wallTests.push({ runner, path: relative8(ctx.repoDir, dest) });
14087
14153
  }
14088
14154
  ctx.wallSealed = true;
14089
14155
  ctx.emit("wall.sealed", "wall", { files: sealedFiles, ...a.manifestSha256 ? { manifest_sha256: a.manifestSha256 } : {} });
14090
14156
  const baseRunner = opts.baseRunner ?? new RealBaseTestRunner, baseRun = { pass: 0, fail: 0, not_run: discarded.length }, notRunFiles = [];
14091
14157
  for (const t of wallTests) {
14092
- const r = baseRunner.run(baseDir, [t]), abs = join56(ctx.repoDir, t.path);
14158
+ const r = baseRunner.run(baseDir, [t]), abs = join57(ctx.repoDir, t.path);
14093
14159
  baseRun.pass += r.pass;
14094
14160
  baseRun.fail += r.fail;
14095
14161
  baseRun.not_run += r.not_run ?? 0;
@@ -14130,6 +14196,7 @@ var init_wall = __esm(() => {
14130
14196
  init_seal();
14131
14197
  init_holdout();
14132
14198
  init_verify();
14199
+ init_testmap();
14133
14200
  init_resolve();
14134
14201
  init_check_result();
14135
14202
  init_conventions();
@@ -14143,15 +14210,15 @@ var init_wall = __esm(() => {
14143
14210
  });
14144
14211
 
14145
14212
  // ../../loki-ts/src/e10ext/discard.ts
14146
- import { chmodSync as chmodSync5, closeSync as closeSync9, lstatSync as lstatSync12, mkdirSync as mkdirSync24, openSync as openSync9, readFileSync as readFileSync43, realpathSync as realpathSync20, rmdirSync, unlinkSync as unlinkSync6, writeFileSync as writeFileSync27 } from "fs";
14147
- import { dirname as dirname23, join as join57, relative as relative8, sep as sep11 } from "path";
14213
+ import { chmodSync as chmodSync5, closeSync as closeSync9, lstatSync as lstatSync12, mkdirSync as mkdirSync24, openSync as openSync9, readFileSync as readFileSync44, realpathSync as realpathSync21, rmdirSync, unlinkSync as unlinkSync6, writeFileSync as writeFileSync27 } from "fs";
14214
+ import { dirname as dirname23, join as join58, relative as relative9, sep as sep12 } from "path";
14148
14215
  function safeRestore(repoDir, f, want, mode) {
14149
- const root = realpathSync20(repoDir), fp = join57(root, f), rel = relative8(root, dirname23(fp));
14216
+ const root = realpathSync21(repoDir), fp = join58(root, f), rel = relative9(root, dirname23(fp));
14150
14217
  if (rel.startsWith(".."))
14151
14218
  throw new Error("outside repo");
14152
14219
  let cur = root;
14153
- for (const part of rel === "" ? [] : rel.split(sep11)) {
14154
- cur = join57(cur, part);
14220
+ for (const part of rel === "" ? [] : rel.split(sep12)) {
14221
+ cur = join58(cur, part);
14155
14222
  let st2;
14156
14223
  try {
14157
14224
  st2 = lstatSync12(cur);
@@ -14168,7 +14235,7 @@ function safeRestore(repoDir, f, want, mode) {
14168
14235
  } catch {
14169
14236
  st = null;
14170
14237
  }
14171
- if (st?.isFile() && readFileSync43(fp).equals(want)) {
14238
+ if (st?.isFile() && readFileSync44(fp).equals(want)) {
14172
14239
  chmodSync5(fp, mode);
14173
14240
  return;
14174
14241
  }
@@ -14206,7 +14273,7 @@ async function discardIfSatisfied(git3, base, o, staged, keep, repoDir) {
14206
14273
  return { status: "failed", data: {}, reason: "already-satisfied discard failed" };
14207
14274
  const notProven = [];
14208
14275
  for (const [f, v] of Object.entries(o.intake?.preexisting_untracked_blobs ?? {})) {
14209
- const fp = join57(repoDir, f);
14276
+ const fp = join58(repoDir, f);
14210
14277
  try {
14211
14278
  if (v.startsWith("!")) {
14212
14279
  const st = lstatSync12(fp);
@@ -14225,7 +14292,7 @@ async function discardIfSatisfied(git3, base, o, staged, keep, repoDir) {
14225
14292
  try {
14226
14293
  let m = 420;
14227
14294
  try {
14228
- const l = lstatSync12(join57(repoDir, f));
14295
+ const l = lstatSync12(join58(repoDir, f));
14229
14296
  if (l.isFile())
14230
14297
  m = l.mode & 511;
14231
14298
  } catch {}
@@ -14269,7 +14336,7 @@ var init_commit_filter = __esm(() => {
14269
14336
  });
14270
14337
 
14271
14338
  // ../../loki-ts/src/e10ext/scope.ts
14272
- import { basename as basename20, dirname as dirname25 } from "path";
14339
+ import { basename as basename21, dirname as dirname25 } from "path";
14273
14340
  function contractText(o) {
14274
14341
  const c = o.intake?.contract_snapshot?.contract;
14275
14342
  return Array.isArray(c?.criteria) ? c.criteria.map((x) => typeof x?.text === "string" ? x.text : "").join(`
@@ -14284,7 +14351,7 @@ function outsideScope(o, staged) {
14284
14351
  ${typeof o.intake?.task === "string" ? o.intake.task : ""}
14285
14352
  ${contractText(o)}`, pre = o.intake?.preexisting_dirty ?? {};
14286
14353
  const toks = surfaceTokens(text2), plannedDirs = new Set(rel.map((r) => dirname25(r)).filter((d) => d !== "."));
14287
- return staged.filter(({ st, f }) => st !== "A" && !isTestFile(f) && !Object.hasOwn(pre, f) && !rel.includes(f) && !mentions(text2, f) && !mentions(text2, basename20(f)) && !plannedDirs.has(dirname25(f)) && !dirSegs(f).some((d) => toks.has(d))).map(({ f }) => f);
14354
+ return staged.filter(({ st, f }) => st !== "A" && !isTestFile(f) && !Object.hasOwn(pre, f) && !rel.includes(f) && !mentions(text2, f) && !mentions(text2, basename21(f)) && !plannedDirs.has(dirname25(f)) && !dirSegs(f).some((d) => toks.has(d))).map(({ f }) => f);
14288
14355
  }
14289
14356
  function flagOutsideScope(o, staged) {
14290
14357
  const unit = unitFlags(staged, process.env, o.intake?.preexisting_dirty ?? {});
@@ -14299,14 +14366,14 @@ var init_scope2 = __esm(() => {
14299
14366
  });
14300
14367
 
14301
14368
  // ../../loki-ts/src/council/role_agents.ts
14302
- import { existsSync as existsSync36, readdirSync as readdirSync19, readFileSync as readFileSync44 } from "fs";
14369
+ import { existsSync as existsSync37, readdirSync as readdirSync20, readFileSync as readFileSync45 } from "fs";
14303
14370
  import { homedir as homedir9 } from "os";
14304
- import { join as join58 } from "path";
14371
+ import { join as join59 } from "path";
14305
14372
  function agentDirs(repoDir, env = process.env) {
14306
- return [env["LOKI_AGENTS_PROJECT_DIR"] || join58(repoDir, ".loki", "agents"), env["LOKI_AGENTS_USER_DIR"] || join58(env["XDG_CONFIG_HOME"] || join58(homedir9(), ".config"), "loki", "agents")];
14373
+ return [env["LOKI_AGENTS_PROJECT_DIR"] || join59(repoDir, ".loki", "agents"), env["LOKI_AGENTS_USER_DIR"] || join59(env["XDG_CONFIG_HOME"] || join59(homedir9(), ".config"), "loki", "agents")];
14307
14374
  }
14308
14375
  function parseAgent(file, stem2) {
14309
- const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(readFileSync44(file, "utf8"));
14376
+ const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(readFileSync45(file, "utf8"));
14310
14377
  if (!m)
14311
14378
  return null;
14312
14379
  const body = m[2].trim();
@@ -14320,18 +14387,18 @@ function parseAgent(file, stem2) {
14320
14387
  }
14321
14388
  function loadRoleAgent(repoDir, role, env = process.env) {
14322
14389
  for (const d of agentDirs(repoDir, env)) {
14323
- if (!existsSync36(d))
14390
+ if (!existsSync37(d))
14324
14391
  continue;
14325
14392
  let names;
14326
14393
  try {
14327
- names = readdirSync19(d).filter((n2) => n2.endsWith(".md") && !n2.startsWith(".")).sort();
14394
+ names = readdirSync20(d).filter((n2) => n2.endsWith(".md") && !n2.startsWith(".")).sort();
14328
14395
  } catch {
14329
14396
  continue;
14330
14397
  }
14331
14398
  const ordered = [...names.filter((n2) => n2 === `${role}.md`), ...names.filter((n2) => n2 !== `${role}.md`)];
14332
14399
  for (const n2 of ordered) {
14333
14400
  try {
14334
- const a = parseAgent(join58(d, n2), n2.slice(0, -3));
14401
+ const a = parseAgent(join59(d, n2), n2.slice(0, -3));
14335
14402
  if (a && a.role === role)
14336
14403
  return a;
14337
14404
  } catch {}
@@ -14349,7 +14416,7 @@ var init_role_agents = __esm(() => {
14349
14416
 
14350
14417
  // ../../loki-ts/src/util/child_ledger.ts
14351
14418
  import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync25 } from "fs";
14352
- import { join as join59 } from "path";
14419
+ import { join as join60 } from "path";
14353
14420
  function unmeasuredRecord(phase, model, source) {
14354
14421
  return { phase, model, input_tokens: 0, output_tokens: 0, cache_creation_tokens: 0, cache_read_tokens: 0, source, cost_status: "unmeasured" };
14355
14422
  }
@@ -14374,9 +14441,9 @@ function recordFromClaudeResult(phase, payload, source = "claude-json") {
14374
14441
  }
14375
14442
  function appendChildLedger(lokiDir2, rec2) {
14376
14443
  try {
14377
- const dir = join59(lokiDir2, "metrics");
14444
+ const dir = join60(lokiDir2, "metrics");
14378
14445
  mkdirSync25(dir, { recursive: true });
14379
- appendFileSync4(join59(dir, "child-sessions.jsonl"), `${JSON.stringify(rec2)}
14446
+ appendFileSync4(join60(dir, "child-sessions.jsonl"), `${JSON.stringify(rec2)}
14380
14447
  `);
14381
14448
  return true;
14382
14449
  } catch {
@@ -14406,14 +14473,14 @@ var init_child_ledger = __esm(() => {
14406
14473
  });
14407
14474
 
14408
14475
  // ../../loki-ts/src/util/run_summary.ts
14409
- import { existsSync as existsSync37, mkdirSync as mkdirSync26, readFileSync as readFileSync45, renameSync as renameSync11, statSync as statSync18, writeFileSync as writeFileSync28 } from "fs";
14410
- import { join as join60 } from "path";
14476
+ import { existsSync as existsSync38, mkdirSync as mkdirSync26, readFileSync as readFileSync46, renameSync as renameSync11, statSync as statSync18, writeFileSync as writeFileSync28 } from "fs";
14477
+ import { join as join61 } from "path";
14411
14478
  function readRiskRecord(repoDir, sinceMs = 0) {
14412
14479
  try {
14413
- const p = join60(repoDir, ".loki", "state", "risk-tier.json");
14480
+ const p = join61(repoDir, ".loki", "state", "risk-tier.json");
14414
14481
  if (statSync18(p).mtimeMs < sinceMs)
14415
14482
  return null;
14416
- const r = JSON.parse(readFileSync45(p, "utf8"));
14483
+ const r = JSON.parse(readFileSync46(p, "utf8"));
14417
14484
  return r && typeof r === "object" ? r : null;
14418
14485
  } catch {
14419
14486
  return null;
@@ -14427,8 +14494,8 @@ var init_run_summary = __esm(() => {
14427
14494
  });
14428
14495
 
14429
14496
  // ../../loki-ts/src/engine10/stages/xreview.ts
14430
- import { existsSync as existsSync38, readFileSync as readFileSync46 } from "fs";
14431
- import { join as join61 } from "path";
14497
+ import { existsSync as existsSync39, readFileSync as readFileSync47 } from "fs";
14498
+ import { join as join62 } from "path";
14432
14499
  function minVerdict(verdict, review) {
14433
14500
  const ceiling = review?.level === "block" ? "PARTIAL" : verdict;
14434
14501
  return RANK3[ceiling] < RANK3[verdict] ? ceiling : verdict;
@@ -14441,11 +14508,11 @@ function explicitReview(repoDir, env) {
14441
14508
  if (flag && isOff(ev))
14442
14509
  return "off";
14443
14510
  for (const f of ["loki.yaml", "loki.yml"]) {
14444
- const p = join61(repoDir, f);
14445
- if (!existsSync38(p))
14511
+ const p = join62(repoDir, f);
14512
+ if (!existsSync39(p))
14446
14513
  continue;
14447
14514
  try {
14448
- const m = /^review:[ \t]*["']?([A-Za-z]+)["']?[ \t]*(?:#.*)?$/m.exec(readFileSync46(p, "utf8"));
14515
+ const m = /^review:[ \t]*["']?([A-Za-z]+)["']?[ \t]*(?:#.*)?$/m.exec(readFileSync47(p, "utf8"));
14449
14516
  const v = asProvider(m?.[1]);
14450
14517
  if (v)
14451
14518
  return v;
@@ -14527,7 +14594,7 @@ Review ONLY the diff below. Do not modify files.` : "You are an independent code
14527
14594
  try {
14528
14595
  if (p === "claude")
14529
14596
  await ensureClaudeHelpCache();
14530
- const r = await withChildLedger(run, join61(ctx.repoDir, ".loki"), "xreview")(reviewArgv(p, prompt, process.env, p === "claude" ? agent?.model : undefined), { cwd: ctx.repoDir, timeoutMs: TIMEOUT_MS });
14597
+ const r = await withChildLedger(run, join62(ctx.repoDir, ".loki"), "xreview")(reviewArgv(p, prompt, process.env, p === "claude" ? agent?.model : undefined), { cwd: ctx.repoDir, timeoutMs: TIMEOUT_MS });
14531
14598
  if (r.exitCode !== 0)
14532
14599
  return { provider: p, level: "not_run", notes: [`cross-review not run: ${p} exited ${r.exitCode}`] };
14533
14600
  return parseReview(p, r.stdout);
@@ -14621,8 +14688,8 @@ See also: loki cost --detail (what a run ALREADY spent)
14621
14688
  });
14622
14689
 
14623
14690
  // ../../loki-ts/src/features/contract.ts
14624
- import { existsSync as existsSync39, lstatSync as lstatSync13, mkdirSync as mkdirSync27, readFileSync as readFileSync47, rmSync as rmSync19, writeFileSync as writeFileSync29 } from "fs";
14625
- import { dirname as dirname26, join as join62 } from "path";
14691
+ import { existsSync as existsSync40, lstatSync as lstatSync13, mkdirSync as mkdirSync27, readFileSync as readFileSync48, rmSync as rmSync19, writeFileSync as writeFileSync29 } from "fs";
14692
+ import { dirname as dirname26, join as join63 } from "path";
14626
14693
  import { createHash as createHash16 } from "crypto";
14627
14694
  function contractEnabled(env = process.env) {
14628
14695
  return env["LOKI_CONTRACT"] !== "0";
@@ -14654,7 +14721,7 @@ function untracedLines(trace) {
14654
14721
  return trace.criteria.filter((c) => c.status === "no_match").map((c) => `contract ${sanitizeCriterion(c.id)} untraced (no keyword match in changed files): ${sanitizeCriterion(c.text)}`);
14655
14722
  }
14656
14723
  function contractPath(repoDir) {
14657
- return join62(repoDir, ".loki", "contract.json");
14724
+ return join63(repoDir, ".loki", "contract.json");
14658
14725
  }
14659
14726
  function readContract(repoDir) {
14660
14727
  const p = contractPath(repoDir);
@@ -14670,7 +14737,7 @@ function readContract(repoDir) {
14670
14737
  return { contract: null, notes: ["contract unreadable: too large"], sha256: null };
14671
14738
  let raw2;
14672
14739
  try {
14673
- raw2 = readFileSync47(p);
14740
+ raw2 = readFileSync48(p);
14674
14741
  } catch {
14675
14742
  return { contract: null, notes: ["contract unreadable: read failed"], sha256: null };
14676
14743
  }
@@ -14739,17 +14806,17 @@ var init_contract = __esm(() => {
14739
14806
  init_safe_git();
14740
14807
  STOP2 = new Set(["the", "and", "for", "with", "that", "this", "must", "should", "shall", "when", "then", "are", "was", "all", "any", "can", "not", "has", "have", "from", "into", "each", "user", "users"]);
14741
14808
  MAX_CONTRACT_BYTES = 1024 * 1024;
14742
- REQ_MAP_REL = join62(".loki", "state", "requirements-map.json");
14809
+ REQ_MAP_REL = join63(".loki", "state", "requirements-map.json");
14743
14810
  REQ_STOP = new Set(["with", "that", "this", "from", "have", "will", "should", "must", "when", "then", "into", "each", "every", "user", "users", "page", "able", "allow", "support", "ensure", "using", "their", "there", "which", "shall"]);
14744
14811
  });
14745
14812
 
14746
14813
  // ../../loki-ts/src/features/speed/seal_group.ts
14747
14814
  import { createHash as createHash17 } from "crypto";
14748
- import { existsSync as existsSync40, mkdirSync as mkdirSync28, readdirSync as readdirSync20, readFileSync as readFileSync48, renameSync as renameSync12, statSync as statSync19, writeFileSync as writeFileSync30 } from "fs";
14749
- import { dirname as dirname27, join as join63 } from "path";
14815
+ import { existsSync as existsSync41, mkdirSync as mkdirSync28, readdirSync as readdirSync21, readFileSync as readFileSync49, renameSync as renameSync12, statSync as statSync19, writeFileSync as writeFileSync30 } from "fs";
14816
+ import { dirname as dirname27, join as join64 } from "path";
14750
14817
  function sealGroup(runDir, rh) {
14751
- const manifestPath = join63(runDir, "group", "manifest.json");
14752
- if (!existsSync40(manifestPath))
14818
+ const manifestPath = join64(runDir, "group", "manifest.json");
14819
+ if (!existsSync41(manifestPath))
14753
14820
  return { section: undefined, notProven: [], problems: 0, allUnitsPass: true };
14754
14821
  const notProven = [];
14755
14822
  let problems = 0;
@@ -14773,10 +14840,10 @@ function sealGroup(runDir, rh) {
14773
14840
  return fail(`unit ${index2} has an invalid, duplicate or case-colliding id`);
14774
14841
  seen.add(id);
14775
14842
  seenLower.add(id.toLowerCase());
14776
- const dir = join63(unitsDir(runDir), id), rp = join63(dir, "receipt.json"), ep = join63(dir, "events.jsonl");
14843
+ const dir = join64(unitsDir(runDir), id), rp = join64(dir, "receipt.json"), ep = join64(dir, "events.jsonl");
14777
14844
  let bytes;
14778
14845
  try {
14779
- bytes = readFileSync48(rp);
14846
+ bytes = readFileSync49(rp);
14780
14847
  } catch {
14781
14848
  return fail(`unit ${id} sub-receipt missing`);
14782
14849
  }
@@ -14793,7 +14860,7 @@ function sealGroup(runDir, rh) {
14793
14860
  unit_id: id,
14794
14861
  sub_receipt_sha256: sha3(bytes),
14795
14862
  receipt_sha256: sub["receipt_sha256"],
14796
- events_file_sha256: existsSync40(ep) ? sha3(readFileSync48(ep)) : null,
14863
+ events_file_sha256: existsSync41(ep) ? sha3(readFileSync49(ep)) : null,
14797
14864
  verdict,
14798
14865
  goal: text2(u["goal"], 200),
14799
14866
  files: (Array.isArray(u["files"]) ? u["files"] : []).map((f) => text2(f, 200)).filter(Boolean).slice(0, 50),
@@ -14818,7 +14885,7 @@ async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
14818
14885
  const bad = (reason) => ({ verdict: "TAMPERED", reason: `group: ${reason}` });
14819
14886
  const g = receipt["group"];
14820
14887
  if (g === undefined)
14821
- return existsSync40(join63(runDir, "group", "manifest.json")) ? bad("group directory present but the receipt has no group section") : null;
14888
+ return existsSync41(join64(runDir, "group", "manifest.json")) ? bad("group directory present but the receipt has no group section") : null;
14822
14889
  if (!isObj10(g) || !ID_RE.test(String(g["group_id"] ?? "")) || !Array.isArray(g["units"]) || g["units"].length === 0)
14823
14890
  return bad("group section malformed");
14824
14891
  const entries = g["units"];
@@ -14830,20 +14897,20 @@ async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
14830
14897
  return bad("unit directories do not match the receipt (missing or extra unit)");
14831
14898
  let unchecked = null;
14832
14899
  for (let i = 0;i < entries.length; i++) {
14833
- const e = entries[i], id = ids[i], dir = join63(unitsDir(runDir), id), rp = join63(dir, "receipt.json"), ep = join63(dir, "events.jsonl");
14900
+ const e = entries[i], id = ids[i], dir = join64(unitsDir(runDir), id), rp = join64(dir, "receipt.json"), ep = join64(dir, "events.jsonl");
14834
14901
  if (e["index"] !== i)
14835
14902
  return bad(`unit ${id} is out of order (index ${String(e["index"])} at position ${i})`);
14836
14903
  let bytes;
14837
14904
  try {
14838
14905
  if (!statSync19(dir).isDirectory())
14839
14906
  return bad(`unit ${id} is not a directory`);
14840
- bytes = readFileSync48(rp);
14907
+ bytes = readFileSync49(rp);
14841
14908
  } catch {
14842
14909
  return bad(`unit ${id} sub-receipt missing`);
14843
14910
  }
14844
14911
  if (sha3(bytes) !== e["sub_receipt_sha256"])
14845
14912
  return bad(`unit ${id} sub-receipt does not match its recorded hash`);
14846
- const evSha = existsSync40(ep) ? sha3(readFileSync48(ep)) : null;
14913
+ const evSha = existsSync41(ep) ? sha3(readFileSync49(ep)) : null;
14847
14914
  if (evSha !== (e["events_file_sha256"] ?? null))
14848
14915
  return bad(`unit ${id} events.jsonl does not match its recorded hash`);
14849
14916
  const sub = readJson5(rp);
@@ -14866,15 +14933,15 @@ function compositeVerdict(childVerdicts) {
14866
14933
  const failed2 = childVerdicts.filter((v) => v === "FAILED" || !["VERIFIED", "ALREADY_SATISFIED", "PARTIAL", "SPEC_CONFLICT"].includes(v)).length;
14867
14934
  return capGroupVerdict(base, { section: undefined, notProven: [], problems: failed2, allUnitsPass: childVerdicts.every((v) => PASSING.has(v)) });
14868
14935
  }
14869
- var ID_RE, PASSING, sha3 = (b) => createHash17("sha256").update(b).digest("hex"), isObj10 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), text2 = (v, cap) => typeof v === "string" ? v.replace(/[\x00-\x1f\x7f]+/g, " ").trim().slice(0, cap) : "", num4 = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0, unitsDir = (runDir) => join63(runDir, "group", "units"), readJson5 = (p) => {
14936
+ var ID_RE, PASSING, sha3 = (b) => createHash17("sha256").update(b).digest("hex"), isObj10 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), text2 = (v, cap) => typeof v === "string" ? v.replace(/[\x00-\x1f\x7f]+/g, " ").trim().slice(0, cap) : "", num4 = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0, unitsDir = (runDir) => join64(runDir, "group", "units"), readJson5 = (p) => {
14870
14937
  try {
14871
- return JSON.parse(readFileSync48(p, "utf8"));
14938
+ return JSON.parse(readFileSync49(p, "utf8"));
14872
14939
  } catch {
14873
14940
  return;
14874
14941
  }
14875
14942
  }, dirNames = (d) => {
14876
14943
  try {
14877
- return readdirSync20(d).filter((n3) => !n3.startsWith(".")).sort();
14944
+ return readdirSync21(d).filter((n3) => !n3.startsWith(".")).sort();
14878
14945
  } catch {
14879
14946
  return null;
14880
14947
  }
@@ -14886,8 +14953,8 @@ var init_seal_group = __esm(() => {
14886
14953
  });
14887
14954
 
14888
14955
  // ../../loki-ts/src/supply/supply_guard.ts
14889
- import { existsSync as existsSync41, readFileSync as readFileSync49, statSync as statSync20 } from "fs";
14890
- import { basename as basename21, join as join64 } from "path";
14956
+ import { existsSync as existsSync42, readFileSync as readFileSync50, statSync as statSync20 } from "fs";
14957
+ import { basename as basename22, join as join65 } from "path";
14891
14958
  function supplyEnabled(env) {
14892
14959
  return env["LOKI_SUPPLY_GUARD"] !== "0";
14893
14960
  }
@@ -14899,16 +14966,16 @@ function supplyVerdict(verdict, r) {
14899
14966
  return r.blocked && verdict === "VERIFIED" ? "FAILED" : verdict;
14900
14967
  }
14901
14968
  function isManifestPath(path) {
14902
- return MANIFESTS.test(basename21(path));
14969
+ return MANIFESTS.test(basename22(path));
14903
14970
  }
14904
14971
  function readDeclared(repoDir) {
14905
- const p = join64(repoDir, ".loki", DECLARED_FILE);
14906
- if (!existsSync41(p))
14972
+ const p = join65(repoDir, ".loki", DECLARED_FILE);
14973
+ if (!existsSync42(p))
14907
14974
  return { deps: [], problem: null };
14908
14975
  try {
14909
14976
  if (statSync20(p).size > MAX_FILE_BYTES)
14910
14977
  return { deps: [], problem: "declaration file too large" };
14911
- const j = JSON.parse(readFileSync49(p, "utf8"));
14978
+ const j = JSON.parse(readFileSync50(p, "utf8"));
14912
14979
  if (!Array.isArray(j))
14913
14980
  return { deps: [], problem: "declaration is not a JSON array" };
14914
14981
  const deps = [];
@@ -14928,11 +14995,11 @@ function readDeclared(repoDir) {
14928
14995
  }
14929
14996
  }
14930
14997
  function readAllowlist(repoDir) {
14931
- const p = join64(repoDir, ".loki", "supply-allowlist");
14932
- if (!existsSync41(p))
14998
+ const p = join65(repoDir, ".loki", "supply-allowlist");
14999
+ if (!existsSync42(p))
14933
15000
  return new Set;
14934
15001
  try {
14935
- return new Set(readFileSync49(p, "utf8").split(`
15002
+ return new Set(readFileSync50(p, "utf8").split(`
14936
15003
  `).map((l) => l.replace(/#.*$/, "").trim()).filter(Boolean));
14937
15004
  } catch {
14938
15005
  return new Set;
@@ -14973,7 +15040,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
14973
15040
  if (eco === "npm") {
14974
15041
  if (privateUrlList([env["npm_config_registry"] ?? "", env["NPM_CONFIG_REGISTRY"] ?? ""]))
14975
15042
  return true;
14976
- return files(join64(repoDir, ".npmrc"), home ? join64(home, ".npmrc") : "").some((t) => t.split(`
15043
+ return files(join65(repoDir, ".npmrc"), home ? join65(home, ".npmrc") : "").some((t) => t.split(`
14977
15044
  `).some((l) => {
14978
15045
  const m = /^\s*(?:(@[^:\s]+):)?registry\s*=\s*(\S+)/.exec(l);
14979
15046
  return !!m && privateUrl(m[2]) && (m[1] === undefined || name.startsWith(`${m[1]}/`));
@@ -14982,7 +15049,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
14982
15049
  if (eco === "pypi") {
14983
15050
  if (privateUrlList([env["PIP_INDEX_URL"] ?? "", env["PIP_EXTRA_INDEX_URL"] ?? ""]))
14984
15051
  return true;
14985
- const cfg = [env["PIP_CONFIG_FILE"] ?? "", home ? join64(home, ".config", "pip", "pip.conf") : "", home ? join64(home, ".pip", "pip.conf") : "", join64(repoDir, "pip.conf")];
15052
+ const cfg = [env["PIP_CONFIG_FILE"] ?? "", home ? join65(home, ".config", "pip", "pip.conf") : "", home ? join65(home, ".pip", "pip.conf") : "", join65(repoDir, "pip.conf")];
14986
15053
  return files(...cfg).some((t) => t.split(`
14987
15054
  `).some((l) => {
14988
15055
  const m = /^\s*(?:extra-)?index-url\s*[=:]\s*(.+)$/.exec(l);
@@ -14992,7 +15059,7 @@ function userConfigPrivate(eco, repoDir, env, goEnv = {}, name = "") {
14992
15059
  if (eco === "cargo") {
14993
15060
  if (Object.keys(env).some((k) => /^CARGO_REGISTRIES_.+_INDEX$/.test(k) || /^CARGO_SOURCE_/.test(k)))
14994
15061
  return true;
14995
- return files(join64(repoDir, ".cargo", "config.toml"), join64(repoDir, ".cargo", "config"), home ? join64(home, ".cargo", "config.toml") : "", home ? join64(home, ".cargo", "config") : "").some((t) => /^\s*\[(registries\.|source\.)/m.test(t) || /replace-with\s*=/.test(t));
15062
+ return files(join65(repoDir, ".cargo", "config.toml"), join65(repoDir, ".cargo", "config"), home ? join65(home, ".cargo", "config.toml") : "", home ? join65(home, ".cargo", "config") : "").some((t) => /^\s*\[(registries\.|source\.)/m.test(t) || /replace-with\s*=/.test(t));
14996
15063
  }
14997
15064
  if (eco === "go") {
14998
15065
  const gp = goEnv["GOPROXY"] ?? env["GOPROXY"] ?? "";
@@ -15115,7 +15182,7 @@ var MIN_AGE_DAYS = 7, DECLARED_FILE = "supply-declared.json", MAX_CHECKED = 50,
15115
15182
  }
15116
15183
  }, PUBLIC_HOSTS, hostOf = (u) => u.trim().toLowerCase().replace(/^[a-z][a-z0-9+.-]*:\/\//, "").replace(/^www\./, "").split(/[/?#\s]/)[0].replace(/^[^@]*@/, "").replace(/:\d+$/, ""), privateUrl = (u) => /[a-z0-9]/i.test(u) && !PUBLIC_HOSTS.has(hostOf(u)), readSmall = (p) => {
15117
15184
  try {
15118
- return statSync20(p).size <= MAX_FILE_BYTES ? readFileSync49(p, "utf8") : "";
15185
+ return statSync20(p).size <= MAX_FILE_BYTES ? readFileSync50(p, "utf8") : "";
15119
15186
  } catch {
15120
15187
  return "";
15121
15188
  }
@@ -15131,8 +15198,8 @@ var init_supply_guard = __esm(() => {
15131
15198
 
15132
15199
  // ../../loki-ts/src/engine10/stages/seal.ts
15133
15200
  import { createHash as createHash18 } from "crypto";
15134
- import { existsSync as existsSync42, readdirSync as readdirSync21, mkdirSync as mkdirSync29, readFileSync as readFileSync50, writeFileSync as writeFileSync31 } from "fs";
15135
- import { basename as basename22, isAbsolute as isAbsolute9, join as join65, relative as relative9 } from "path";
15201
+ import { existsSync as existsSync43, readdirSync as readdirSync22, mkdirSync as mkdirSync29, readFileSync as readFileSync51, writeFileSync as writeFileSync31 } from "fs";
15202
+ import { basename as basename23, isAbsolute as isAbsolute10, join as join66, relative as relative10 } from "path";
15136
15203
  function sanitizeReason(s) {
15137
15204
  const collapsed = s.replace(/[\x00-\x1f\x7f]+/g, " ").trim();
15138
15205
  const capped = collapsed.length > 500 ? `${collapsed.slice(0, 500)}...` : collapsed;
@@ -15207,8 +15274,8 @@ function renderReceiptMd(r) {
15207
15274
  `);
15208
15275
  }
15209
15276
  var DEEP_NOT_PROVEN, SIGNING_UNAVAILABLE = "receipt signing unavailable (no usable signing key: invalid key or unwritable ~/.loki/keys)", EXCLUDE_LOKI = ":(exclude).loki", sha2562 = (s) => createHash18("sha256").update(s).digest("hex"), str3 = (v) => typeof v === "string" && v !== "" ? v : null, strs2 = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string" && x !== "") : [], receiptRel = (ctx) => {
15210
- const r = relative9(ctx.repoDir, join65(ctx.runDir, "receipt.json"));
15211
- return r.startsWith("..") || isAbsolute9(r) ? `.loki/runs/${ctx.runId}/receipt.json` : r;
15277
+ const r = relative10(ctx.repoDir, join66(ctx.runDir, "receipt.json"));
15278
+ return r.startsWith("..") || isAbsolute10(r) ? `.loki/runs/${ctx.runId}/receipt.json` : r;
15212
15279
  }, commitStage, sealStage;
15213
15280
  var init_seal = __esm(() => {
15214
15281
  init_spec_file();
@@ -15307,6 +15374,8 @@ var init_seal = __esm(() => {
15307
15374
  }
15308
15375
  if (wallNotRun > 0)
15309
15376
  notProven.add(`wall base run not_run: ${wallNotRun}`);
15377
+ for (const n3 of strs2(o.wall?.not_proven))
15378
+ notProven.add(n3);
15310
15379
  for (const d of Array.isArray(o.wall?.discarded) ? o.wall.discarded : [])
15311
15380
  notProven.add(`wall test discarded: ${String(d.file)} (${String(d.reason)})`);
15312
15381
  for (const d of Array.isArray(o.wall?.not_run_files) ? o.wall.not_run_files : [])
@@ -15315,8 +15384,8 @@ var init_seal = __esm(() => {
15315
15384
  notProven.add(`Wall test not executed: ${wallNotRun} file(s), no reason recorded`);
15316
15385
  if (wallNotRun > 0) {
15317
15386
  try {
15318
- const kept = new Set((Array.isArray(o.wall?.files) ? o.wall.files : []).map((f) => basename22(String(f.path))));
15319
- for (const n3 of readdirSync21(join65(ctx.runDir, "wall")).sort())
15387
+ const kept = new Set((Array.isArray(o.wall?.files) ? o.wall.files : []).map((f) => basename23(String(f.path))));
15388
+ for (const n3 of readdirSync22(join66(ctx.runDir, "wall")).sort())
15320
15389
  if (!kept.has(n3))
15321
15390
  notProven.add(`wall test discarded: ${n3} (not_run)`);
15322
15391
  } catch {}
@@ -15379,19 +15448,19 @@ var init_seal = __esm(() => {
15379
15448
  for (const [s, d] of Object.entries(o))
15380
15449
  if (typeof d?.duration_s === "number")
15381
15450
  stages[s] = d.duration_s;
15382
- const T = hooks.time, time = T ? T.build(ctx, stages, T.firstEventMs(join65(ctx.runDir, "events.jsonl"))) : { wall_s: Object.values(stages).reduce((a, b) => a + (b ?? 0), 0), stages }, totalS = T?.reconciled(time) ?? null;
15451
+ const T = hooks.time, time = T ? T.build(ctx, stages, T.firstEventMs(join66(ctx.runDir, "events.jsonl"))) : { wall_s: Object.values(stages).reduce((a, b) => a + (b ?? 0), 0), stages }, totalS = T?.reconciled(time) ?? null;
15383
15452
  const iterIds = Object.values(o).flatMap((d) => [...strs2(d?.iteration_ids), ...strs2([d?.iteration_id])]);
15384
15453
  if (iterIds.length === 0)
15385
15454
  notProven.add("cost not measured (no iteration ids recorded)");
15386
15455
  const cost = ctx.cost.read(ctx.repoDir, iterIds);
15387
15456
  if (cost.unmetered)
15388
15457
  notProven.add("cost unmetered (CLI invoker; recorded as 0)");
15389
- const eventsPath = join65(ctx.runDir, "events.jsonl");
15458
+ const eventsPath = join66(ctx.runDir, "events.jsonl");
15390
15459
  const wallFiles = Array.isArray(o.wall?.files) ? o.wall.files : [];
15391
15460
  const wallPassed = typeof o.verify?.wall_passed === "boolean" ? o.verify.wall_passed : null;
15392
15461
  if (wallFiles.length > 0 && wallPassed === null)
15393
15462
  notProven.add("wall result not recorded by verify");
15394
- const routeBlock = buildRouteBlock(process.env, ctx.provider, o.implement?.route ?? o.plan?.route_record ?? (routerEnabled(process.env) ? loadRouteRecord(ctx.runDir) : undefined), cost.router ?? (routerEnabled(process.env) ? sumResultCosts(join65(ctx.repoDir, ".loki"), liveArchivedCosts(join65(ctx.repoDir, ".loki"), iterIds, UNMETERED)).router : undefined), ctx.model);
15463
+ const routeBlock = buildRouteBlock(process.env, ctx.provider, o.implement?.route ?? o.plan?.route_record ?? (routerEnabled(process.env) ? loadRouteRecord(ctx.runDir) : undefined), cost.router ?? (routerEnabled(process.env) ? sumResultCosts(join66(ctx.repoDir, ".loki"), liveArchivedCosts(join66(ctx.repoDir, ".loki"), iterIds, UNMETERED)).router : undefined), ctx.model);
15395
15464
  if (routeBlock)
15396
15465
  for (const l of routeNotProven(routeBlock))
15397
15466
  notProven.add(l);
@@ -15433,7 +15502,7 @@ var init_seal = __esm(() => {
15433
15502
  provider: ctx.provider,
15434
15503
  model: ctx.model,
15435
15504
  resumed: o.intake?.resumed === true,
15436
- events_sha256: sha2562(existsSync42(eventsPath) ? readFileSync50(eventsPath) : ""),
15505
+ events_sha256: sha2562(existsSync43(eventsPath) ? readFileSync51(eventsPath) : ""),
15437
15506
  ...await sealEvidence(ctx.repoDir, ctx.runDir, o, notProven, signal, ctx.emit),
15438
15507
  log_seal: true,
15439
15508
  ...receiptBlock(process.env, cost.usd, cost.unmetered === true, totalS),
@@ -15455,10 +15524,10 @@ var init_seal = __esm(() => {
15455
15524
  }
15456
15525
  const receipt = { ...body, receipt_sha256: hash, verification: { jwt: sig.jwt, kid: sig.kid } };
15457
15526
  mkdirSync29(ctx.runDir, { recursive: true });
15458
- const path = join65(ctx.runDir, "receipt.json");
15527
+ const path = join66(ctx.runDir, "receipt.json");
15459
15528
  writeFileSync31(path, JSON.stringify(receipt, null, 2) + `
15460
15529
  `);
15461
- writeFileSync31(join65(ctx.runDir, "receipt.md"), renderReceiptMd(receipt));
15530
+ writeFileSync31(join66(ctx.runDir, "receipt.md"), renderReceiptMd(receipt));
15462
15531
  recordRun(process.env, ctx.repoDir, ranModel(o.implement, ctx.model, o.fix), verdict, cost.usd, cost.unmetered === true, totalS);
15463
15532
  try {
15464
15533
  hooks.sealed?.(ctx.runDir, JSON.parse(JSON.stringify(receipt), (_k, v) => v && typeof v === "object" ? Object.freeze(v) : v));
@@ -15484,7 +15553,7 @@ var init_seal = __esm(() => {
15484
15553
 
15485
15554
  // ../../loki-ts/src/features/receipt_dsse.ts
15486
15555
  import { createPublicKey as createPublicKey3, sign as sign2, verify as verify3 } from "crypto";
15487
- import { readFileSync as readFileSync51 } from "fs";
15556
+ import { readFileSync as readFileSync52 } from "fs";
15488
15557
  function pae(payloadType, body) {
15489
15558
  const t = Buffer.from(payloadType, "utf8");
15490
15559
  return Buffer.concat([Buffer.from(`DSSEv1 ${t.length} `), t, Buffer.from(` ${body.length} `), body]);
@@ -15561,7 +15630,7 @@ function verifyDsseReceipt(env, d) {
15561
15630
  }
15562
15631
  function runIdGuard(receiptPath, runId) {
15563
15632
  try {
15564
- return envelopeRunIdProblem(JSON.parse(readFileSync51(receiptPath, "utf8")), runId);
15633
+ return envelopeRunIdProblem(JSON.parse(readFileSync52(receiptPath, "utf8")), runId);
15565
15634
  } catch {
15566
15635
  return null;
15567
15636
  }
@@ -15570,14 +15639,14 @@ var DSSE_PAYLOAD_TYPE = "application/vnd.in-toto+json", STATEMENT_TYPE = "https:
15570
15639
  var init_receipt_dsse = () => {};
15571
15640
 
15572
15641
  // ../../loki-ts/src/util/composite_seal.ts
15573
- import { existsSync as existsSync43, readFileSync as readFileSync52 } from "fs";
15574
- import { basename as basename23, dirname as dirname29, join as join66 } from "path";
15642
+ import { existsSync as existsSync44, readFileSync as readFileSync53 } from "fs";
15643
+ import { basename as basename24, dirname as dirname29, join as join67 } from "path";
15575
15644
  function logProblem(runDir, integ) {
15576
15645
  if (typeof integ["log_sha256"] !== "string")
15577
15646
  return null;
15578
15647
  let b;
15579
15648
  try {
15580
- b = readFileSync52(join66(runDir, "integration.log"));
15649
+ b = readFileSync53(join67(runDir, "integration.log"));
15581
15650
  } catch {
15582
15651
  return "integration.log is missing but integration.json records its hash";
15583
15652
  }
@@ -15600,13 +15669,13 @@ async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
15600
15669
  return bad("body malformed");
15601
15670
  let ibytes;
15602
15671
  try {
15603
- ibytes = readFileSync52(join66(runDir, "integration.json"));
15672
+ ibytes = readFileSync53(join67(runDir, "integration.json"));
15604
15673
  } catch {
15605
15674
  return bad("integration.json missing");
15606
15675
  }
15607
15676
  if (sha3(ibytes) !== receipt["integration_sha256"])
15608
15677
  return bad("integration.json does not match its recorded hash");
15609
- const integ = readJson5(join66(runDir, "integration.json"));
15678
+ const integ = readJson5(join67(runDir, "integration.json"));
15610
15679
  if (!isObj10(integ) || !isObj10(integ["outcomes"]))
15611
15680
  return bad("integration.json has no outcomes");
15612
15681
  const iprob = integrationProblem(integ);
@@ -15636,10 +15705,10 @@ async function verifyComposite(receiptPath, receipt, rh, verifyOne, deps = {}) {
15636
15705
  return bad(`child ${text2(repo, 80) || "?"} has an invalid receipt path`);
15637
15706
  if (outcomes[repo] !== "ok")
15638
15707
  return bad(`child ${text2(repo, 80)} did not finish ok in integration.json`);
15639
- const rp = join66(runDir, rel);
15708
+ const rp = join67(runDir, rel);
15640
15709
  let bytes;
15641
15710
  try {
15642
- bytes = readFileSync52(rp);
15711
+ bytes = readFileSync53(rp);
15643
15712
  } catch {
15644
15713
  return bad(`child ${repo} receipt missing`);
15645
15714
  }
@@ -15688,8 +15757,8 @@ var init_keys_cmd = __esm(() => {
15688
15757
  });
15689
15758
 
15690
15759
  // ../../loki-ts/src/engine10/verify_cmd.ts
15691
- import { existsSync as existsSync44, readFileSync as readFileSync53, renameSync as renameSync13, statSync as statSync22, writeFileSync as writeFileSync32 } from "fs";
15692
- import { basename as basename24, dirname as dirname30, join as join67 } from "path";
15760
+ import { existsSync as existsSync45, readFileSync as readFileSync54, renameSync as renameSync13, statSync as statSync22, writeFileSync as writeFileSync32 } from "fs";
15761
+ import { basename as basename25, dirname as dirname30, join as join68 } from "path";
15693
15762
  import { createHash as createHash19, createPublicKey as createPublicKey4, verify as verify4 } from "crypto";
15694
15763
  function pubFor(kid, given) {
15695
15764
  if (given)
@@ -15697,7 +15766,7 @@ function pubFor(kid, given) {
15697
15766
  const active = loadSigningKey(false);
15698
15767
  const pubs = (process.env["LOKI_RECEIPT_RETIRED_PUBKEYS"] ?? "").split(":").map((f) => f.trim()).filter(Boolean).flatMap((f) => {
15699
15768
  try {
15700
- return [createPublicKey4(readFileSync53(f))];
15769
+ return [createPublicKey4(readFileSync54(f))];
15701
15770
  } catch {
15702
15771
  return [];
15703
15772
  }
@@ -15741,10 +15810,10 @@ function checkEventLog(receiptPath, receipt) {
15741
15810
  const claims = st !== null && typeof st === "object" && Object.keys(st).length > 0;
15742
15811
  return claims ? "the receipt records stages but binds the empty-log hash, so no events.jsonl can back it (missing, empty or non-empty); the receipt is forged or was sealed without a log. Re-run the task to produce a fresh receipt" : null;
15743
15812
  }
15744
- const path = join67(dirname30(receiptPath), "events.jsonl");
15745
- if (!existsSync44(path))
15813
+ const path = join68(dirname30(receiptPath), "events.jsonl");
15814
+ if (!existsSync45(path))
15746
15815
  return "events.jsonl is missing";
15747
- const raw2 = readFileSync53(path, "utf8"), events2 = readEvents(path), lines2 = raw2.split(`
15816
+ const raw2 = readFileSync54(path, "utf8"), events2 = readEvents(path), lines2 = raw2.split(`
15748
15817
  `).filter((l) => l.trim() !== "");
15749
15818
  if (events2.length !== lines2.length || events2.some((e, i) => e.seq !== i))
15750
15819
  return "events.jsonl has a forged, edited or missing line";
@@ -15760,7 +15829,7 @@ function checkEventLog(receiptPath, receipt) {
15760
15829
  return h.digest("hex") === bound ? null : "events.jsonl does not match the hash recorded at seal";
15761
15830
  }
15762
15831
  function checkLogSeal(receiptPath, hash, kid, given) {
15763
- const path = join67(dirname30(receiptPath), "events.jsonl"), events2 = readEvents(path), done = events2.findIndex((e) => e.type === "run.completed");
15832
+ const path = join68(dirname30(receiptPath), "events.jsonl"), events2 = readEvents(path), done = events2.findIndex((e) => e.type === "run.completed");
15764
15833
  if (!events2.some((e) => e.type === "receipt.sealed" && e.data["receipt_sha256"] === hash))
15765
15834
  return { verdict: "TAMPERED", reason: "events.jsonl has no receipt.sealed event for this receipt" };
15766
15835
  if (done < 0)
@@ -15768,7 +15837,7 @@ function checkLogSeal(receiptPath, hash, kid, given) {
15768
15837
  const seal = events2[done + 1], d = seal?.type === "log.sealed" ? seal.data : null;
15769
15838
  if (!d)
15770
15839
  return { verdict: "TAMPERED", reason: "events.jsonl has no signed log.sealed line after run.completed" };
15771
- const lines2 = readFileSync53(path, "utf8").split(`
15840
+ const lines2 = readFileSync54(path, "utf8").split(`
15772
15841
  `).filter((l) => l.trim() !== ""), sha4 = createHash19("sha256").update(lines2.slice(0, done + 1).join(`
15773
15842
  `) + `
15774
15843
  `).digest("hex");
@@ -15778,11 +15847,11 @@ function checkLogSeal(receiptPath, hash, kid, given) {
15778
15847
  return null;
15779
15848
  }
15780
15849
  async function verifyReceipt(receiptPath, deps = {}) {
15781
- if (!existsSync44(receiptPath))
15850
+ if (!existsSync45(receiptPath))
15782
15851
  return { verdict: "UNCHECKED", reasons: [`receipt not found: ${receiptPath}`] };
15783
15852
  let receipt;
15784
15853
  try {
15785
- receipt = JSON.parse((deps.read ?? ((p) => readFileSync53(p, "utf8")))(receiptPath));
15854
+ receipt = JSON.parse((deps.read ?? ((p) => readFileSync54(p, "utf8")))(receiptPath));
15786
15855
  } catch {
15787
15856
  return { verdict: "UNCHECKED", reasons: ["receipt.json is not valid JSON"] };
15788
15857
  }
@@ -15870,8 +15939,8 @@ var init_verify_cmd = __esm(() => {
15870
15939
  });
15871
15940
 
15872
15941
  // src/server/app.ts
15873
- import { existsSync as existsSync46, readFileSync as readFileSync56, statSync as statSync23 } from "fs";
15874
- import { join as join70, resolve as resolve15, sep as sep13 } from "path";
15942
+ import { existsSync as existsSync47, readFileSync as readFileSync57, statSync as statSync23 } from "fs";
15943
+ import { join as join71, resolve as resolve15, sep as sep14 } from "path";
15875
15944
 
15876
15945
  // node_modules/hono/dist/request/constants.js
15877
15946
  var GET_MATCH_RESULT = Symbol();
@@ -26153,9 +26222,9 @@ function mount20(ctx) {
26153
26222
  }
26154
26223
 
26155
26224
  // src/server/routes/verify.ts
26156
- import { readFileSync as readFileSync54, realpathSync as realpathSync21 } from "fs";
26225
+ import { readFileSync as readFileSync55, realpathSync as realpathSync22 } from "fs";
26157
26226
  import { createPublicKey as createPublicKey5 } from "crypto";
26158
- import { join as join68, sep as sep12 } from "path";
26227
+ import { join as join69, sep as sep13 } from "path";
26159
26228
  init_verify_cmd();
26160
26229
  init_seal();
26161
26230
  init_receipt_dsse();
@@ -26182,15 +26251,15 @@ function mount21(ctx) {
26182
26251
  return done(404, "receipt not available", "not_found");
26183
26252
  let runDir, file;
26184
26253
  try {
26185
- const root = realpathSync21(join68(repo.p, ".loki", "runs"));
26186
- runDir = realpathSync21(join68(root, run2));
26187
- if (runDir !== join68(root, run2))
26254
+ const root = realpathSync22(join69(repo.p, ".loki", "runs"));
26255
+ runDir = realpathSync22(join69(root, run2));
26256
+ if (runDir !== join69(root, run2))
26188
26257
  return done(404, "receipt not found", "not_found");
26189
- file = realpathSync21(join68(runDir, "receipt.json"));
26258
+ file = realpathSync22(join69(runDir, "receipt.json"));
26190
26259
  } catch {
26191
26260
  return done(404, "receipt not found", "not_found");
26192
26261
  }
26193
- if (!file.startsWith(runDir + sep12))
26262
+ if (!file.startsWith(runDir + sep13))
26194
26263
  return done(404, "receipt not found", "not_found");
26195
26264
  let integrity, reasons, sha4 = null, outcome = "UNREADABLE";
26196
26265
  try {
@@ -26205,7 +26274,7 @@ function mount21(ctx) {
26205
26274
  sha4 = r.receiptSha256 ?? null;
26206
26275
  }
26207
26276
  try {
26208
- outcome = outcomeOf(JSON.parse(readFileSync54(file, "utf8")));
26277
+ outcome = outcomeOf(JSON.parse(readFileSync55(file, "utf8")));
26209
26278
  } catch {
26210
26279
  outcome = "UNREADABLE";
26211
26280
  }
@@ -26267,8 +26336,8 @@ function ttlCache(ttlMs = PROBE_CACHE_MS, now2 = Date.now) {
26267
26336
  }
26268
26337
 
26269
26338
  // src/server/legacy/shim.ts
26270
- import { existsSync as existsSync45, readFileSync as readFileSync55 } from "fs";
26271
- import { join as join69 } from "path";
26339
+ import { existsSync as existsSync46, readFileSync as readFileSync56 } from "fs";
26340
+ import { join as join70 } from "path";
26272
26341
 
26273
26342
  // src/server/legacy/routes.ts
26274
26343
  var LEGACY_ROUTES = [
@@ -26646,10 +26715,10 @@ var logged = new Set;
26646
26715
  var toHono = (p) => p.replace(/\{([A-Za-z_]+):path\}/g, ":$1{.+}").replace(/\{([A-Za-z_]+)\}/g, ":$1");
26647
26716
  var NOT_SUPPORTED = "not yet supported by the Control Plane";
26648
26717
  var repoVersion = () => {
26649
- for (const f of [join69(import.meta.dir, "../../../../../VERSION")]) {
26718
+ for (const f of [join70(import.meta.dir, "../../../../../VERSION")]) {
26650
26719
  try {
26651
- if (existsSync45(f))
26652
- return readFileSync55(f, "utf8").trim();
26720
+ if (existsSync46(f))
26721
+ return readFileSync56(f, "utf8").trim();
26653
26722
  } catch {}
26654
26723
  }
26655
26724
  return "unknown";
@@ -26831,7 +26900,7 @@ function legacyShim(opts) {
26831
26900
 
26832
26901
  // src/server/app.ts
26833
26902
  var MAX_BODY2 = 1e6;
26834
- var defaultUiDir = () => [join70(import.meta.dir, "../../ui/dist"), join70(import.meta.dir, "../ui/dist")].find((d) => existsSync46(join70(d, "index.html")));
26903
+ var defaultUiDir = () => [join71(import.meta.dir, "../../ui/dist"), join71(import.meta.dir, "../ui/dist")].find((d) => existsSync47(join71(d, "index.html")));
26835
26904
  function createApp(opts) {
26836
26905
  const uiDir = opts.uiDir ?? defaultUiDir();
26837
26906
  const { db, sqlite } = openDb(opts.dbPath);
@@ -26860,10 +26929,10 @@ function createApp(opts) {
26860
26929
  await next();
26861
26930
  });
26862
26931
  const readInstalled = () => {
26863
- for (const f of [process.env.LOKI_VERSION_FILE, join70(import.meta.dir, "../../../../VERSION")]) {
26932
+ for (const f of [process.env.LOKI_VERSION_FILE, join71(import.meta.dir, "../../../../VERSION")]) {
26864
26933
  try {
26865
26934
  if (f)
26866
- return readFileSync56(f, "utf8").trim() || "unknown";
26935
+ return readFileSync57(f, "utf8").trim() || "unknown";
26867
26936
  } catch {}
26868
26937
  }
26869
26938
  return "unknown";
@@ -26974,11 +27043,11 @@ function createApp(opts) {
26974
27043
  return c.json({ error: "not found" }, 404);
26975
27044
  const root = resolve15(uiDir);
26976
27045
  const f = resolve15(root, `.${p}`);
26977
- if (f.startsWith(root + sep13) && existsSync46(f) && statSync23(f).isFile())
27046
+ if (f.startsWith(root + sep14) && existsSync47(f) && statSync23(f).isFile())
26978
27047
  return new Response(Bun.file(f));
26979
27048
  if (/\.[a-z0-9]+$/i.test(p))
26980
27049
  return c.json({ error: "not found" }, 404);
26981
- return new Response(Bun.file(join70(root, "index.html")));
27050
+ return new Response(Bun.file(join71(root, "index.html")));
26982
27051
  });
26983
27052
  return { app, db, close: () => {
26984
27053
  clearInterval(reconciler);