loki-mode 11.82.0 → 11.84.0

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 (69) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/autonomy/lib/telemetry-schema.json +1 -1
  4. package/autonomy/telemetry.sh +1 -1
  5. package/dashboard/__init__.py +1 -1
  6. package/docs/CLI-REFERENCE.md +1 -1
  7. package/docs/INSTALLATION.md +1 -1
  8. package/loki-ts/dist/loki.js +1362 -1341
  9. package/mcp/__init__.py +1 -1
  10. package/package.json +2 -2
  11. package/packages/control-plane/dist/server.js +401 -106
  12. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  13. package/web-app/dist/assets/{AdminPage-BDwJkrfT.js → AdminPage-CXLv81So.js} +1 -1
  14. package/web-app/dist/assets/{Avatar-Bjb7tmLG.js → Avatar-Dkquf4s9.js} +1 -1
  15. package/web-app/dist/assets/{Badge-BYWNt-lF.js → Badge-BPlO-Wiw.js} +1 -1
  16. package/web-app/dist/assets/{Button-CEKS68UU.js → Button-BO-JvVyh.js} +1 -1
  17. package/web-app/dist/assets/{CockpitPage-fAeYAB91.js → CockpitPage-DCuXv1OL.js} +1 -1
  18. package/web-app/dist/assets/{ComparePage-DRiaB5aq.js → ComparePage-zVSpiuEp.js} +1 -1
  19. package/web-app/dist/assets/{ErrorBoundary-C_ts0y6d.js → ErrorBoundary-Ci4wqP2a.js} +1 -1
  20. package/web-app/dist/assets/{EvidenceReceiptPanel-CAM2bOHh.js → EvidenceReceiptPanel-CEBhqO60.js} +1 -1
  21. package/web-app/dist/assets/{GitHubIssuesPanel-eTpdboWA.js → GitHubIssuesPanel-UR6xkpVn.js} +1 -1
  22. package/web-app/dist/assets/{GitHubPRsPanel-ufk1eqQm.js → GitHubPRsPanel-BspmPZ6K.js} +1 -1
  23. package/web-app/dist/assets/{HomePage-D8Cg8c0d.js → HomePage-DchBOs8o.js} +2 -2
  24. package/web-app/dist/assets/{LoginPage-DWVzDN9I.js → LoginPage-BldlfUlE.js} +1 -1
  25. package/web-app/dist/assets/{MagicPage-bmS03_51.js → MagicPage-CVnhnrh6.js} +1 -1
  26. package/web-app/dist/assets/{MetricsPage-ffCkhsSV.js → MetricsPage-I_Ye6IjS.js} +1 -1
  27. package/web-app/dist/assets/{NotFoundPage-CqluOiCR.js → NotFoundPage-CCDI4T7K.js} +1 -1
  28. package/web-app/dist/assets/{ProjectPage-D5XbTRQt.js → ProjectPage-DuyA8Qz7.js} +3 -3
  29. package/web-app/dist/assets/{ProjectsPage-BK4mJziQ.js → ProjectsPage-BF2JSz1r.js} +1 -1
  30. package/web-app/dist/assets/{SettingsPage-BoH4mS-n.js → SettingsPage-B_5LeF6K.js} +1 -1
  31. package/web-app/dist/assets/{ShowcasePage-B7xHXyht.js → ShowcasePage-lE5cIgbU.js} +1 -1
  32. package/web-app/dist/assets/{SystemSettingsPage-BFyzSmVR.js → SystemSettingsPage-v2DJyogx.js} +1 -1
  33. package/web-app/dist/assets/{TeamsPage-DkuTf7Pm.js → TeamsPage-eXMmORI1.js} +1 -1
  34. package/web-app/dist/assets/{TemplatesPage-DqC4qY5U.js → TemplatesPage-CkHulSrT.js} +1 -1
  35. package/web-app/dist/assets/{TerminalOutput-CiERRLAB.js → TerminalOutput-DJwjzb2Y.js} +1 -1
  36. package/web-app/dist/assets/{activity-BBdRZTad.js → activity-CAtLpfNe.js} +1 -1
  37. package/web-app/dist/assets/{bell-CvIl2nxi.js → bell-CL-IIbCA.js} +1 -1
  38. package/web-app/dist/assets/{bot-CWMB2JQE.js → bot-fT57nwl5.js} +1 -1
  39. package/web-app/dist/assets/{check-CSVvxOtd.js → check-hWhzzw0m.js} +1 -1
  40. package/web-app/dist/assets/{chevron-left-B7MXj-CB.js → chevron-left-BLHNp2u-.js} +1 -1
  41. package/web-app/dist/assets/{circle-alert-DlegpSSz.js → circle-alert-BiPOqU-L.js} +1 -1
  42. package/web-app/dist/assets/{clock-CO7alYth.js → clock-Cqcvrmkj.js} +1 -1
  43. package/web-app/dist/assets/{cloud-CmCwC9tD.js → cloud-DUijmoIE.js} +1 -1
  44. package/web-app/dist/assets/{code-xml-CttGX_KN.js → code-xml-CHpO2Oxh.js} +1 -1
  45. package/web-app/dist/assets/{database-BFoEsl1d.js → database-DggasNHP.js} +1 -1
  46. package/web-app/dist/assets/{dollar-sign-CsX8E6iv.js → dollar-sign-CXxG_8K6.js} +1 -1
  47. package/web-app/dist/assets/{file-code-corner-AD_LP7Sr.js → file-code-corner-xfVvREvW.js} +1 -1
  48. package/web-app/dist/assets/{file-plus-D1lrSELb.js → file-plus-CxboFD8a.js} +1 -1
  49. package/web-app/dist/assets/{globe-BO79vdlK.js → globe-uQo7wmFo.js} +1 -1
  50. package/web-app/dist/assets/{hammer-ByRAYTmN.js → hammer-DpmqB3Jc.js} +1 -1
  51. package/web-app/dist/assets/{index-Dhf-7-HA.js → index-DSecwFL3.js} +3 -3
  52. package/web-app/dist/assets/{layers-Ch8twnaQ.js → layers-DAhv2mJy.js} +1 -1
  53. package/web-app/dist/assets/{loader-circle-jCLtMahM.js → loader-circle-DlfD5ae4.js} +1 -1
  54. package/web-app/dist/assets/{lock-DYipaQub.js → lock-Bp9L8WT9.js} +1 -1
  55. package/web-app/dist/assets/{package-DTU2eDJk.js → package-YoE2sWU8.js} +1 -1
  56. package/web-app/dist/assets/{plus-Dwtg85R2.js → plus-DdcvjiWR.js} +1 -1
  57. package/web-app/dist/assets/{refresh-cw-B2BZn7xv.js → refresh-cw-DlhQH4A4.js} +1 -1
  58. package/web-app/dist/assets/{rotate-ccw-BnDgsF2l.js → rotate-ccw-BMskUWd9.js} +1 -1
  59. package/web-app/dist/assets/{scroll-text-CHcWlkC1.js → scroll-text-wq9VgYsu.js} +1 -1
  60. package/web-app/dist/assets/{server-DGbuh4v5.js → server-BvBfqjcL.js} +1 -1
  61. package/web-app/dist/assets/{shield-alert-BGxG6i1x.js → shield-alert-Ctv17L9P.js} +1 -1
  62. package/web-app/dist/assets/{thumbs-up-C4_XsjwR.js → thumbs-up-Bppr-IMM.js} +1 -1
  63. package/web-app/dist/assets/{trash-2-CXkZKiJ3.js → trash-2-C__rfpz0.js} +1 -1
  64. package/web-app/dist/assets/{trending-down-Ca8gOfqE.js → trending-down-CA0bokwG.js} +1 -1
  65. package/web-app/dist/assets/{trending-up-BwTtd3Ft.js → trending-up-BFh3twff.js} +1 -1
  66. package/web-app/dist/assets/{upload-DK47bkj8.js → upload-DABSXWW6.js} +1 -1
  67. package/web-app/dist/assets/{usePolling-CrEvFOnC.js → usePolling-DcTxi6kF.js} +1 -1
  68. package/web-app/dist/assets/{user-Ck5fqwRB.js → user-y8K-uMqG.js} +1 -1
  69. package/web-app/dist/index.html +1 -1
@@ -258,7 +258,7 @@ var ASSIGNMENT, RULES, QUERY_SEGMENT, SECRET_PARAM, redactQuery = (s) => s.repla
258
258
  if (!keep || !data || typeof data !== "object" || Array.isArray(data))
259
259
  return redactDeep(data);
260
260
  return Object.fromEntries(Object.entries(data).map(([k, v]) => typeof v === "string" && keep.get(k)?.test(v) ? [k, v] : [redactSecrets(k), redactDeep(v)]));
261
- }, redactEnvelope = (e) => Object.fromEntries(Object.entries(e).map(([k, v]) => [redactSecrets(k), k === "data" ? redactEventData(e.type, v) : redactDeep(v)]));
261
+ }, redactEnvelope = (e) => Object.fromEntries(Object.entries(e).map(([k, v]) => [redactSecrets(k), k === "data" ? redactEventData(e.type, v) : redactDeep(v)])), UNSAFE_TERMINAL_CHARS_RE;
262
262
  var init_redact = __esm(() => {
263
263
  ASSIGNMENT = /((?<![A-Za-z0-9_.-])[_.-]*(?:[A-Za-z0-9]+[_.-]+)*(?:password|passwd|secret|token|api[_-]?key|apikey)["']?\s*[:=]\s*)((?:"(?!\[REDACTED)(?:\\.|[^"\\\n])+")|(?:'(?!\[REDACTED)(?:\\.|[^'\\\n])+')|(?!["']|\[REDACTED)[^\s"',;&]+)/gi;
264
264
  RULES = [
@@ -300,6 +300,7 @@ var init_redact = __esm(() => {
300
300
  ["log.sealed", new Map([["kid", B64(43)], ["sig", B64(86)], ["events_sha256", HEX64]])],
301
301
  ["receipt.sealed", new Map([["kid", B64(43)], ["receipt_sha256", HEX64], ["events_sha256", HEX64]])]
302
302
  ]);
303
+ UNSAFE_TERMINAL_CHARS_RE = /[\x00-\x1f\x7f-\x9f\u00ad\u061c\u200b-\u200f\u2028-\u202e\u2060-\u2064\u2066-\u2069\ufeff]/g;
303
304
  });
304
305
 
305
306
  // ../../loki-ts/src/util/credential_env.ts
@@ -8986,7 +8987,12 @@ function reapLiveGroup(pgid, onReap) {
8986
8987
  onReap();
8987
8988
  killGroupWithGrace(pgid);
8988
8989
  }
8990
+ function maxTurnsFor(limitS, env) {
8991
+ const user = Number(env["LOKI_E10_MAX_TURNS"]);
8992
+ return Number.isInteger(user) && user > 0 ? user : Math.max(MIN_TURNS, Math.ceil(limitS / SECONDS_PER_TURN));
8993
+ }
8989
8994
  function clampBashTimeoutEnv(env, limitS) {
8995
+ env["LOKI_E10_MAX_TURNS"] = String(maxTurnsFor(limitS, env));
8990
8996
  const budget = Math.max(BASH_CLAMP_FLOOR_MS, Math.floor(limitS * 1000) - BASH_CLAMP_MARGIN_MS);
8991
8997
  for (const [k, dflt] of [["BASH_DEFAULT_TIMEOUT_MS", 120000], ["BASH_MAX_TIMEOUT_MS", 600000]]) {
8992
8998
  const cur = Number(env[k]);
@@ -9074,7 +9080,7 @@ function spawnWorker(argv, env, cwd, backstopMs, escalateMs, onLine, onStopped =
9074
9080
  });
9075
9081
  });
9076
9082
  }
9077
- var CANCEL_GRACE_MS, DRAIN_MS = 2000, KILL_GRACE_MS2 = 2000, BASH_CLAMP_FLOOR_MS = 30000, BASH_CLAMP_MARGIN_MS = 1e4, SAFE_BUN_FLAGS, ULIMIT_REFUSED_EXIT = 97, ULIMIT_KNOBS;
9083
+ var CANCEL_GRACE_MS, DRAIN_MS = 2000, KILL_GRACE_MS2 = 2000, BASH_CLAMP_FLOOR_MS = 30000, BASH_CLAMP_MARGIN_MS = 1e4, MAX_TURNS_EXIT = 98, SECONDS_PER_TURN = 3, MIN_TURNS = 10, SAFE_BUN_FLAGS, ULIMIT_REFUSED_EXIT = 97, ULIMIT_KNOBS;
9078
9084
  var init_worker_proc = __esm(() => {
9079
9085
  CANCEL_GRACE_MS = Number(process.env["LOKI_E10_CANCEL_GRACE_MS"]) > 0 ? Number(process.env["LOKI_E10_CANCEL_GRACE_MS"]) : 1e4;
9080
9086
  SAFE_BUN_FLAGS = ["--no-env-file", "--config=/dev/null"];
@@ -12484,6 +12490,7 @@ async function consumeSdkStream(messages, ctx, clock) {
12484
12490
  let refusedNoFallback = false;
12485
12491
  let rateLimit;
12486
12492
  let sawResult = false;
12493
+ let maxTurns = false;
12487
12494
  const usageById = new Map;
12488
12495
  let anonUsageId = 0;
12489
12496
  let firstTurnId;
@@ -12724,10 +12731,11 @@ async function consumeSdkStream(messages, ctx, clock) {
12724
12731
  if (advisorById.size === 0)
12725
12732
  recordRouterUsage(new Map, advisorById, "#result", data.usage ?? {});
12726
12733
  writeResultCost(lokiRoot, ctx.iteration, data, data.model ?? sessionModel, firstTurnPromptTokens, { ...routerTelemetry(reqById, advisorById, advisorFaults), ...toolTelemetry() }, ctx.requestedModel);
12727
- exitCode = data.is_error ? 1 : 0;
12734
+ maxTurns = data.subtype === "error_max_turns";
12735
+ exitCode = data.is_error || maxTurns ? 1 : 0;
12728
12736
  }
12729
12737
  }
12730
- return { exitCode, sessionId: sessionId ?? seenSessionId, totalCostUsd, capturedText: captured, rateLimit, sawResult, truncated: guard.truncated || !sawResult, refused, refusedNoFallback };
12738
+ return { exitCode, sessionId: sessionId ?? seenSessionId, totalCostUsd, capturedText: captured, rateLimit, sawResult, truncated: guard.truncated || !sawResult, refused, refusedNoFallback, maxTurns };
12731
12739
  }
12732
12740
  async function* asAsync(src, guard) {
12733
12741
  try {
@@ -53666,6 +53674,7 @@ var exports_providers = {};
53666
53674
  __export(exports_providers, {
53667
53675
  useProviderDefaultModel: () => useProviderDefaultModel,
53668
53676
  truthy: () => truthy,
53677
+ stageMaxTurns: () => stageMaxTurns,
53669
53678
  selectClaudeInvokerKind: () => selectClaudeInvokerKind,
53670
53679
  sdkQueryProvider: () => sdkQueryProvider,
53671
53680
  resolveSystemPrompt: () => resolveSystemPrompt,
@@ -53754,6 +53763,10 @@ function claudeTierToModel(tier) {
53754
53763
  return pinned("DEVELOPMENT", "sonnet");
53755
53764
  }
53756
53765
  }
53766
+ function stageMaxTurns(env = process.env) {
53767
+ const n10 = Number(env["LOKI_E10_MAX_TURNS"]);
53768
+ return env["LOKI_E10_STAGE"] && Number.isInteger(n10) && n10 > 0 ? n10 : undefined;
53769
+ }
53757
53770
  async function* closeQueryOnResult(q10, enabled) {
53758
53771
  if (!enabled) {
53759
53772
  yield* q10;
@@ -54185,7 +54198,8 @@ function sdkQueryProvider() {
54185
54198
  ...extra.maxBudgetUsd ? { maxBudgetUsd: extra.maxBudgetUsd } : {},
54186
54199
  ...extra.taskBudget ? { taskBudget: extra.taskBudget } : {},
54187
54200
  ...extra.fallbackModel ? { fallbackModel: extra.fallbackModel } : {},
54188
- ...extra.settings ? { settings: extra.settings } : {}
54201
+ ...extra.settings ? { settings: extra.settings } : {},
54202
+ ...stageMaxTurns() ? { maxTurns: stageMaxTurns() } : {}
54189
54203
  }
54190
54204
  });
54191
54205
  const res = await consumeSdkStream(closeQueryOnResult(q10, !!process.env["LOKI_E10_STAGE"]), {
@@ -54199,7 +54213,11 @@ function sdkQueryProvider() {
54199
54213
  captured = res.capturedText;
54200
54214
  if (process.env["LOKI_E10_STAGE"])
54201
54215
  writeSessionId(call.cwd, process.env["LOKI_ITERATION"] ?? "0", res);
54202
- exitCode = res.sawResult ? res.exitCode : 1;
54216
+ exitCode = res.sawResult ? res.maxTurns ? MAX_TURNS_EXIT : res.exitCode : 1;
54217
+ if (res.maxTurns)
54218
+ captured += `
54219
+ [sdk-loop error: turn cap reached (error_max_turns)]
54220
+ `;
54203
54221
  rateLimit = res.rateLimit;
54204
54222
  } catch (e10) {
54205
54223
  captured += `
@@ -54938,6 +54956,8 @@ function childEnv2(opts, cfg) {
54938
54956
  env["LOKI_SDK_LOOP"] = "1";
54939
54957
  env["LOKI_HOST_GUARD"] = "1";
54940
54958
  env["CLAUDE_CODE_DISABLE_BACKGROUND_TASKS"] = "1";
54959
+ if (process.env["LOKI_E10_STAGE"])
54960
+ delete env["LOKI_E10_MAX_TURNS"];
54941
54961
  clampBashTimeoutEnv(env, opts.limitS);
54942
54962
  if (env["LOKI_E10_PREFIX"] === undefined)
54943
54963
  env["LOKI_E10_PREFIX"] = "lean";
@@ -55182,7 +55202,8 @@ var init_session = __esm(() => {
55182
55202
  [127, "command not found"],
55183
55203
  [130, "SIGINT"],
55184
55204
  [137, "SIGKILL"],
55185
- [143, "SIGTERM"]
55205
+ [143, "SIGTERM"],
55206
+ [98, "turn cap"]
55186
55207
  ].map(([code, what]) => [code, `exit ${code} (${what})`]));
55187
55208
  lastStageEnd = new WeakMap;
55188
55209
  main = sessionChildMain;
@@ -55484,7 +55505,8 @@ async function discoverProjectModel(ctx, signal, opts = {}) {
55484
55505
  const session = raced;
55485
55506
  const raw2 = readAnswer(answerPath, session.summary);
55486
55507
  if (raw2 === undefined && (session.killed || session.exit !== 0)) {
55487
- return { model: unknownModel("", `owner=provider: the discovery session failed (exit ${session.exit}${session.killed ? ", killed" : ""})`), cached: false, attempts: attempt, owner: "provider" };
55508
+ const capped = session.exit === MAX_TURNS_EXIT && !session.killed;
55509
+ return { model: unknownModel("", `owner=${capped ? "harness" : "provider"}: the discovery session ${capped ? "hit the turn cap" : "failed"} (exit ${session.exit}${session.killed ? ", killed" : ""})`), cached: false, attempts: attempt, owner: capped ? "harness" : "provider" };
55488
55510
  }
55489
55511
  const v3 = raw2 === undefined ? null : validateAnswer(ctx.repoDir, raw2);
55490
55512
  if (v3?.ok) {
@@ -55514,6 +55536,7 @@ async function intakeProjectModel(ctx, signal, startedMs) {
55514
55536
  var PROJECT_FILE = ".loki/project.json", UNKNOWN_TTL_MS, SESSION_LIMIT_S = 60, HARD_GRACE_MS = 5000, MIN_SESSION_S = 8, KILL_GRACE_S = 2, MARGIN_S = 3;
55515
55537
  var init_discover2 = __esm(() => {
55516
55538
  init_model_downgrades();
55539
+ init_worker_proc();
55517
55540
  init_types();
55518
55541
  init_gather();
55519
55542
  init_schema();
@@ -55777,6 +55800,7 @@ var init_test_file_text = __esm(() => {
55777
55800
  var exports_testmap = {};
55778
55801
  __export(exports_testmap, {
55779
55802
  projectInterpreter: () => projectInterpreter,
55803
+ missingJavaTool: () => missingJavaTool,
55780
55804
  isTestFile: () => isTestFile,
55781
55805
  impactedRefs: () => impactedRefs,
55782
55806
  harnessRunners: () => harnessRunners,
@@ -55796,6 +55820,10 @@ function pytestPython(root) {
55796
55820
  }
55797
55821
  return "python";
55798
55822
  }
55823
+ function missingJavaTool(files, env = process.env, root) {
55824
+ const want = files.some((f) => /(?:^|\/)pom\.xml$/.test(f)) ? "maven" : files.some((f) => /(?:^|\/)(?:build|settings)\.gradle(?:\.kts)?$|(?:^|\/)gradlew$/.test(f)) ? "gradle" : files.some((f) => /\.java$/.test(f)) ? "javac" : null;
55825
+ return want && !javaToolOk(want, env, root) ? JAVA_TOOLS[want].tool : null;
55826
+ }
55799
55827
  function guessRunner(fileName, runners, relPath) {
55800
55828
  if (fileName.endsWith(".py"))
55801
55829
  return runners.includes("unittest") && !runners.includes("pytest") ? "unittest" : "pytest";
@@ -55803,6 +55831,8 @@ function guessRunner(fileName, runners, relPath) {
55803
55831
  return "go";
55804
55832
  if (fileName.endsWith(".rs"))
55805
55833
  return runners.includes("cargo") && relPath !== undefined && CARGO_TEST_FILE_RE.test(relPath) ? "cargo" : null;
55834
+ if (fileName.endsWith(".java"))
55835
+ return ["maven", "gradle", "javac"].find((r) => runners.includes(r)) ?? null;
55806
55836
  return /\.[cm]?[jt]sx?$/.test(fileName) ? ["vitest", "jest", "bun", "node"].find((r) => runners.includes(r)) ?? null : null;
55807
55837
  }
55808
55838
  function projectInterpreter(root) {
@@ -55851,6 +55881,10 @@ function buildTestMap(root) {
55851
55881
  mark("go", rel);
55852
55882
  else if (name === "Cargo.toml")
55853
55883
  mark("cargo", rel);
55884
+ else if (name === "pom.xml")
55885
+ mark("maven", rel);
55886
+ else if (/^(?:build|settings)\.gradle(?:\.kts)?$/.test(name) || name === "gradlew")
55887
+ mark("gradle", rel);
55854
55888
  }
55855
55889
  const jsRunner = evidence["vitest"] ? "vitest" : evidence["jest"] ? "jest" : evidence["bun"] ? "bun" : evidence["node"] ? "node" : null;
55856
55890
  const tests = [];
@@ -55919,7 +55953,10 @@ class RealTestMapProvider {
55919
55953
  return impactedRefs(map, changedFiles);
55920
55954
  }
55921
55955
  }
55922
- var RUNNER_ORDER, COMMANDS, STDLIB_RUNNERS, FOREIGN_SOURCE_RE, harnessRunners = (runners, files = [], env = process.env, root, focus2 = []) => {
55956
+ var RUNNER_ORDER, COMMANDS, STDLIB_RUNNERS, FOREIGN_SOURCE_RE, JAVA_TOOLS, javaToolOk = (r, env, root) => {
55957
+ const t = JAVA_TOOLS[r];
55958
+ return !t || !!Bun.which(t.tool, { PATH: env.PATH ?? "" }) || !!t.wrapper && !!root && existsSync36(join53(root, t.wrapper));
55959
+ }, harnessRunners = (runners, files = [], env = process.env, root, focus2 = []) => pickHarnessRunners(runners, files, env, root, focus2).filter((r) => javaToolOk(r, env, root)), pickHarnessRunners = (runners, files, env, root, focus2) => {
55923
55960
  const onPath = (tool) => !!Bun.which(tool, { PATH: env.PATH ?? "" }), w = languageBytes(root, files, (f) => STDLIB_RUNNERS.find((r) => r.ext.test(f))?.runner ?? (/\.[cm]?[jt]sx?$/i.test(f) ? "js" : FOREIGN_SOURCE_RE.test(f) ? "other" : null)), at2 = (k3) => w.get(k3) ?? 0, js = at2("js"), top = STDLIB_RUNNERS.reduce((a, r) => at2(r.runner) > at2(a.runner) ? r : a), bun = env.LOKI_WALL_HARNESS_RUNNER !== "0" && onPath("bun") ? ["bun"] : toolchainRunner(files, focus2);
55924
55961
  const t = at2(top.runner), o = at2("other");
55925
55962
  return runners.length > 0 ? runners : js >= t && js >= o ? js === 0 && w.size > 0 ? [] : bun : t > o ? onPath(top.tool) ? [top.runner] : toolchainRunner(files, focus2) : [];
@@ -55939,7 +55976,7 @@ var init_testmap = __esm(() => {
55939
55976
  init_linguist();
55940
55977
  init_scope();
55941
55978
  init_test_file_text();
55942
- RUNNER_ORDER = ["pytest", "vitest", "jest", "bun", "node", "npm", "go", "cargo"];
55979
+ RUNNER_ORDER = ["pytest", "vitest", "jest", "bun", "node", "npm", "go", "cargo", "maven", "gradle", "javac"];
55943
55980
  COMMANDS = {
55944
55981
  pytest: { cmd: "python -m pytest -q <files>", coarse: false },
55945
55982
  unittest: { cmd: "python3 -m unittest <files>", coarse: false },
@@ -55949,11 +55986,15 @@ var init_testmap = __esm(() => {
55949
55986
  node: { cmd: "node --test <files>", coarse: false },
55950
55987
  npm: { cmd: "npm test --silent", coarse: true },
55951
55988
  go: { cmd: "go test ./<pkg dirs>", coarse: false },
55952
- cargo: { cmd: "cargo test", coarse: true }
55989
+ cargo: { cmd: "cargo test", coarse: true },
55990
+ maven: { cmd: "mvn test -Dtest=<class>", coarse: false },
55991
+ gradle: { cmd: "gradle cleanTest test --tests <class>", coarse: false },
55992
+ javac: { cmd: "javac + java <test class>", coarse: false }
55953
55993
  };
55954
- STDLIB_RUNNERS = [{ ext: /\.py$/, runner: "unittest", tool: "python3" }, { ext: /\.go$/, runner: "go", tool: "go" }, { ext: /\.rs$/, runner: "cargo", tool: "cargo" }];
55994
+ STDLIB_RUNNERS = [{ ext: /\.py$/, runner: "unittest", tool: "python3" }, { ext: /\.go$/, runner: "go", tool: "go" }, { ext: /\.rs$/, runner: "cargo", tool: "cargo" }, { ext: /\.java$/, runner: "javac", tool: "javac" }];
55955
55995
  FOREIGN_SOURCE_RE = /\.(?:py|go|rs|java|kt|kts|scala|rb|php|cs|c|cc|cpp|cxx|h|hpp|swift|m|mm|ex|exs|erl|hs|clj|lua|pl|dart|r|jl|zig)$/i;
55956
- TOOLCHAINS = [[/(?:^|\/)package\.json$/, "node", /\.[cm]?[jt]sx?$/], [/(?:^|\/)go\.mod$/, "go", /\.go$/], [/(?:^|\/)Cargo\.toml$/, "cargo", /\.rs$/], [/(?:^|\/)(?:pyproject\.toml|setup\.py|setup\.cfg|requirements(?:[-_.][\w.-]+)?\.txt|tox\.ini|pytest\.ini)$/, "pytest", /\.py$/]];
55996
+ JAVA_TOOLS = { maven: { tool: "mvn", wrapper: "mvnw" }, gradle: { tool: "gradle", wrapper: "gradlew" }, javac: { tool: "javac" } };
55997
+ TOOLCHAINS = [[/(?:^|\/)package\.json$/, "node", /\.[cm]?[jt]sx?$/], [/(?:^|\/)go\.mod$/, "go", /\.go$/], [/(?:^|\/)Cargo\.toml$/, "cargo", /\.rs$/], [/(?:^|\/)pom\.xml$/, "maven", /\.java$/], [/(?:^|\/)(?:build|settings)\.gradle(?:\.kts)?$|(?:^|\/)gradlew$/, "gradle", /\.java$/], [/(?:^|\/)(?:pyproject\.toml|setup\.py|setup\.cfg|requirements(?:[-_.][\w.-]+)?\.txt|tox\.ini|pytest\.ini)$/, "pytest", /\.py$/]];
55957
55998
  CARGO_TEST_FILE_RE = /(?:^|\/)tests\/[^/]+\.rs$/;
55958
55999
  });
55959
56000
 
@@ -55978,7 +56019,8 @@ var init_python_build_check = __esm(() => {
55978
56019
  // ../../loki-ts/src/util/check_result.ts
55979
56020
  import { spawn as spawn9 } from "child_process";
55980
56021
  import { createHash as createHash13 } from "crypto";
55981
- import { existsSync as existsSync37, mkdirSync as mkdirSync23, readFileSync as readFileSync49, realpathSync as realpathSync19, renameSync as renameSync11, rmSync as rmSync13, writeFileSync as writeFileSync22 } from "fs";
56022
+ import { existsSync as existsSync37, mkdirSync as mkdirSync23, mkdtempSync as mkdtempSync5, readFileSync as readFileSync49, realpathSync as realpathSync19, renameSync as renameSync11, rmSync as rmSync13, writeFileSync as writeFileSync22 } from "fs";
56023
+ import { tmpdir as tmpdir7 } from "os";
55982
56024
  import { basename as basename12, dirname as dirname23, isAbsolute as isAbsolute6, join as join54, relative as relative6 } from "path";
55983
56025
  function plainTestEnv(base = process.env) {
55984
56026
  const e10 = {};
@@ -56014,7 +56056,7 @@ function ran(raw2, path, ok2) {
56014
56056
  function cargoTrailer(out3) {
56015
56057
  const ls2 = out3.split(`
56016
56058
  `).filter((x3) => x3.trim());
56017
- while (ls2.length && /^error: /.test(ls2[ls2.length - 1]))
56059
+ while (ls2.length && CARGO_NOISE.test(ls2[ls2.length - 1]))
56018
56060
  ls2.pop();
56019
56061
  const segs = [];
56020
56062
  for (const l of ls2) {
@@ -56103,7 +56145,8 @@ function goRunner(cmd, args) {
56103
56145
  return {};
56104
56146
  }
56105
56147
  function goJson(out3) {
56106
- let any = false, failed2 = false;
56148
+ let any = false, failed2 = false, dirty = false;
56149
+ const status = new Map, ranSet = new Set, pkgs = new Set, failedTests = new Set, starts = new Map, done = new Map;
56107
56150
  for (const x3 of out3.split(`
56108
56151
  `)) {
56109
56152
  if (!x3.trim() || /^go: /.test(x3))
@@ -56117,10 +56160,97 @@ function goJson(out3) {
56117
56160
  if (!e10 || typeof e10 !== "object" || typeof e10.Action !== "string")
56118
56161
  return null;
56119
56162
  any = true;
56120
- if (e10.Action === "fail")
56163
+ const pkg = typeof e10.Package === "string" ? e10.Package : "", test = typeof e10.Test === "string" ? e10.Test : "";
56164
+ if (e10.Action === "start" && !test) {
56165
+ pkgs.add(pkg);
56166
+ starts.set(pkg, (starts.get(pkg) ?? 0) + 1);
56167
+ }
56168
+ if (e10.Action === "fail") {
56121
56169
  failed2 = true;
56170
+ if (test)
56171
+ failedTests.add(`${pkg}::${test}`);
56172
+ }
56173
+ if (!/^build-/.test(e10.Action) && !starts.has(pkg))
56174
+ dirty = true;
56175
+ if (!test && e10.Action === "output" && /\[no tests to run\]/.test(String(e10.Output ?? "")))
56176
+ dirty = true;
56177
+ if (!test) {
56178
+ if (/^(?:pass|fail|skip)$/.test(e10.Action))
56179
+ done.set(pkg, (done.get(pkg) ?? 0) + 1);
56180
+ continue;
56181
+ }
56182
+ if (test.includes("/"))
56183
+ continue;
56184
+ const k3 = `${pkg}::${test}`;
56185
+ if (e10.Action === "run") {
56186
+ if (ranSet.has(k3))
56187
+ dirty = true;
56188
+ ranSet.add(k3);
56189
+ } else if (ranSet.has(k3) && /^(?:pass|fail|skip)$/.test(e10.Action))
56190
+ status.set(k3, e10.Action);
56122
56191
  }
56123
- return any ? { failed: failed2 } : null;
56192
+ if (!any)
56193
+ return null;
56194
+ const passedNames = [...status].filter(([, v3]) => v3 === "pass").map(([k3]) => k3);
56195
+ return { failed: failed2, failedTests: [...failedTests], passed: passedNames.length, passedNames, complete: !dirty && pkgs.size > 0 && [...pkgs].every((p) => starts.get(p) === 1 && done.get(p) === 1) };
56196
+ }
56197
+ async function corroborateGoPass(c, out3, cmdOrLine, args, o) {
56198
+ if (c.result !== "pass" || goRunner(cmdOrLine, args).runner !== "go")
56199
+ return c;
56200
+ const refuse = { result: "not_run", reason: GO_EXIT0_REASON };
56201
+ const first = goJson(stripAnsi(out3));
56202
+ const names = first?.passedNames ?? [];
56203
+ const toks = args ? [cmdOrLine, ...args] : cmdOrLine.trim().split(/\s+/);
56204
+ if (!names.length || toks.some((t) => /[&|;$`"'<>()\\]/.test(t)) || basename12(toks[0] ?? "") !== "go" || toks[1] !== "test")
56205
+ return refuse;
56206
+ const pkgs = [], run2 = [];
56207
+ for (let k3 = 2;k3 < toks.length; k3++) {
56208
+ const t = toks[k3];
56209
+ if (t === "-json")
56210
+ continue;
56211
+ if (t === "-run") {
56212
+ const v3 = toks[++k3];
56213
+ if (v3 === undefined)
56214
+ return refuse;
56215
+ run2.push("-run", v3);
56216
+ continue;
56217
+ }
56218
+ if (t.startsWith("-"))
56219
+ return refuse;
56220
+ pkgs.push(t);
56221
+ }
56222
+ const dir = mkdtempSync5(join54(tmpdir7(), "loki-gocov-")), prof = join54(dir, "cover.out");
56223
+ try {
56224
+ const r = await spawnCollect("go", ["test", "-json", "-count=1", `-coverprofile=${prof}`, ...run2, ...pkgs.length ? pkgs : ["."]], { cwd: o.cwd, env: o.env, timeoutMs: 600000 });
56225
+ const second = goJson(stripAnsi(r.output));
56226
+ if (r.status !== 0 || !second || second.failed || !second.complete)
56227
+ return refuse;
56228
+ const again = new Set(second.passedNames);
56229
+ if (!names.every((n10) => again.has(n10)))
56230
+ return refuse;
56231
+ const covered = new Set;
56232
+ for (const l of (existsSync37(prof) ? readFileSync49(prof, "utf8") : "").split(`
56233
+ `)) {
56234
+ const m = /^(.+)\/[^/:]+:\d+\.\d+,\d+\.\d+ \d+ \d+$/.exec(l);
56235
+ if (m)
56236
+ covered.add(m[1]);
56237
+ }
56238
+ return [...new Set(names.map((n10) => n10.slice(0, n10.indexOf("::"))))].every((pk2) => covered.has(pk2)) ? c : refuse;
56239
+ } finally {
56240
+ rmSync13(dir, { recursive: true, force: true });
56241
+ }
56242
+ }
56243
+ function readableFailIds(runner, out3) {
56244
+ const text3 = stripAnsi(out3);
56245
+ if (runner === "go")
56246
+ return goJson(text3)?.failedTests ?? [];
56247
+ const failed2 = cargoTrailer(text3).reduce((t, l) => t + +(l.match(/(\d+) failed/)?.[1] ?? 0), 0);
56248
+ const ids = [...new Set(text3.split(`
56249
+ `).flatMap((l) => {
56250
+ const m = /^test (.+?) \.\.\. FAILED$/.exec(l.trim());
56251
+ return m ? [m[1]] : [];
56252
+ }))];
56253
+ return failed2 > 0 && ids.length >= failed2 ? ids : [];
56124
56254
  }
56125
56255
  function summaryPassFailCount(out3) {
56126
56256
  return ["pass", "fail"].reduce((t, k3) => t + +([...out3.matchAll(new RegExp(`^(?:#|\\u2139) ${k3} (\\d+)$`, "gm"))].pop()?.[1] ?? 0), 0);
@@ -56129,6 +56259,50 @@ function skipped(raw2) {
56129
56259
  return stripAnsi(raw2).split(`
56130
56260
  `).filter((l) => /^(?:=+ )?\d+ \w+.* in [\d.]+s|^\s*Tests?:?\s+\d|^(?:#|\u2139) skipped \d/.test(l.trim())).reduce((t, l) => t + [...l.matchAll(/(\d+) (?:skipped|deselected|xfailed)|skipped (\d+)/g)].reduce((u10, m) => u10 + +(m[1] ?? m[2]), 0), 0);
56131
56261
  }
56262
+ function javaSummary(raw2) {
56263
+ const ls2 = stripAnsi(raw2).split(`
56264
+ `).map((l) => l.trimEnd()), tail2 = ls2.filter((l) => l.trim()).slice(-40), ok2 = (re2) => {
56265
+ const m = tail2.map((l) => re2.exec(l)).filter(Boolean).pop();
56266
+ return m ? m[1] === "SUCCESS" || m[1] === "SUCCESSFUL" : null;
56267
+ };
56268
+ const wrap = ls2.filter((l) => l.trim()).slice(-1)[0]?.match(/^LOKI_JAVA_TESTS: (\d+) run, (\d+) failed$/);
56269
+ if (wrap) {
56270
+ const ids = ls2.flatMap((l) => l.match(/^FAIL (.+)$/)?.[1] ?? []), failed2 = +wrap[2];
56271
+ return +wrap[1] > 0 && ids.length === failed2 && ls2.filter((l) => /^(?:PASS|FAIL) /.test(l)).length === +wrap[1] ? { executed: +wrap[1], failed: failed2, ids } : null;
56272
+ }
56273
+ const mv2 = ok2(/^\[(?:INFO|ERROR)\] BUILD (SUCCESS|FAILURE)$/), gr2 = ok2(/^BUILD (SUCCESSFUL|FAILED)\b/);
56274
+ if (mv2 !== null) {
56275
+ let executed = 0, failed2 = 0, seen = false;
56276
+ ls2.forEach((l, i) => {
56277
+ if (/^\[(?:INFO|ERROR)\] Results:$/.test(l)) {
56278
+ const m = ls2.slice(i + 1, i + 40).map((x3) => /^\[(?:INFO|WARNING|ERROR)\] Tests run: (\d+), Failures: (\d+), Errors: (\d+), Skipped: (\d+)$/.exec(x3)).find(Boolean);
56279
+ if (m) {
56280
+ seen = true;
56281
+ executed += +m[1] - +m[4];
56282
+ failed2 += +m[2] + +m[3];
56283
+ }
56284
+ }
56285
+ });
56286
+ const ids = [...new Set(ls2.flatMap((l) => {
56287
+ const m = /^\[ERROR\] (?:(\S+)\(([\w.$]+)\)|([\w.$]+\.[\w$]+)(?:\[[^\]]*\])?) .*<<< (?:FAILURE|ERROR)!$/.exec(l);
56288
+ return m ? [m[3] ?? `${m[2]}.${m[1]}`] : [];
56289
+ }))];
56290
+ return seen && executed > 0 && (mv2 ? failed2 === 0 : failed2 > 0) ? { executed, failed: failed2, ids } : null;
56291
+ }
56292
+ if (gr2 !== null) {
56293
+ const ev2 = ls2.flatMap((l) => {
56294
+ const m = /^\s*(\S.*?) > (\S.*?) (PASSED|FAILED|SKIPPED)$/.exec(l);
56295
+ return m ? [{ id: `${m[1]}.${m[2]}`, s: m[3] }] : [];
56296
+ }), bad = ev2.filter((e10) => e10.s === "FAILED");
56297
+ const executed = ev2.filter((e10) => e10.s !== "SKIPPED").length;
56298
+ return executed > 0 && (gr2 ? bad.length === 0 : bad.length > 0) ? { executed, failed: bad.length, ids: [...new Set(bad.map((e10) => e10.id))] } : null;
56299
+ }
56300
+ return null;
56301
+ }
56302
+ function javaTestClass(path) {
56303
+ const m = /^(.*?)\/?src\/test\/java\/(.+)\.java$/.exec(path), cls = (m ? m[2] : basename12(path, ".java")).split("/").join(".");
56304
+ return { root: m?.[1] || ".", cls, rel: m ? `src/test/java/${m[2]}.java` : path };
56305
+ }
56132
56306
  function testCount(raw2, path, ok2) {
56133
56307
  const out3 = stripAnsi(raw2);
56134
56308
  const bu2 = bunCount(out3), ut = unittestCount(out3, ok2);
@@ -56136,6 +56310,9 @@ function testCount(raw2, path, ok2) {
56136
56310
  return bu2;
56137
56311
  if (ut !== null)
56138
56312
  return ut;
56313
+ const jv = javaSummary(out3);
56314
+ if (jv)
56315
+ return jv.executed;
56139
56316
  if (/^\s*(?:Test Files\s+0\b|No test files found)/m.test(out3) && !/^\s*Tests?\s+\d/m.test(out3))
56140
56317
  return 0;
56141
56318
  const r = ran(out3, path, ok2);
@@ -56184,9 +56361,12 @@ function classifyCheck(i) {
56184
56361
  return { result: i.ok ? "pass" : "fail" };
56185
56362
  const text3 = stripAnsi(i.out);
56186
56363
  if (i.runner === "go") {
56187
- if (i.ok)
56188
- return { result: "not_run", reason: GO_EXIT0_REASON };
56189
56364
  const j10 = goJson(text3);
56365
+ if (i.ok) {
56366
+ if (!j10 || j10.failed || !j10.complete)
56367
+ return { result: "not_run", reason: GO_EXIT0_REASON };
56368
+ return j10.passed > 0 ? { result: "pass", n: j10.passed } : { result: "not_run", n: 0, reason: `${NO_TESTS_REASON} (ran 0 tests, empty or all skipped)` };
56369
+ }
56190
56370
  if (j10)
56191
56371
  return j10.failed ? { result: "fail" } : { result: "not_run", reason: UNCONFIRMED_REASON };
56192
56372
  return FAIL_EVIDENCE.test(text3) || GO_FAIL_EVIDENCE.test(text3) ? { result: "fail" } : { result: "not_run", reason: UNCONFIRMED_REASON };
@@ -56202,6 +56382,9 @@ function classifyCheck(i) {
56202
56382
  return { result: "fail", ...n10 !== null ? { n: n10 } : {} };
56203
56383
  if (n10 === null)
56204
56384
  return { result: "not_run", reason: UNMEASURED_REASON };
56385
+ const jv = javaSummary(text3);
56386
+ if (jv && jv.failed > 0)
56387
+ return { result: "fail", n: n10 };
56205
56388
  return { result: "pass", n: n10 };
56206
56389
  }
56207
56390
  function checkProvenance(name, ctx) {
@@ -56708,13 +56891,19 @@ function classify(f, status, output, repoDir, interpreter) {
56708
56891
  if (status === null || status === 126 || status === 127)
56709
56892
  return "not_run";
56710
56893
  if (status === 0)
56711
- return classifyCheck({ kind: "test", ok: true, out: output, path: f.path, ...f.runner === "go" ? { runner: "go" } : {} }).result === "pass" ? "pass" : "not_run";
56894
+ return f.runner !== "go" && classifyCheck({ kind: "test", ok: true, out: output, path: f.path }).result === "pass" ? "pass" : "not_run";
56712
56895
  if (f.runner === "unittest")
56713
56896
  return status === 1 && unittestCount(output, false) !== null ? /unittest\.loader\._FailedTest|Failed to import test module/.test(output) ? pytestCollectionIsRed(output, repoDir) ? "fail" : "not_run" : "fail" : "not_run";
56714
56897
  if (f.runner === "pytest")
56715
56898
  return status === 1 ? pytestExit1IsRed(output) ? "fail" : "not_run" : status === 2 ? pytestCollectionIsRed(output, repoDir) ? "fail" : "not_run" : "not_run";
56716
56899
  if (f.runner === "jest" || f.runner === "vitest" || f.runner === "bun")
56717
56900
  return parsedFailCount(f.runner, output) > 0 ? "fail" : "not_run";
56901
+ if (f.runner === "maven" || f.runner === "gradle" || f.runner === "javac") {
56902
+ const j10 = javaSummary(output);
56903
+ return j10 && j10.failed > 0 ? "fail" : "not_run";
56904
+ }
56905
+ if (f.runner === "go" || f.runner === "cargo")
56906
+ return readableFailIds(f.runner, output).length > 0 ? "fail" : "not_run";
56718
56907
  return f.runner === "node" && nodeIsRed(f, output) ? "fail" : "not_run";
56719
56908
  }
56720
56909
  function baseJobs() {
@@ -56809,11 +56998,27 @@ function runnerCmd(t, repoDir) {
56809
56998
  const names = goTestNames(join54(repoDir, t.path));
56810
56999
  return ["go", ["test", "-json", ...names.length ? ["-run", `^(${names.join("|")})$`] : [], `./${dirname23(t.path)}`]];
56811
57000
  }
57001
+ case "maven": {
57002
+ const j10 = javaTestClass(t.path);
57003
+ return [wrapperOr(repoDir, "mvnw", "mvn"), ["-B", "test", `-Dtest=${j10.cls.split(".").pop()}`, "-Dsurefire.failIfNoSpecifiedTests=false", "-DfailIfNoTests=false"]];
57004
+ }
57005
+ case "gradle": {
57006
+ const j10 = javaTestClass(t.path);
57007
+ return [wrapperOr(repoDir, "gradlew", "gradle"), ["cleanTest", "test", "--tests", j10.cls, "-i", "--console=plain"]];
57008
+ }
57009
+ case "javac": {
57010
+ const j10 = javaTestClass(t.path);
57011
+ return ["bash", ["-c", JAVAC_WRAPPER, "loki-javac", j10.root, j10.cls, j10.rel]];
57012
+ }
56812
57013
  case "cargo":
56813
57014
  return CARGO_TEST_FILE_RE.test(t.path) ? ["cargo", ["test", "--test", basename12(t.path, ".rs")]] : ["cargo", ["test"]];
56814
57015
  }
56815
57016
  }
56816
57017
  function fullSuiteCmd(runner, repoDir) {
57018
+ if (runner === "maven" || runner === "gradle") {
57019
+ const s = FULL_SUITE_STATIC[runner];
57020
+ return { ...s, cmd: wrapperOr(repoDir, runner === "maven" ? "mvnw" : "gradlew", s.cmd) };
57021
+ }
56817
57022
  if (runner !== "pytest" && runner !== "unittest")
56818
57023
  return FULL_SUITE_STATIC[runner];
56819
57024
  const [cmd, interpreter, pre2] = resolveTool(repoDir, "python", "python3", "python");
@@ -56896,7 +57101,23 @@ function firstFileLineAnchor(desc2) {
56896
57101
  }
56897
57102
  var NO_TESTS_REASON = "no tests executed", NO_RUNNER_REASON = "no runner of this repo runs this file", harnessSkipCode = (env = process.env) => env.LOKI_WALL_HARNESS_RUNNER === "0" ? "harness_runner_disabled" : Bun.which("bun", { PATH: env.PATH ?? "" }) ? "no_toolchain" : "bun_not_on_path", 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, `
56898
57103
  `), tailLines = (out3) => out3.split(`
56899
- `).filter((x3) => x3.trim()).slice(-12), GO_PKG_RE, EXIT_CODED_COUNT = "n/a (exit-coded check, not a test runner)", FRAMEWORK_RE, SCRIPT_RE, isExecutedProof = (c) => c.result === "pass" && typeof c.n === "number" && c.n > 0, hasExecutedProof = (checks) => checks.some(isExecutedProof), LLM_JUDGES, NON_RUNNER, normPath = (p) => p.replace(/^(?:\.\/)+/, ""), hasExogenousProof = (checks, ctx) => checks.some((c) => isExecutedProof(c) && ((p) => p !== "agent_authored" && p !== "llm_judge")(checkProvenance(c.name ?? "", ctx))), CODE_FILE_EXT, DECL_RE, VAR_DECL_RE, stripComments = (src) => src.replace(/\/\*[\s\S]*?\*\//g, " ").split(`
57104
+ `).filter((x3) => x3.trim()).slice(-12), CARGO_NOISE, GO_PKG_RE, JAVAC_WRAPPER = `set -u
57105
+ root="$1"; cls="$2"; shift 2; cd "$root" || exit 70
57106
+ if [ "$cls" = "-" ]; then
57107
+ set -- $(find src/test/java -name '*Test.java' 2>/dev/null | sort); cls=""
57108
+ for f in "$@"; do c="\${f#src/test/java/}"; c="\${c%.java}"; cls="$cls \${c//\\//.}"; done
57109
+ fi
57110
+ out="$(mktemp -d "\${TMPDIR:-/tmp}/loki-javac.XXXXXX")" || exit 70
57111
+ trap 'rm -rf -- "\${out:?}"' EXIT
57112
+ find src/main/java -name '*.java' 2>/dev/null > "$out/srcs"
57113
+ javac -nowarn -d "$out" @"$out/srcs" "$@" || exit 1
57114
+ st=0; : > "$out/run.log"
57115
+ for c in $cls; do java -cp "$out" "$c" >> "$out/run.log" 2>&1 || st=$?; done
57116
+ cat "$out/run.log"
57117
+ p=$(grep -c '^PASS ' "$out/run.log"); f=$(grep -c '^FAIL ' "$out/run.log")
57118
+ echo "LOKI_JAVA_TESTS: $((p + f)) run, $f failed"
57119
+ [ "$f" -gt 0 ] && st=1
57120
+ exit $st`, wrapperOr = (repoDir, w, bare) => existsSync37(join54(repoDir, w)) ? `./${w}` : bare, EXIT_CODED_COUNT = "n/a (exit-coded check, not a test runner)", FRAMEWORK_RE, SCRIPT_RE, isExecutedProof = (c) => c.result === "pass" && typeof c.n === "number" && c.n > 0, hasExecutedProof = (checks) => checks.some(isExecutedProof), LLM_JUDGES, NON_RUNNER, normPath = (p) => p.replace(/^(?:\.\/)+/, ""), hasExogenousProof = (checks, ctx) => checks.some((c) => isExecutedProof(c) && ((p) => p !== "agent_authored" && p !== "llm_judge")(checkProvenance(c.name ?? "", ctx))), CODE_FILE_EXT, DECL_RE, VAR_DECL_RE, stripComments = (src) => src.replace(/\/\*[\s\S]*?\*\//g, " ").split(`
56900
57121
  `).map((l) => /^\s*\*/.test(l) ? "" : l.replace(/\/\/.*$/, "").replace(/(^|\s)#.*$/, "$1")).join(`
56901
57122
  `), GO_METHOD_RE, METHOD_RE, NOT_A_NAME, declNames = (line2) => {
56902
57123
  const out3 = [];
@@ -56911,7 +57132,7 @@ var NO_TESTS_REASON = "no tests executed", NO_RUNNER_REASON = "no runner of this
56911
57132
  if (m)
56912
57133
  out3.push(m[1]);
56913
57134
  return out3.filter((n10) => !NOT_A_NAME.has(n10));
56914
- }, printable = (s) => s.replace(/[\x00-\x1f\x7f]/g, "?"), SENSITIVE, API, TEST_CFG, RANK3, FILES_MEDIUM = 4, FILES_HIGH = 15, LINES_MEDIUM = 100, LINES_HIGH = 500, RAN_ALWAYS, REVIEWER_ITEM = "one reviewer", PLAN, LOW_SKIPPED, deferredOf = (tier, selected, executed) => (tier === "low" ? LOW_SKIPPED : selected).filter((c) => !RAN_ALWAYS.includes(c) && !executed.includes(c)), DEEP_ITEMS, NOT_SELECTED = "not selected by risk tier: ", MANIFEST_LOCKS, dirOf = (p) => p.includes("/") ? p.slice(0, p.lastIndexOf("/")) : "", PKG_DEP_KEYS, PYPROJECT_NONDEP, SEM_RULES, DOC_FILE, readOr = (p) => {
57135
+ }, printable = (s) => s.replace(UNSAFE_TERMINAL_CHARS_RE, "?"), SENSITIVE, API, TEST_CFG, RANK3, FILES_MEDIUM = 4, FILES_HIGH = 15, LINES_MEDIUM = 100, LINES_HIGH = 500, RAN_ALWAYS, REVIEWER_ITEM = "one reviewer", PLAN, LOW_SKIPPED, deferredOf = (tier, selected, executed) => (tier === "low" ? LOW_SKIPPED : selected).filter((c) => !RAN_ALWAYS.includes(c) && !executed.includes(c)), DEEP_ITEMS, NOT_SELECTED = "not selected by risk tier: ", MANIFEST_LOCKS, dirOf = (p) => p.includes("/") ? p.slice(0, p.lastIndexOf("/")) : "", PKG_DEP_KEYS, PYPROJECT_NONDEP, SEM_RULES, DOC_FILE, readOr = (p) => {
56915
57136
  try {
56916
57137
  return readFileSync49(p, "utf8");
56917
57138
  } catch {
@@ -56935,6 +57156,7 @@ var init_check_result = __esm(() => {
56935
57156
  init_redact();
56936
57157
  FAIL_EVIDENCE = /\[(?:build|setup) failed\]|^--- FAIL|^[\w./-]+\.go:\d+:\d+: \S|\b[1-9]\d* (?:failed|errors?)\b/m;
56937
57158
  GO_FAIL_EVIDENCE = /^FAIL\t\S+\t[\d.]+s$|^panic: /m;
57159
+ CARGO_NOISE = /^\s*(?:Compiling|Finished|Running|Doc-tests|Fresh|Blocking|Downloaded|Downloading|Updating|Locking|Adding|Packaging|Building)\b|^(?:warning|error|note|help)\b|^\s*(?:-->|=\s|\||\d+\s*\||\^|~)|^(?:Some errors have detailed|For more information about)/;
56938
57160
  GO_PKG_RE = /^(?:ok|FAIL|\?)\s+\S+\s+(?:\(cached\)|[\d.]+s\b|\[(?:no test files|build failed|setup failed)\])/;
56939
57161
  FRAMEWORK_RE = /\b(?:pytest|py\.test|unittest|nose2?|tox|nox|jest|vitest|mocha|jasmine|ava|tap|playwright|cypress|karma|rspec|minitest|phpunit|pest|codeception|ctest|busted|prove)\b|\b(?:bun|deno|node|go|cargo|dotnet|swift|mix|dart|flutter|zig)\s+(?:[\w:.=-]+\s+)*test\b|\b(?:npm|pnpm|yarn|bun|npx)\b.*\btest|\b(?:mvn|mvnw|gradle|gradlew|ant|sbt|make|cmake|bazel|rake|composer|lein)\b|test/i;
56940
57162
  SCRIPT_RE = /^(?:python[\d.]*|node|bash|sh|ruby|perl)\s+(?:--?[\w-]+\s+)*([^\s-][^\s]*\.(?:py|js|mjs|cjs|sh|rb|pl))(?:\s|$)/;
@@ -56990,7 +57212,10 @@ var init_check_result = __esm(() => {
56990
57212
  node: { cmd: "node", args: ["--test"] },
56991
57213
  npm: { cmd: "npm", args: ["test", "--silent"] },
56992
57214
  go: { cmd: "go", args: ["test", "-json", "./..."] },
56993
- cargo: { cmd: "cargo", args: ["test"] }
57215
+ cargo: { cmd: "cargo", args: ["test"] },
57216
+ maven: { cmd: "mvn", args: ["-B", "test"] },
57217
+ gradle: { cmd: "gradle", args: ["cleanTest", "test", "-i", "--console=plain"] },
57218
+ javac: { cmd: "bash", args: ["-c", JAVAC_WRAPPER, "loki-javac", ".", "-"] }
56994
57219
  };
56995
57220
  URL_RE = /\b[a-z][a-z0-9+.-]{0,63}:\/\/\S+/gi;
56996
57221
  ANCHOR_RE = /(?<![\w./@-])([\w./@-]{1,512})[`'"]?(?::L?|#L|\s*\(line\s+)([1-9]\d*)(?!\d)/g;
@@ -59186,6 +59411,9 @@ function failIds(raw2) {
59186
59411
  const output = stripAnsi(raw2), gc2 = goCargoIds(output);
59187
59412
  if (gc2)
59188
59413
  return gc2;
59414
+ const jv = javaSummary(output);
59415
+ if (jv)
59416
+ return jv.failed > 0 && jv.ids.length >= jv.failed ? jv.ids : [];
59189
59417
  const ids = [...new Set(output.split(`
59190
59418
  `).map((l) => ID_LINE.exec(l.trim())).flatMap((m) => m ? [(m.slice(1).find(Boolean) ?? "").trim()] : []).filter(Boolean))];
59191
59419
  const c = failCount(output);
@@ -60715,8 +60943,8 @@ var init_runner_errors = __esm(() => {
60715
60943
 
60716
60944
  // ../../loki-ts/src/runner/load_owner.ts
60717
60945
  import { spawnSync as spawnSync5 } from "child_process";
60718
- import { mkdtempSync as mkdtempSync5, realpathSync as realpathSync23, rmSync as rmSync16 } from "fs";
60719
- import { tmpdir as tmpdir7 } from "os";
60946
+ import { mkdtempSync as mkdtempSync6, realpathSync as realpathSync23, rmSync as rmSync16 } from "fs";
60947
+ import { tmpdir as tmpdir8 } from "os";
60720
60948
  import { basename as basename17, extname as extname3, join as join66 } from "path";
60721
60949
  function changedFilesNamed(out3, repoDir, changed) {
60722
60950
  return changed.filter((f) => {
@@ -60839,7 +61067,7 @@ async function loadErrorIsHarnessOwned(i) {
60839
61067
  return false;
60840
61068
  if (i.args.some((a) => changed.includes(a.replace(/^\.\//, ""))))
60841
61069
  return false;
60842
- const dir = mkdtempSync5(join66(tmpdir7(), "e10-loadown-"));
61070
+ const dir = mkdtempSync6(join66(tmpdir8(), "e10-loadown-"));
60843
61071
  const git3 = (args) => {
60844
61072
  safeGit(i.repoDir, args, { stdio: "ignore" });
60845
61073
  };
@@ -60918,7 +61146,7 @@ ${r.stderr}`);
60918
61146
  notProven.add(`${lr2} (${name}; harness-owned)`);
60919
61147
  continue;
60920
61148
  }
60921
- const cls = classifyCheck({ kind: "test", ok: r.exitCode === 0, out: out3, ...goRunner(line2), exitCoded: isExitCodedScript(line2) });
61149
+ const cls = await corroborateGoPass(classifyCheck({ kind: "test", ok: r.exitCode === 0, out: out3, ...goRunner(line2), exitCoded: isExitCodedScript(line2) }), out3, line2, undefined, { cwd: join67(repoDir, cwd), env: suiteEnv(opts.path) });
60922
61150
  checks.push({ name, cmd, result: cls.result, duration_s, ...cls.count ? { count: cls.count } : {}, ...cls.result === "fail" ? { ids: cls.count ? [exitCodedId(line2, out3, repoDir) ?? []].flat() : failIds(out3), excerpt: failureExcerpt(out3, repoDir) } : {} });
60923
61151
  if (cls.result === "not_run")
60924
61152
  notProven.add(`not run: ${name} (${cls.reason ?? NO_TESTS_REASON})`);
@@ -63731,8 +63959,8 @@ var init_wall_owned = __esm(() => {
63731
63959
  });
63732
63960
 
63733
63961
  // ../../loki-ts/src/util/mutation_proof.ts
63734
- import { existsSync as existsSync53, mkdirSync as mkdirSync38, mkdtempSync as mkdtempSync6, readFileSync as readFileSync68, rmSync as rmSync17, symlinkSync as symlinkSync3, writeFileSync as writeFileSync36 } from "fs";
63735
- import { tmpdir as tmpdir8 } from "os";
63962
+ import { existsSync as existsSync53, mkdirSync as mkdirSync38, mkdtempSync as mkdtempSync7, readFileSync as readFileSync68, rmSync as rmSync17, symlinkSync as symlinkSync3, writeFileSync as writeFileSync36 } from "fs";
63963
+ import { tmpdir as tmpdir9 } from "os";
63736
63964
  import { basename as basename18, dirname as dirname30, isAbsolute as isAbsolute14, join as join77, relative as relative14 } from "path";
63737
63965
  function mutationProof(i) {
63738
63966
  const rels = i.wallFiles.map((f) => isAbsolute14(f.path) ? relative14(i.repoDir, f.path) : f.path);
@@ -63751,7 +63979,7 @@ function mutationProof(i) {
63751
63979
  const deadline = Date.now() + budgetS * 1000, remaining = () => deadline - Date.now();
63752
63980
  let parent = null, wt = null, added = false;
63753
63981
  try {
63754
- parent = mkdtempSync6(join77(tmpdir8(), "loki-mutproof-"));
63982
+ parent = mkdtempSync7(join77(tmpdir9(), "loki-mutproof-"));
63755
63983
  wt = join77(parent, "wt");
63756
63984
  const add3 = git5(i.repoDir, ["worktree", "add", "--detach", wt, i.baseSha], Math.max(1000, Math.min(30000, remaining())));
63757
63985
  added = existsSync53(wt) || add3.status === 0;
@@ -63837,10 +64065,10 @@ var init_mutation_proof = __esm(() => {
63837
64065
  });
63838
64066
 
63839
64067
  // ../../loki-ts/src/util/python.ts
63840
- import { accessSync, constants as constants4, existsSync as existsSync54, mkdtempSync as mkdtempSync7, readFileSync as readFileSync69, realpathSync as realpathSync25, rmSync as rmSync18, statSync as statSync24 } from "fs";
64068
+ import { accessSync, constants as constants4, existsSync as existsSync54, mkdtempSync as mkdtempSync8, readFileSync as readFileSync69, realpathSync as realpathSync25, rmSync as rmSync18, statSync as statSync24 } from "fs";
63841
64069
  import { join as join78 } from "path";
63842
64070
  import { spawnSync as spawnSync8 } from "child_process";
63843
- import { tmpdir as tmpdir9 } from "os";
64071
+ import { tmpdir as tmpdir10 } from "os";
63844
64072
  async function findPython3() {
63845
64073
  if (_pythonCache !== undefined)
63846
64074
  return _pythonCache;
@@ -63879,7 +64107,7 @@ function pySignatures2(src) {
63879
64107
  const r = spawnSync8(py2, ["-I", "-S", "-c", PY_SCRIPT], {
63880
64108
  input: src.replace(/\r\n?/g, `
63881
64109
  `),
63882
- cwd: tmpdir9(),
64110
+ cwd: tmpdir10(),
63883
64111
  timeout: PY_TIMEOUT_MS,
63884
64112
  encoding: "utf8",
63885
64113
  env: { PATH: process.env.PATH ?? "/usr/bin:/bin" },
@@ -64022,8 +64250,8 @@ ${res.stderr ?? ""}`, res.status, timedOut, junitXml);
64022
64250
  };
64023
64251
  }
64024
64252
  function spawnPytest(pythonBin, repoDir, timeoutMs, extra, withJunit) {
64025
- const pycPrefix = mkdtempSync7(join78(tmpdir9(), "loki-pyc-"));
64026
- const junitDir = mkdtempSync7(join78(tmpdir9(), "loki-junit-"));
64253
+ const pycPrefix = mkdtempSync8(join78(tmpdir10(), "loki-pyc-"));
64254
+ const junitDir = mkdtempSync8(join78(tmpdir10(), "loki-junit-"));
64027
64255
  const junit = join78(junitDir, "junit.xml");
64028
64256
  let junitXml;
64029
64257
  try {
@@ -64503,14 +64731,17 @@ class TestName(unittest.TestCase):
64503
64731
  def test_it(self): self.assertEqual(fn(1), 2)
64504
64732
  Run: python3 -m unittest <file>.`,
64505
64733
  go: `${COMMANDS.go.cmd.replace(" ./<pkg dirs>", "")}. Write a _test.go file in the package under test. Example: func TestName(t *testing.T) { if got := Fn(1); got != 2 { t.Fatalf("got %v", got) } } Run: ${COMMANDS.go.cmd.replace("<pkg dirs>", "<dir>")}.`,
64506
- cargo: `${COMMANDS.cargo.cmd}. Write an integration test file directly under tests/ that calls the crate's public API. Example: #[test] fn name() { assert_eq!(my_crate::f(1), 2); } Run: ${COMMANDS.cargo.cmd} --test <stem>.`
64734
+ cargo: `${COMMANDS.cargo.cmd}. Write an integration test file directly under tests/ that calls the crate's public API. Example: #[test] fn name() { assert_eq!(my_crate::f(1), 2); } Run: ${COMMANDS.cargo.cmd} --test <stem>.`,
64735
+ maven: `Maven + JUnit (use the JUnit version already declared in the build file). Put the file in src/test/java/ (add a package line only if the code under test is in a package). The file name must end in Test.java and the public class name must equal the file name without .java, so surefire picks it up. Example: import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; public class loki_wall_LeapTest { @Test void leap() { assertTrue(Leap.is(2000)); } } Run: ${COMMANDS.maven.cmd.replace("<class>", "<ClassName>")}.`,
64736
+ gradle: `Gradle + JUnit (use the JUnit version already declared in the build file). Put the file in src/test/java/. The public class name must equal the file name without .java and the file name must end in Test.java. Example: import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; public class loki_wall_LeapTest { @Test void leap() { assertTrue(Leap.is(2000)); } } Run: ${COMMANDS.gradle.cmd.replace("<class>", "<ClassName>")}.`,
64737
+ javac: 'Plain Java 8+ with NO test framework and NO build tool (do not import org.junit). Put the file in src/test/java/. The file name must end in Test.java and the public class name must equal the file name without .java. The class has public static void main. For every check print exactly one line, `PASS <name>` or `FAIL <name>` (name on the same line), and at the end System.exit(1) if any check failed. Catch exceptions per check so one failure does not hide the rest. Example: static void check(String n, boolean ok) { System.out.println((ok ? "PASS " : "FAIL ") + n); if (!ok) failed = true; } Run: javac the sources under src/main/java plus the file, then java <ClassName>.'
64507
64738
  };
64508
64739
  });
64509
64740
 
64510
64741
  // ../../loki-ts/src/util/holdout.ts
64511
64742
  import { createHash as createHash25 } from "crypto";
64512
64743
  import { appendFileSync as appendFileSync9, copyFileSync as copyFileSync4, existsSync as existsSync55, mkdirSync as mkdirSync39, readFileSync as readFileSync70, rmSync as rmSync19, writeFileSync as writeFileSync37 } from "fs";
64513
- import { tmpdir as tmpdir10 } from "os";
64744
+ import { tmpdir as tmpdir11 } from "os";
64514
64745
  import { basename as basename20, join as join79, relative as relative15 } from "path";
64515
64746
  function wallHoldoutRatio(env = process.env) {
64516
64747
  if (env["LOKI_WALL_HOLDOUT"]?.trim() === "0")
@@ -64581,7 +64812,7 @@ function recordHoldoutTriage(runDir, entry2) {
64581
64812
  `, { mode: 384 });
64582
64813
  } catch {}
64583
64814
  }
64584
- var sha3 = (s) => createHash25("sha256").update(s).digest("hex"), WALL_HOLDOUT_DEFAULT_RATIO = 0.2, isHoldoutCheck = (name) => name.startsWith("holdout:"), holdoutDirFor = (runId, repoDir) => join79(tmpdir10(), `loki-e10-holdout-${sha3(`${runId}:${repoDir}`).slice(0, 16)}`), MANIFEST = "manifest.json", WALL_HOLDOUT_MIN = 5, HOLDOUT_TRIAGE_FILE = "holdout-triage.jsonl";
64815
+ var sha3 = (s) => createHash25("sha256").update(s).digest("hex"), WALL_HOLDOUT_DEFAULT_RATIO = 0.2, isHoldoutCheck = (name) => name.startsWith("holdout:"), holdoutDirFor = (runId, repoDir) => join79(tmpdir11(), `loki-e10-holdout-${sha3(`${runId}:${repoDir}`).slice(0, 16)}`), MANIFEST = "manifest.json", WALL_HOLDOUT_MIN = 5, HOLDOUT_TRIAGE_FILE = "holdout-triage.jsonl";
64585
64816
  var init_holdout = () => {};
64586
64817
 
64587
64818
  // ../../loki-ts/src/features/runner_config.ts
@@ -64984,8 +65215,8 @@ var init_runner_config = __esm(() => {
64984
65215
 
64985
65216
  // ../../loki-ts/src/e10ext/assert_delta.ts
64986
65217
  import { execFileSync as execFileSync6 } from "child_process";
64987
- import { mkdtempSync as mkdtempSync8, readFileSync as readFileSync72, rmSync as rmSync20 } from "fs";
64988
- import { tmpdir as tmpdir11 } from "os";
65218
+ import { mkdtempSync as mkdtempSync9, readFileSync as readFileSync72, rmSync as rmSync20 } from "fs";
65219
+ import { tmpdir as tmpdir12 } from "os";
64989
65220
  import { join as join81 } from "path";
64990
65221
  import { basename as basename21 } from "path";
64991
65222
  function classifyAssertDelta(inp) {
@@ -64996,7 +65227,7 @@ function classifyAssertDelta(inp) {
64996
65227
  return WEAKENED;
64997
65228
  let cwd = "";
64998
65229
  try {
64999
- cwd = mkdtempSync8(join81(tmpdir11(), "loki-ad-"));
65230
+ cwd = mkdtempSync9(join81(tmpdir12(), "loki-ad-"));
65000
65231
  const raw2 = execFileSync6("python3", ["-I", "-c", PY2], {
65001
65232
  input: JSON.stringify({ path: inp.path, base: inp.base, head: inp.head, task: inp.task }),
65002
65233
  cwd,
@@ -65508,9 +65739,9 @@ app_runner_stop >/dev/null 2>&1
65508
65739
  });
65509
65740
 
65510
65741
  // ../../loki-ts/src/util/secure_scan.ts
65511
- import { copyFileSync as copyFileSync5, existsSync as existsSync57, lstatSync as lstatSync23, mkdirSync as mkdirSync41, mkdtempSync as mkdtempSync9, readFileSync as readFileSync75, realpathSync as realpathSync26, rmSync as rmSync21, statSync as statSync25, writeFileSync as writeFileSync39 } from "fs";
65742
+ import { copyFileSync as copyFileSync5, existsSync as existsSync57, lstatSync as lstatSync23, mkdirSync as mkdirSync41, mkdtempSync as mkdtempSync10, readFileSync as readFileSync75, realpathSync as realpathSync26, rmSync as rmSync21, statSync as statSync25, writeFileSync as writeFileSync39 } from "fs";
65512
65743
  import { randomBytes as randomBytes6 } from "crypto";
65513
- import { tmpdir as tmpdir12 } from "os";
65744
+ import { tmpdir as tmpdir13 } from "os";
65514
65745
  import { basename as basename22, dirname as dirname34, join as join84, resolve as resolve28, sep as sep17 } from "path";
65515
65746
  function fail(error) {
65516
65747
  return { ok: false, findings: [], error };
@@ -65560,7 +65791,7 @@ async function runSecureScan(targetDir, opts = {}) {
65560
65791
  return fail(`secure-scan failed (exit ${res.exitCode}): ${tail2}`);
65561
65792
  }
65562
65793
  async function secureScanChanged(repoDir, changed, scriptPath) {
65563
- const dir = mkdtempSync9(join84(tmpdir12(), "loki-deep-secure-"));
65794
+ const dir = mkdtempSync10(join84(tmpdir13(), "loki-deep-secure-"));
65564
65795
  try {
65565
65796
  for (const f of changed)
65566
65797
  if (existsSync57(join84(repoDir, f)) && lstatSync23(join84(repoDir, f)).isFile()) {
@@ -65721,7 +65952,7 @@ async function scanAddedLines(repoDir, opts = {}) {
65721
65952
  }
65722
65953
  if (added.size === 0)
65723
65954
  return { ok: true, findings: skipped2 };
65724
- const mirror = mkdtempSync9(join84(tmpdir12(), "loki-secure-added-"));
65955
+ const mirror = mkdtempSync10(join84(tmpdir13(), "loki-secure-added-"));
65725
65956
  try {
65726
65957
  const root = resolve28(mirror) + sep17;
65727
65958
  const chunkMap = new Map;
@@ -66266,8 +66497,8 @@ var init_conventions = __esm(() => {
66266
66497
  });
66267
66498
 
66268
66499
  // ../../loki-ts/src/util/pr_lessons.ts
66269
- import { existsSync as existsSync60, mkdirSync as mkdirSync42, mkdtempSync as mkdtempSync10, readFileSync as readFileSync78, rmSync as rmSync22, writeFileSync as writeFileSync41 } from "fs";
66270
- import { homedir as homedir10, tmpdir as tmpdir13 } from "os";
66500
+ import { existsSync as existsSync60, mkdirSync as mkdirSync42, mkdtempSync as mkdtempSync11, readFileSync as readFileSync78, rmSync as rmSync22, writeFileSync as writeFileSync41 } from "fs";
66501
+ import { homedir as homedir10, tmpdir as tmpdir14 } from "os";
66271
66502
  import { dirname as dirname36, join as join87 } from "path";
66272
66503
  import { createHash as createHash26 } from "crypto";
66273
66504
  function loadLessons(repoDir) {
@@ -67081,6 +67312,7 @@ ${relevantFiles.join(`
67081
67312
  var MAX_PLAN_LINES = 10, PLAN_OUTPUT_FILENAME = "plan-output.txt", planStage, stage2;
67082
67313
  var init_plan = __esm(() => {
67083
67314
  init_relevant_files();
67315
+ init_worker_proc();
67084
67316
  init_session();
67085
67317
  init_sizing();
67086
67318
  init_types();
@@ -67134,7 +67366,7 @@ var init_plan = __esm(() => {
67134
67366
  let planModelNote = null;
67135
67367
  if (pr2.pinOpus && !session.killed && session.exit !== 0) {
67136
67368
  planModel = planFallbackModel(ctx.model);
67137
- planModelNote = `Opus plan session failed (exit ${session.exit}); the plan ran on ${planModel}`;
67369
+ planModelNote = `Opus plan session failed (${session.exit === MAX_TURNS_EXIT ? "turn cap reached" : `exit ${session.exit}`}); the plan ran on ${planModel}`;
67138
67370
  session = await runPlan(true);
67139
67371
  }
67140
67372
  if (!session.killed && session.exit !== 0) {
@@ -67169,8 +67401,8 @@ var init_plan = __esm(() => {
67169
67401
 
67170
67402
  // ../../loki-ts/src/util/conflict_resume.ts
67171
67403
  import { createHash as createHash27 } from "crypto";
67172
- import { existsSync as existsSync64, mkdtempSync as mkdtempSync11, readFileSync as readFileSync83, rmSync as rmSync24, writeFileSync as writeFileSync45 } from "fs";
67173
- import { tmpdir as tmpdir14 } from "os";
67404
+ import { existsSync as existsSync64, mkdtempSync as mkdtempSync12, readFileSync as readFileSync83, rmSync as rmSync24, writeFileSync as writeFileSync45 } from "fs";
67405
+ import { tmpdir as tmpdir15 } from "os";
67174
67406
  import { basename as basename24, join as join92, relative as relative18 } from "path";
67175
67407
  async function resumeAfterConflict(ctx, first, firstSession) {
67176
67408
  if ((ctx.implementLeftS?.() ?? Infinity) < RESUME_MIN_LEFT_S)
@@ -67195,7 +67427,7 @@ async function adjudicateWallConflict(ctx, first, firstSession, wall) {
67195
67427
  const reason = firstSession.markers.specConflict, rels = wall.map((f10) => relative18(ctx.repoDir, f10.path)), a = reason ? wallAnchor(reason, rels) : null;
67196
67428
  if (!reason || !a)
67197
67429
  return null;
67198
- const f = wall[rels.indexOf(a.file)], ids = [], o = ctx.outputs(), cwd = mkdtempSync11(join92(tmpdir14(), "loki-e15-wall-")), name = basename24(f.path);
67430
+ const f = wall[rels.indexOf(a.file)], ids = [], o = ctx.outputs(), cwd = mkdtempSync12(join92(tmpdir15(), "loki-e15-wall-")), name = basename24(f.path);
67199
67431
  try {
67200
67432
  writeFileSync45(join92(cwd, name), f.content, "utf8");
67201
67433
  const id2 = `${first.iterationId}-wa`;
@@ -67392,6 +67624,7 @@ var init_implement = __esm(() => {
67392
67624
  init_verify();
67393
67625
  init_resolve();
67394
67626
  init_session();
67627
+ init_worker_proc();
67395
67628
  init_conflict_resume();
67396
67629
  init_session_resume();
67397
67630
  init_implement_route();
@@ -67454,7 +67687,7 @@ var init_implement = __esm(() => {
67454
67687
  } }) : null;
67455
67688
  let session = two ? two.session : await ctx.sessions.run(first);
67456
67689
  const ids = two ? two.ids : [first.iterationId];
67457
- if (resumeId && !session.killed && session.exit !== 0) {
67690
+ if (resumeId && !session.killed && session.exit !== 0 && session.exit !== MAX_TURNS_EXIT) {
67458
67691
  planChainMode = "fallback (resume failed)";
67459
67692
  if (ownId) {
67460
67693
  sessionResume = "fallback (resume failed)";
@@ -67501,7 +67734,7 @@ var init_implement = __esm(() => {
67501
67734
  const testsReverted = restoreReadOnly(readOnly);
67502
67735
  const iterationId = ids[ids.length - 1];
67503
67736
  let exit;
67504
- if (session.killed) {
67737
+ if (session.killed || session.exit === MAX_TURNS_EXIT) {
67505
67738
  exit = "killed";
67506
67739
  } else if (session.markers.specConflict) {
67507
67740
  exit = "spec_conflict";
@@ -67526,6 +67759,7 @@ var init_implement = __esm(() => {
67526
67759
  ...rt2 ? { route_model: rt2.current, route_escalations: rt2.escalations } : {},
67527
67760
  session_id: readSessionId(ctx.repoDir, iterationId),
67528
67761
  duration_s: session.durationS,
67762
+ ...session.exit === MAX_TURNS_EXIT && !session.killed ? { stop_cause: "max_turns", owner: "harness", limit_s: implementStage.limitS, elapsed_s: session.durationS } : {},
67529
67763
  ...planChainMode ? { plan_chain: planChainMode } : {},
67530
67764
  ...sessionResume ? { session_resume: sessionResume } : {},
67531
67765
  ...two ? { attempts: two.summary } : {}
@@ -68218,12 +68452,12 @@ __export(exports_deep, {
68218
68452
  deepStage: () => deepStage,
68219
68453
  DEFAULT_SECRET_SCAN_SH: () => DEFAULT_SECRET_SCAN_SH
68220
68454
  });
68221
- import { existsSync as existsSync67, mkdirSync as mkdirSync49, mkdtempSync as mkdtempSync12, rmSync as rmSync27, writeFileSync as writeFileSync48 } from "fs";
68222
- import { tmpdir as tmpdir15 } from "os";
68455
+ import { existsSync as existsSync67, mkdirSync as mkdirSync49, mkdtempSync as mkdtempSync13, rmSync as rmSync27, writeFileSync as writeFileSync48 } from "fs";
68456
+ import { tmpdir as tmpdir16 } from "os";
68223
68457
  import { join as join96 } from "path";
68224
68458
  function sessionCouncil(sessions) {
68225
68459
  return { async run(input, signal) {
68226
- const cwd = mkdtempSync12(join96(tmpdir15(), "loki-deep-council-"));
68460
+ const cwd = mkdtempSync13(join96(tmpdir16(), "loki-deep-council-"));
68227
68461
  try {
68228
68462
  writeFileSync48(join96(cwd, "diff.patch"), input.diff, "utf8");
68229
68463
  const r = await sessions.run({
@@ -68286,7 +68520,7 @@ ${r.stderr}`), lr2 = r.exitCode === 0 ? undefined : await harnessLoadReason({ re
68286
68520
  notProven.add(`${lr2} (${name}; harness-owned)`);
68287
68521
  continue;
68288
68522
  }
68289
- const cls = classifyCheck({ kind: "test", ok: r.exitCode === 0, out: out3, ...goRunner(spec.cmd, spec.args) });
68523
+ const cls = await corroborateGoPass(classifyCheck({ kind: "test", ok: r.exitCode === 0, out: out3, ...goRunner(spec.cmd, spec.args) }), out3, spec.cmd, spec.args, { cwd: ctx.repoDir, env: suiteEnv(opts.path) });
68290
68524
  checks.push({ name, cmd: [spec.cmd, ...spec.args].join(" "), result: cls.result, duration_s: durationS, ...cls.result === "fail" ? { ids: failIds(out3), excerpt: failureExcerpt(out3, ctx.repoDir) } : {} });
68291
68525
  if (cls.result === "not_run")
68292
68526
  notProven.add(`not run: ${name} (${cls.reason ?? NO_TESTS_REASON})`);
@@ -68526,8 +68760,8 @@ __export(exports_verify, {
68526
68760
  commandFor: () => commandFor,
68527
68761
  changedFiles: () => changedFiles
68528
68762
  });
68529
- import { existsSync as existsSync68, mkdtempSync as mkdtempSync13, readFileSync as readFileSync86, rmSync as rmSync28 } from "fs";
68530
- import { tmpdir as tmpdir16 } from "os";
68763
+ import { existsSync as existsSync68, mkdtempSync as mkdtempSync14, readFileSync as readFileSync86, rmSync as rmSync28 } from "fs";
68764
+ import { tmpdir as tmpdir17 } from "os";
68531
68765
  import { basename as basename25, isAbsolute as isAbsolute18, join as join97, relative as relative21 } from "path";
68532
68766
  async function runOnce3(cmd, args, cwd, signal, opts) {
68533
68767
  if (!Bun.which(cmd, { PATH: opts.path ?? process.env["PATH"] ?? "" }))
@@ -68564,7 +68798,7 @@ async function runCheck(ctx, name, cmd, args, signal, checks, opts = {}) {
68564
68798
  const kind = opts.kind ?? "test";
68565
68799
  const cwd = opts.cwd ?? ctx.repoDir;
68566
68800
  const one2 = async (a) => {
68567
- let c10 = classifyCheck({ kind, ok: a.ok, cut: a.cut, missing: a.missing, out: a.out, ...goRunner(cmd, args), path: /\.[cm]?[jt]s$/.test(args[args.length - 1] ?? "") ? args[args.length - 1] : undefined });
68801
+ let c10 = await corroborateGoPass(classifyCheck({ kind, ok: a.ok, cut: a.cut, missing: a.missing, out: a.out, ...goRunner(cmd, args), path: /\.[cm]?[jt]s$/.test(args[args.length - 1] ?? "") ? args[args.length - 1] : undefined }), a.out, cmd, args, { cwd, env: opts.path ? { ...plainTestEnv(), PATH: opts.path } : plainTestEnv() });
68568
68802
  const lr2 = kind === "test" && !a.ok && !a.cut && !a.missing ? await harnessLoadReason({ repoDir: ctx.repoDir, baseSha: ctx.baseSha, skip: installOwned(ctx.repoDir, ctx.outputs?.().intake?.install_created), out: a.out, cmd, args, signal, cwd, protect: opts.protect, ...opts.path ? { env: { PATH: opts.path } } : {} }) : undefined;
68569
68803
  if (lr2)
68570
68804
  c10 = { result: "not_run", reason: lr2, owner: "harness" };
@@ -68621,7 +68855,7 @@ async function subtractBase(ctx, api, checks, tests, changed, wall, rel, signal,
68621
68855
  const zc2 = zeroOk ? un2.filter(({ c, t }) => c.result === "not_run" && !c.owner && (c.reason ?? "").startsWith(NO_TESTS_REASON) && !wall.has(c.name) && !isHoldoutCheck(c.name) && !changed.includes(t.path) && zeroIntake.has(c.name)) : [];
68622
68856
  if (!(un2.some(({ c }) => c.result === "fail" && c.ids?.length) || sus.length || zc2.length) || signal.aborted)
68623
68857
  return out3;
68624
- const dir = mkdtempSync13(join97(tmpdir16(), "e10-base-"));
68858
+ const dir = mkdtempSync14(join97(tmpdir17(), "e10-base-"));
68625
68859
  const git9 = (args) => {
68626
68860
  safeGit(ctx.repoDir, args, { stdio: "ignore", repoDrivers: true });
68627
68861
  };
@@ -68920,8 +69154,8 @@ __export(exports_wall, {
68920
69154
  BASE_RUN_TIMEOUT_MS: () => BASE_RUN_TIMEOUT_MS
68921
69155
  });
68922
69156
  import { spawnSync as spawnSync10 } from "child_process";
68923
- import { existsSync as existsSync69, mkdirSync as mkdirSync50, mkdtempSync as mkdtempSync14, readFileSync as readFileSync87, readdirSync as readdirSync28, rmSync as rmSync29, writeFileSync as writeFileSync49 } from "fs";
68924
- import { tmpdir as tmpdir17 } from "os";
69157
+ import { existsSync as existsSync69, mkdirSync as mkdirSync50, mkdtempSync as mkdtempSync15, readFileSync as readFileSync87, readdirSync as readdirSync28, rmSync as rmSync29, writeFileSync as writeFileSync49 } from "fs";
69158
+ import { tmpdir as tmpdir18 } from "os";
68925
69159
  import { dirname as dirname39, join as join98, relative as relative22 } from "path";
68926
69160
 
68927
69161
  class RealBaseTestRunner {
@@ -69001,8 +69235,10 @@ function loadTaskText(ctx, fromPrior) {
69001
69235
  }
69002
69236
  return process.env.LOKI_E10_TASK_TEXT ?? "";
69003
69237
  }
69004
- function wallTargetDir(repoDir, existingTests) {
69238
+ function wallTargetDir(repoDir, existingTests, runners = []) {
69005
69239
  const first = existingTests[0];
69240
+ if (!first && runners.some((r) => r === "maven" || r === "gradle" || r === "javac"))
69241
+ return join98(repoDir, "src", "test", "java");
69006
69242
  return first ? join98(repoDir, dirname39(first.path)) : join98(repoDir, "tests");
69007
69243
  }
69008
69244
  async function wallAuthor(ctx, signal, retry) {
@@ -69022,15 +69258,17 @@ async function wallAuthor(ctx, signal, retry) {
69022
69258
  if (!ctx.externalPatch && planMode() !== "always" && smallTaskPath(sz2.size, hasRelevantTests(task, repoMap, testMap, ctx.tests.impacted)) === "lean") {
69023
69259
  return done({ status: "skipped", data: { size: sz2.size }, reason: "small task with a relevant test: cascade skips Wall" });
69024
69260
  }
69025
- if (testMap && runners.length === 0)
69026
- return done({ status: "skipped", data: { size: sz2.size, files: [], no_runner: true, skip_code: harnessSkipCode(), not_proven: ["Wall skipped: no runnable test command for this stack"] }, reason: "no runnable test command detected: the Wall cannot write a runnable check" });
69261
+ if (testMap && runners.length === 0) {
69262
+ const miss = missingJavaTool(repoMap?.files ?? [], process.env, ctx.repoDir);
69263
+ return done({ status: "skipped", data: { size: sz2.size, files: [], no_runner: true, skip_code: harnessSkipCode(), not_proven: [miss ? `Wall not run: ${miss} is not installed on this machine, so this Java repo could not be tested (harness-owned)` : "Wall skipped: no runnable test command for this stack"] }, reason: miss ? `${miss} is not installed: the Wall cannot run Java tests (harness-owned, not proven)` : "no runnable test command detected: the Wall cannot write a runnable check" });
69264
+ }
69027
69265
  if (testMap && runners.every((r) => r === "pytest") && projectInterpreter(ctx.repoDir) === "system" && wallHoldoutRatio() === 0)
69028
69266
  return done({ status: "skipped", data: { size: sz2.size, files: [], no_interpreter: true, not_proven: ["Wall skipped: no project test interpreter"] }, reason: "Wall skipped: no project test interpreter" });
69029
69267
  const tree = prior.intake?.tree;
69030
69268
  const repomapText = repoMapText(ctx.repoDir, tree, repomapRef, WALL_MAP_MAX_LINES);
69031
- const targetDir = wallTargetDir(ctx.repoDir, existingTests), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${relative22(ctx.repoDir, targetDir)}/x`);
69269
+ const targetDir = wallTargetDir(ctx.repoDir, existingTests, runners), pkg = loadProjectApi(ctx.repoDir)?.packageOf(`${relative22(ctx.repoDir, targetDir)}/x`);
69032
69270
  const conv2 = readPackageConventions(join98(ctx.repoDir, pkg?.root ?? "."), pkg?.runner ?? null);
69033
- const cwd = mkdtempSync14(join98(tmpdir17(), "loki-e15-wall-"));
69271
+ const cwd = mkdtempSync15(join98(tmpdir18(), "loki-e15-wall-"));
69034
69272
  const wm2 = wallManifestFor(ctx.repoDir, tree, task);
69035
69273
  for (const [n10, c] of [["task.md", task], ["repomap.txt", repomapText], ...wm2 ? [["wall_manifest.txt", wm2.text]] : []])
69036
69274
  writeFileSync49(join98(cwd, n10), c, "utf8");
@@ -70968,7 +71206,7 @@ var init_seal = __esm(() => {
70968
71206
  checks,
70969
71207
  not_proven: [],
70970
71208
  verdict,
70971
- ...typeof o.implement?.limit_s === "number" ? { implement_limit: { limit_s: o.implement.limit_s, elapsed_s: typeof o.implement.elapsed_s === "number" ? o.implement.elapsed_s : 0 } } : {},
71209
+ ...typeof o.implement?.limit_s === "number" ? { implement_limit: { limit_s: o.implement.limit_s, elapsed_s: typeof o.implement.elapsed_s === "number" ? o.implement.elapsed_s : 0, ...o.implement.stop_cause === "max_turns" ? { stop_cause: "max_turns", owner: "harness" } : {} } } : {},
70972
71210
  ...grp.section ? { group: grp.section } : {},
70973
71211
  ...ctx.failovers && ctx.failovers().length > 0 ? { failover: ctx.failovers() } : {},
70974
71212
  ...str3(o.implement?.spec_conflict_reason) !== null ? { spec_conflict_reason: sanitizeReason(str3(o.implement?.spec_conflict_reason)) } : {},
@@ -71659,9 +71897,21 @@ var init_provider = __esm(() => {
71659
71897
  });
71660
71898
 
71661
71899
  // ../../loki-ts/src/util/funnel.ts
71900
+ function blockerOf(v3) {
71901
+ return typeof v3 === "string" && PREFLIGHT_BLOCKERS.includes(v3) ? v3 : null;
71902
+ }
71903
+ function noteRefusal(b) {
71904
+ if (b)
71905
+ refusal = b;
71906
+ }
71907
+ function noteRefusalFromEvents(events2) {
71908
+ noteRefusal(blockerOf(events2.find((e10) => e10.type === "stage.failed" && e10.stage === "intake")?.data["blocker"]));
71909
+ }
71910
+ var PREFLIGHT_BLOCKERS, refusal = null;
71662
71911
  var init_funnel = __esm(() => {
71663
71912
  init_paths();
71664
71913
  init_safe_git();
71914
+ PREFLIGHT_BLOCKERS = ["not_a_repo", "git_identity", "dirty_tracked_tree", "no_provider", "not_logged_in", "prd_missing", "unsupported_flag", "disk", "other"];
71665
71915
  });
71666
71916
 
71667
71917
  // ../../loki-ts/src/cockpit/capability.ts
@@ -71676,7 +71926,7 @@ var init_raster = () => {};
71676
71926
  // ../../loki-ts/src/commands/doctor.ts
71677
71927
  import { appendFileSync as appendFileSync11, writeFileSync as writeFileSync56, mkdirSync as mkdirSync56, accessSync as accessSync2, constants as fsConstants2, existsSync as existsSync75, lstatSync as lstatSync28, readdirSync as readdirSync32, readFileSync as readFileSync94, readlinkSync as readlinkSync6, realpathSync as realpathSync31, statSync as statSync29, statfsSync } from "fs";
71678
71928
  import { spawnSync as spawnSync12 } from "child_process";
71679
- import { homedir as homedir12, tmpdir as tmpdir18 } from "os";
71929
+ import { homedir as homedir12, tmpdir as tmpdir19 } from "os";
71680
71930
  import { join as join108, resolve as resolve31 } from "path";
71681
71931
  function loadRequirements(file = REQUIREMENTS_FILE) {
71682
71932
  if (file === REQUIREMENTS_FILE && cached)
@@ -71706,7 +71956,7 @@ function providerLoginIssue(provider, cli, env) {
71706
71956
  if (provider === "codex") {
71707
71957
  if (key("OPENAI_API_KEY") || key("CODEX_API_KEY"))
71708
71958
  return null;
71709
- const r = spawnSync12(cli, ["login", "status"], { env: providerProbeEnv(env), encoding: "utf8", timeout: 5000, cwd: tmpdir18() });
71959
+ const r = spawnSync12(cli, ["login", "status"], { env: providerProbeEnv(env), encoding: "utf8", timeout: 5000, cwd: tmpdir19() });
71710
71960
  if (r.status === 0)
71711
71961
  return null;
71712
71962
  const said = `${r.stdout}${r.stderr}`;
@@ -71896,18 +72146,19 @@ async function checkPreflight(o) {
71896
72146
  pinErr = `${e10.message}; set a valid value or unset it (the run would otherwise drop the pin and use the provider default model)`;
71897
72147
  }
71898
72148
  }
71899
- const fatal = wt.exitCode !== 0 || wt.stdout.trim() !== "true" ? initFatal ?? NOT_A_REPO(o.repoDir) : !name.stdout.trim() || !email.stdout.trim() ? `git identity is not set; run: git config user.name "you" && git config user.email "you@example.com"` : !envVar ? `the v10 engine has no ${o.provider} invoker yet` : o.provider !== "claude" && truthy(env["LOKI_HOST_GUARD"]) ? `LOKI_HOST_GUARD=1 is set but provider '${o.provider}' has no enforced PreToolUse hook; unset LOKI_HOST_GUARD or use --provider claude` : pinErr ? pinErr : !cliOk ? `provider CLI '${cli}' is not on PATH; install it or set ${envVar} to its path${requirementFix(o.provider) ? `. Fix: ${requirementFix(o.provider)}` : ""}` : head.exitCode !== 0 ? "repository has no commits; run: git add . && git commit -m init" : null;
71900
- if (fatal)
71901
- return { fatal, warnings };
72149
+ const refuse = (b, f) => [b, f];
72150
+ const hit = wt.exitCode !== 0 || wt.stdout.trim() !== "true" ? refuse("not_a_repo", initFatal ?? NOT_A_REPO(o.repoDir)) : !name.stdout.trim() || !email.stdout.trim() ? refuse("git_identity", `git identity is not set; run: git config user.name "you" && git config user.email "you@example.com"`) : !envVar ? refuse("unsupported_flag", `the v10 engine has no ${o.provider} invoker yet`) : o.provider !== "claude" && truthy(env["LOKI_HOST_GUARD"]) ? refuse("other", `LOKI_HOST_GUARD=1 is set but provider '${o.provider}' has no enforced PreToolUse hook; unset LOKI_HOST_GUARD or use --provider claude`) : pinErr ? refuse("other", pinErr) : !cliOk ? refuse("no_provider", `provider CLI '${cli}' is not on PATH; install it or set ${envVar} to its path${requirementFix(o.provider) ? `. Fix: ${requirementFix(o.provider)}` : ""}`) : head.exitCode !== 0 ? refuse("other", "repository has no commits; run: git add . && git commit -m init") : null;
72151
+ if (hit)
72152
+ return { fatal: hit[1], warnings, blocker: hit[0] };
71902
72153
  try {
71903
72154
  accessSync3(o.repoDir, fsc2.W_OK);
71904
72155
  } catch {
71905
- return { fatal: `${o.repoDir} is not writable; run: chmod u+w "${o.repoDir}" (or run loki from a writable checkout)`, warnings };
72156
+ return { fatal: `${o.repoDir} is not writable; run: chmod u+w "${o.repoDir}" (or run loki from a writable checkout)`, warnings, blocker: "other" };
71906
72157
  }
71907
72158
  const free = freeMb(o.repoDir, o.statfs ?? statfsSync2);
71908
72159
  const minMb = Number(env["LOKI_MIN_FREE_MB"]) > 0 ? Number(env["LOKI_MIN_FREE_MB"]) : 200;
71909
72160
  if (free !== null && free < minMb)
71910
- return { fatal: `only ${Math.floor(free)} MB free on the volume holding ${o.repoDir} (need ${minMb} MB); free disk space, or lower LOKI_MIN_FREE_MB`, warnings };
72161
+ return { fatal: `only ${Math.floor(free)} MB free on the volume holding ${o.repoDir} (need ${minMb} MB); free disk space, or lower LOKI_MIN_FREE_MB`, warnings, blocker: "disk" };
71911
72162
  if (free !== null && free < Math.max(2048, minMb))
71912
72163
  warnings.push(`low disk: ${Math.floor(free)} MB free on the volume holding ${o.repoDir}; a long run may fail mid-way (warns under 2 GB)`);
71913
72164
  const auth_path = providerAuthPath(o.provider, env);
@@ -71943,11 +72194,11 @@ async function checkPreflight(o) {
71943
72194
  } catch {}
71944
72195
  }
71945
72196
  if (authFatal)
71946
- return { fatal: authFatal, warnings };
72197
+ return { fatal: authFatal, warnings, blocker: "not_logged_in" };
71947
72198
  if (o.pr && GITHUB_ORIGIN_RE.test((await git10(["config", "--get", "remote.origin.url"])).stdout.trim())) {
71948
72199
  const ghOk = await ghAuthProbeCached(env, async () => (await sh3(["gh", "--version"], { env, timeoutMs: 5000 })).exitCode === 0 && (await sh3(["gh", "auth", "status"], { env, timeoutMs: 1e4 })).exitCode === 0);
71949
72200
  if (!ghOk)
71950
- return { fatal: `gh (GitHub CLI) is missing or not authenticated; run gh auth login, or pass --no-pr`, warnings };
72201
+ return { fatal: `gh (GitHub CLI) is missing or not authenticated; run gh auth login, or pass --no-pr`, warnings, blocker: "other" };
71951
72202
  const plan = await probePublish((await git10(["config", "--get", "remote.origin.url"])).stdout.trim(), env);
71952
72203
  if (plan) {
71953
72204
  if (plan.warning)
@@ -71964,7 +72215,7 @@ async function assertPreflight(o) {
71964
72215
  process.stderr.write(`${w}
71965
72216
  `);
71966
72217
  if (r.fatal)
71967
- throw new PreflightError(r.fatal);
72218
+ throw new PreflightError(r.fatal, r.blocker);
71968
72219
  }
71969
72220
  var CLI_ENV_VAR, GITHUB_ORIGIN_RE, PreflightError;
71970
72221
  var init_preflight = __esm(() => {
@@ -71975,9 +72226,15 @@ var init_preflight = __esm(() => {
71975
72226
  init_first_run_repo();
71976
72227
  init_engine_origin();
71977
72228
  init_shell();
72229
+ init_funnel();
71978
72230
  CLI_ENV_VAR = { claude: "LOKI_CLAUDE_CLI", codex: "LOKI_CODEX_CLI", cline: "LOKI_CLINE_CLI", aider: "LOKI_AIDER_CLI", opencode: "LOKI_OPENCODE_CLI" };
71979
72231
  GITHUB_ORIGIN_RE = /^(?:https:\/\/(?:[^@/]+@)?github\.com\/|git@github\.com:|ssh:\/\/git@github\.com\/)/;
71980
72232
  PreflightError = class PreflightError extends Error {
72233
+ blocker;
72234
+ constructor(message, blocker = "other") {
72235
+ super(message);
72236
+ this.blocker = blocker;
72237
+ }
71981
72238
  };
71982
72239
  });
71983
72240
 
@@ -73834,8 +74091,8 @@ __export(exports_issues_run, {
73834
74091
  TRIAGE_RE: () => TRIAGE_RE
73835
74092
  });
73836
74093
  import { spawnSync as spawnSync15 } from "child_process";
73837
- import { cpSync as cpSync3, existsSync as existsSync79, mkdirSync as mkdirSync61, mkdtempSync as mkdtempSync15, rmSync as rmSync33, writeFileSync as writeFileSync59 } from "fs";
73838
- import { tmpdir as tmpdir19 } from "os";
74094
+ import { cpSync as cpSync3, existsSync as existsSync79, mkdirSync as mkdirSync61, mkdtempSync as mkdtempSync16, rmSync as rmSync33, writeFileSync as writeFileSync59 } from "fs";
74095
+ import { tmpdir as tmpdir20 } from "os";
73839
74096
  import { join as join113, resolve as resolve35 } from "path";
73840
74097
  import { createInterface as createInterface3 } from "readline";
73841
74098
  function parseIssuesArgs(args) {
@@ -74250,7 +74507,7 @@ function makeWorktrees(repoDir) {
74250
74507
  let root = null;
74251
74508
  return {
74252
74509
  create: (name, base) => {
74253
- root ??= mkdtempSync15(join113(tmpdir19(), "loki-issues-"));
74510
+ root ??= mkdtempSync16(join113(tmpdir20(), "loki-issues-"));
74254
74511
  const p = join113(root, name);
74255
74512
  safeGit(repoDir, ["worktree", "add", "-B", `loki/${name}`, p, base]);
74256
74513
  return p;
@@ -74713,6 +74970,7 @@ async function main4(args) {
74713
74970
  if (v3 === undefined || v3 === "" || v3.startsWith("-")) {
74714
74971
  process.stderr.write(`engine10: --max-cost needs a value
74715
74972
  `);
74973
+ noteRefusal("unsupported_flag");
74716
74974
  return 2;
74717
74975
  }
74718
74976
  maxCost = v3;
@@ -74724,6 +74982,7 @@ async function main4(args) {
74724
74982
  if (v3 === undefined || v3 === "" || v3.startsWith("-")) {
74725
74983
  process.stderr.write(`engine10: --provider needs a value
74726
74984
  `);
74985
+ noteRefusal("unsupported_flag");
74727
74986
  return 2;
74728
74987
  }
74729
74988
  provider = v3;
@@ -74733,6 +74992,7 @@ async function main4(args) {
74733
74992
  if (v3 === undefined || v3 === "" || v3.startsWith("-")) {
74734
74993
  process.stderr.write(`engine10: --spec needs a value
74735
74994
  `);
74995
+ noteRefusal("unsupported_flag");
74736
74996
  return 2;
74737
74997
  }
74738
74998
  specFile = v3;
@@ -74748,6 +75008,7 @@ async function main4(args) {
74748
75008
  if (v3 === undefined || v3 === "" || v3.startsWith("-")) {
74749
75009
  process.stderr.write(`engine10: --seal-existing needs a patch file
74750
75010
  `);
75011
+ noteRefusal("unsupported_flag");
74751
75012
  return 2;
74752
75013
  }
74753
75014
  sealPatch = resolve36(v3);
@@ -74759,6 +75020,7 @@ async function main4(args) {
74759
75020
  process.stderr.write(`engine10: unknown flag ${a}
74760
75021
  usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-cost N] [--provider P] [--spec F] [--seal-existing PATCH] [--resume] [--fresh] [-- <task>]
74761
75022
  `);
75023
+ noteRefusal("unsupported_flag");
74762
75024
  return 2;
74763
75025
  } else
74764
75026
  words3.push(a);
@@ -74773,6 +75035,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
74773
75035
  } catch (e10) {
74774
75036
  process.stderr.write(`engine10: ${e10.message}
74775
75037
  `);
75038
+ noteRefusal("prd_missing");
74776
75039
  return 2;
74777
75040
  }
74778
75041
  if (!task)
@@ -74789,6 +75052,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
74789
75052
  if (!task) {
74790
75053
  process.stderr.write(`engine10: no task given
74791
75054
  `);
75055
+ noteRefusal("prd_missing");
74792
75056
  return 2;
74793
75057
  }
74794
75058
  let repoDir;
@@ -74799,6 +75063,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
74799
75063
  if (!i.notice) {
74800
75064
  process.stderr.write(`engine10: ${i.fatal ?? "not inside a git repository"}
74801
75065
  `);
75066
+ noteRefusal("not_a_repo");
74802
75067
  return 2;
74803
75068
  }
74804
75069
  process.stderr.write(`engine10: ${i.notice}
@@ -74808,6 +75073,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
74808
75073
  } catch {
74809
75074
  process.stderr.write(`engine10: not inside a git repository
74810
75075
  `);
75076
+ noteRefusal("not_a_repo");
74811
75077
  return 2;
74812
75078
  }
74813
75079
  }
@@ -74969,6 +75235,7 @@ usage: loki "<task>" [--no-pr] [--deep] [--json] [--verbose] [--quiet] [--max-co
74969
75235
  if (e10.type === "stage.completed" && e10.stage === "plan")
74970
75236
  statusStep();
74971
75237
  }, { intervalMs: 500 }) : () => {};
75238
+ let refusedAs = "other";
74972
75239
  const res = await runSupervisor({
74973
75240
  runId: runId2,
74974
75241
  repoDir,
@@ -75037,6 +75304,7 @@ ${prUrl ? "One question" : "Reason"}: ${reason}
75037
75304
  throw e10;
75038
75305
  process.stderr.write(`${e10.message}
75039
75306
  `);
75307
+ refusedAs = e10.blocker;
75040
75308
  return null;
75041
75309
  });
75042
75310
  clearInterval(tailTimer);
@@ -75044,12 +75312,14 @@ ${prUrl ? "One question" : "Reason"}: ${reason}
75044
75312
  if (!res) {
75045
75313
  stopTail();
75046
75314
  liveStop();
75315
+ noteRefusal(refusedAs);
75047
75316
  return 2;
75048
75317
  }
75049
75318
  await new Promise((r) => setTimeout(r, 300));
75050
75319
  stopTail();
75051
75320
  liveStop();
75052
75321
  const events2 = readEvents(eventsPath), f = fold(events2);
75322
+ noteRefusalFromEvents(events2);
75053
75323
  const sawCost = events2.some((e10) => e10.type === "cost"), cli = process.env.LOKI_E10_INVOKER === "cli";
75054
75324
  const { usd, pc: pc2 } = summaryCost(events2, res.tampered);
75055
75325
  const out3 = json2 ? `${JSON.stringify({ ok: EXIT[res.outcome] === 0, outcome: res.outcome, stop: res.stop, run_id: runId2, receipt_sha256: res.receiptSha })}
@@ -75123,6 +75393,7 @@ var init_supervisor = __esm(() => {
75123
75393
  init_worker_proc();
75124
75394
  init_intent_card();
75125
75395
  init_preflight();
75396
+ init_funnel();
75126
75397
  init_session();
75127
75398
  init_failure_memory();
75128
75399
  init_model_downgrades();
@@ -75625,8 +75896,8 @@ var init_warm = __esm(() => {
75625
75896
 
75626
75897
  // ../../loki-ts/src/features/speed/already_done_async.ts
75627
75898
  import { execFile as execFile3 } from "child_process";
75628
- import { mkdirSync as mkdirSync65, mkdtempSync as mkdtempSync16, rmSync as rmSync34 } from "fs";
75629
- import { tmpdir as tmpdir20 } from "os";
75899
+ import { mkdirSync as mkdirSync65, mkdtempSync as mkdtempSync17, rmSync as rmSync34 } from "fs";
75900
+ import { tmpdir as tmpdir21 } from "os";
75630
75901
  import { join as join118 } from "path";
75631
75902
  function hitsUnchangedFromBase(repoDir, baseSha, paths) {
75632
75903
  if (paths.length === 0 || !baseSha)
@@ -75665,7 +75936,7 @@ function dropRoot(root) {
75665
75936
  function pinBaseTree(ctx, signal) {
75666
75937
  let root;
75667
75938
  try {
75668
- root = mkdtempSync16(join118(tmpdir20(), "loki-already-done-"));
75939
+ root = mkdtempSync17(join118(tmpdir21(), "loki-already-done-"));
75669
75940
  } catch {
75670
75941
  return Promise.resolve(null);
75671
75942
  }
@@ -75833,7 +76104,7 @@ async function runIntakeBody(ctx, signal, opts, held) {
75833
76104
  return { status: "failed", data: {}, reason: "aborted before intake started" };
75834
76105
  const { blocking: dirty, preexisting } = splitDirty(ctx.repoDir, dirtyTrackedFiles(ctx.repoDir));
75835
76106
  if (dirty.length > 0)
75836
- return { status: "failed", data: {}, reason: `dirty tracked tree: ${dirty.join(", ")}` };
76107
+ return { status: "failed", data: { blocker: "dirty_tracked_tree" }, reason: `dirty tracked tree: ${dirty.join(", ")}` };
75837
76108
  let baseSha = git13(ctx.repoDir, ["rev-parse", "HEAD"]);
75838
76109
  const startBranch = git13(ctx.repoDir, ["symbolic-ref", "-q", "--short", "HEAD"]);
75839
76110
  let stacked = stackedOnLokiRun(ctx.repoDir);
@@ -77214,8 +77485,8 @@ var init_seal2 = __esm(() => {
77214
77485
 
77215
77486
  // ../../loki-ts/src/engine10/modernize/oracle/search.ts
77216
77487
  import { spawnSync as spawnSync18 } from "child_process";
77217
- import { copyFileSync as copyFileSync6, existsSync as existsSync86, linkSync as linkSync4, mkdirSync as mkdirSync68, mkdtempSync as mkdtempSync17, readFileSync as readFileSync107, renameSync as renameSync22, rmSync as rmSync35, rmdirSync as rmdirSync2, writeFileSync as writeFileSync63 } from "fs";
77218
- import { tmpdir as tmpdir21 } from "os";
77488
+ import { copyFileSync as copyFileSync6, existsSync as existsSync86, linkSync as linkSync4, mkdirSync as mkdirSync68, mkdtempSync as mkdtempSync18, readFileSync as readFileSync107, renameSync as renameSync22, rmSync as rmSync35, rmdirSync as rmdirSync2, writeFileSync as writeFileSync63 } from "fs";
77489
+ import { tmpdir as tmpdir22 } from "os";
77219
77490
  import { basename as basename31, dirname as dirname48, join as join125 } from "path";
77220
77491
  function search(unitSource, seedCases, propose, runCapture, opts = {}) {
77221
77492
  const maxRounds = opts.maxRounds ?? 10;
@@ -77273,7 +77544,7 @@ function realCaptureRunner(unitPath, cases, outPath) {
77273
77544
  return captureFailed("old runtime unavailable");
77274
77545
  let dir = "";
77275
77546
  try {
77276
- dir = mkdtempSync17(join125(tmpdir21(), "m10-search-"));
77547
+ dir = mkdtempSync18(join125(tmpdir22(), "m10-search-"));
77277
77548
  const casesFile = join125(dir, "cases.jsonl");
77278
77549
  const outFile = join125(dir, "out.jsonl");
77279
77550
  const covFile = join125(dir, "coverage.json");
@@ -77324,7 +77595,7 @@ function resolveOldRuntimeSync() {
77324
77595
  }
77325
77596
  function makeProposeInputs(session, cap = 20) {
77326
77597
  return (unitPath, missing, round2) => {
77327
- const cwd = mkdtempSync17(join125(tmpdir21(), "m27-propose-"));
77598
+ const cwd = mkdtempSync18(join125(tmpdir22(), "m27-propose-"));
77328
77599
  try {
77329
77600
  const unitFile = join125(cwd, basename31(unitPath));
77330
77601
  copyFileSync6(unitPath, unitFile);
@@ -77368,7 +77639,7 @@ function captureUnitOracle(a) {
77368
77639
  }
77369
77640
  if (r.cases.length === 0)
77370
77641
  return { ok: false, reason: "no cases captured" };
77371
- const scratch = mkdtempSync17(join125(tmpdir21(), "m27-replay-"));
77642
+ const scratch = mkdtempSync18(join125(tmpdir22(), "m27-replay-"));
77372
77643
  const t12 = join125(scratch, "cases"), t22 = join125(scratch, "replay");
77373
77644
  const created = [];
77374
77645
  for (let p = dir;!existsSync86(p) && !created.includes(p); p = dirname48(p))
@@ -78431,7 +78702,7 @@ var init_presealed_wall = __esm(() => {
78431
78702
  import { spawnSync as spawnSync19 } from "child_process";
78432
78703
  import { createHash as createHash35 } from "crypto";
78433
78704
  import { lstatSync as lstatSync29, readFileSync as readFileSync112, readdirSync as readdirSync37, readlinkSync as readlinkSync7, realpathSync as realpathSync33, rmSync as rmSync36 } from "fs";
78434
- import { tmpdir as tmpdir22 } from "os";
78705
+ import { tmpdir as tmpdir23 } from "os";
78435
78706
  import { join as join130, sep as sep20 } from "path";
78436
78707
  function isSealedName(rel) {
78437
78708
  return TEST_FILE2.test(rel) || PYTEST_CFG.test(rel);
@@ -78578,7 +78849,7 @@ for n in sys.argv[1:]:
78578
78849
  if n in sys.stdlib_module_names or u.find_spec(n): print(n)
78579
78850
  except Exception: print(n)
78580
78851
  `;
78581
- const r = spawnSync19(target, ["-I", "-c", code, ...names], { cwd: tmpdir22(), encoding: "utf8", timeout: 30000, env: tokenFreeEnv() });
78852
+ const r = spawnSync19(target, ["-I", "-c", code, ...names], { cwd: tmpdir23(), encoding: "utf8", timeout: 30000, env: tokenFreeEnv() });
78582
78853
  return r.status === 0 ? new Set(r.stdout.split(`
78583
78854
  `).filter(Boolean)) : new Set(names);
78584
78855
  }
@@ -78857,8 +79128,8 @@ var init_wave = __esm(() => {
78857
79128
 
78858
79129
  // ../../loki-ts/src/util/modernize_unit.ts
78859
79130
  import { spawnSync as spawnSync21 } from "child_process";
78860
- import { existsSync as existsSync89, lstatSync as lstatSync30, mkdtempSync as mkdtempSync18, readFileSync as readFileSync114, realpathSync as realpathSync34, rmSync as rmSync37, statSync as statSync34, writeFileSync as writeFileSync67 } from "fs";
78861
- import { tmpdir as tmpdir23 } from "os";
79131
+ import { existsSync as existsSync89, lstatSync as lstatSync30, mkdtempSync as mkdtempSync19, readFileSync as readFileSync114, realpathSync as realpathSync34, rmSync as rmSync37, statSync as statSync34, writeFileSync as writeFileSync67 } from "fs";
79132
+ import { tmpdir as tmpdir24 } from "os";
78862
79133
  import { join as join132, sep as sep21 } from "path";
78863
79134
  function parseUnitArgs(args) {
78864
79135
  const f = {};
@@ -78976,7 +79247,7 @@ function runPythonCase(o, unitId, newTreeDir, rec2, stub) {
78976
79247
  const src = o.unitFile ? o.unitFile(unitId, newTreeDir) : defaultUnitFile(unitId, newTreeDir);
78977
79248
  if (!src || !src.endsWith(".py") || !existsSync89(src))
78978
79249
  throw new Error(`cannot locate the source of unit ${unitId} in the new tree`);
78979
- const dir = mkdtempSync18(join132(tmpdir23(), "loki-newcase-"));
79250
+ const dir = mkdtempSync19(join132(tmpdir24(), "loki-newcase-"));
78980
79251
  try {
78981
79252
  const cases = join132(dir, "in.jsonl"), out3 = join132(dir, "out.jsonl");
78982
79253
  writeFileSync67(cases, JSON.stringify({ entry: rec2.entry, args: rec2.args, kwargs: rec2.kwargs, boundaries: boundariesFromCase(rec2) }) + `
@@ -79008,10 +79279,10 @@ Usage: ${UNIT_USAGE}
79008
79279
  const runners = u10.implement && u10.runNew && u10.runStub ? null : makeUnitRunners({ target: o.target });
79009
79280
  const implement = u10.implement ?? runners.implement, runNew = u10.runNew ?? runners.runNew, runStub = u10.runStub ?? runners.runStub;
79010
79281
  const runTmp = process.env["LOKI_RUN_TMP"] ?? "";
79011
- const root = u10.tmpRoot ?? (runTmp !== "" && isRealDir(runTmp) ? runTmp : tmpdir23());
79282
+ const root = u10.tmpRoot ?? (runTmp !== "" && isRealDir(runTmp) ? runTmp : tmpdir24());
79012
79283
  let repoDir;
79013
79284
  try {
79014
- repoDir = mkdtempSync18(join132(root, "loki-unit-"));
79285
+ repoDir = mkdtempSync19(join132(root, "loki-unit-"));
79015
79286
  } catch (e10) {
79016
79287
  process.stderr.write(`modernize unit: cannot create a temp checkout directory: ${e10.message}
79017
79288
  `);
@@ -79107,8 +79378,8 @@ var init_modernize_unit = __esm(() => {
79107
79378
 
79108
79379
  // ../../loki-ts/src/util/modernize_coordinator.ts
79109
79380
  import { createHash as createHash36 } from "crypto";
79110
- import { existsSync as existsSync90, mkdtempSync as mkdtempSync19, readFileSync as readFileSync115, rmSync as rmSync38 } from "fs";
79111
- import { tmpdir as tmpdir24 } from "os";
79381
+ import { existsSync as existsSync90, mkdtempSync as mkdtempSync20, readFileSync as readFileSync115, rmSync as rmSync38 } from "fs";
79382
+ import { tmpdir as tmpdir25 } from "os";
79112
79383
  import { join as join133 } from "path";
79113
79384
  function shipUnitOf(d, unit, o) {
79114
79385
  const sealed = join133(oracleDir(d.repoDir, d.mid, unit), "sealed.json");
@@ -79287,7 +79558,7 @@ function makeAttemptRunner(o) {
79287
79558
  }
79288
79559
  function makeUnitPrep(o) {
79289
79560
  const runtimeOk = o.runtimeOk ?? (() => {
79290
- const dir = mkdtempSync19(join133(tmpdir24(), "loki-probe-"));
79561
+ const dir = mkdtempSync20(join133(tmpdir25(), "loki-probe-"));
79291
79562
  try {
79292
79563
  return realCaptureRunner(join133(dir, "probe.py"), []).error !== "old runtime unavailable";
79293
79564
  } finally {
@@ -80359,6 +80630,17 @@ function sealDrift(given, r, env = process.env) {
80359
80630
  }
80360
80631
  return null;
80361
80632
  }
80633
+ function wallNotComparedNote(receiptPath) {
80634
+ try {
80635
+ const r = JSON.parse(readFileSync119(receiptPath, "utf8"));
80636
+ if (r["schema"] !== "loki.v10.receipt/1")
80637
+ return null;
80638
+ const files = r["wall"]?.files;
80639
+ return Array.isArray(files) && files.length > 0 && !existsSync94(join136(dirname51(receiptPath), "wall")) ? "sealed Wall copies not present: not compared" : null;
80640
+ } catch {
80641
+ return null;
80642
+ }
80643
+ }
80362
80644
  var EMPTY_SHA, sha6 = (s) => createHash38("sha256").update(s).digest("hex");
80363
80645
  var init_seal_drift = __esm(() => {
80364
80646
  init_safe_git();
@@ -80802,6 +81084,14 @@ function independentLine(receiptPath) {
80802
81084
  const k3 = pass.filter((c) => isExecutedProof(c) && (c.provenance === "exogenous" || c.provenance === "independent")).length, m = pass.filter((c) => c.provenance === "agent_authored" || c.provenance === "llm_judge").length;
80803
81085
  return { line: `agent-independent: ${k3} of ${pass.length} passing checks (wall/holdout/pre-existing/static/probe); advisory: ${m}`, k: k3, of: pass.length };
80804
81086
  }
81087
+ function signedRunIdProblem(receiptPath, runId2) {
81088
+ try {
81089
+ const r = JSON.parse(readFileSync121(receiptPath, "utf8")), s = r["run_id"];
81090
+ return isEnvelope(r) || typeof s !== "string" || s === runId2 ? null : `receipt run_id ${JSON.stringify(printable(s).slice(0, 128))} does not match the run id ${JSON.stringify(runId2)} it was found under (a sealed run copied under another id)`;
81091
+ } catch {
81092
+ return null;
81093
+ }
81094
+ }
80805
81095
  async function verifyMain(args, deps, rec2) {
80806
81096
  const allowUnsigned = args.includes("--allow-unsigned") || process.env["LOKI_VERIFY_ALLOW_UNSIGNED"] === "1";
80807
81097
  const exportDsse = args.includes("--export-dsse"), requireExo = args.includes("--require-exogenous") || process.env["LOKI_VERIFY_REQUIRE_EXOGENOUS"] === "1";
@@ -80862,7 +81152,7 @@ ${/^(unknown option|expected at most one)/.test(pk2.error) ? `Usage: loki verify
80862
81152
  rec2.receiptPath = receiptPath;
80863
81153
  if (exportDsse)
80864
81154
  return exportDsseReceipt({ receiptPath, runId: byRunId ? runId2 : null, deps, verify: verifyReceipt, key: loadSigningKey(false), kidOf: kidOf2 });
80865
- const bad = byRunId ? runIdGuard(receiptPath, runId2) : null;
81155
+ const bad = byRunId ? runIdGuard(receiptPath, runId2) ?? signedRunIdProblem(receiptPath, runId2) : null;
80866
81156
  if (bad)
80867
81157
  return rec2.verdict = "TAMPERED", rec2.reasons = [bad], process.stdout.write(`run: ${runId2}
80868
81158
  verdict: TAMPERED
@@ -80917,6 +81207,11 @@ verdict: NOT VERIFIED (run outcome ${outcome}; receipt integrity ${result.verdic
80917
81207
  return 4;
80918
81208
  }
80919
81209
  }
81210
+ if (result.verdict === "VERIFIED" || result.verdict === "UNSIGNED") {
81211
+ const note = wallNotComparedNote(receiptPath);
81212
+ if (note)
81213
+ result = { ...result, reasons: [...result.reasons, note] };
81214
+ }
80920
81215
  rec2.verdict = result.verdict;
80921
81216
  rec2.reasons = result.reasons;
80922
81217
  rec2.receiptSha256 = result.receiptSha256 ?? null;
@@ -92136,9 +92431,9 @@ function createApp(opts) {
92136
92431
  }
92137
92432
 
92138
92433
  // src/server/serve.ts
92139
- var refusal = bindRefusal(process.env);
92140
- if (refusal) {
92141
- console.error(refusal);
92434
+ var refusal2 = bindRefusal(process.env);
92435
+ if (refusal2) {
92436
+ console.error(refusal2);
92142
92437
  process.exit(2);
92143
92438
  }
92144
92439
  var warning = insecureBindWarning(process.env);