loki-mode 11.17.43 → 11.17.44

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 (74) hide show
  1. package/SKILL.md +2 -2
  2. package/VERSION +1 -1
  3. package/autonomy/lib/secure-scan.py +58 -2
  4. package/autonomy/loki +20 -7
  5. package/completions/_loki +12 -2
  6. package/completions/loki.bash +16 -1
  7. package/dashboard/__init__.py +1 -1
  8. package/docs/CLI-REFERENCE.md +3 -1
  9. package/docs/INSTALLATION.md +1 -1
  10. package/docs/v10/BOARD.md +36 -36
  11. package/docs/v10/CLI-MODERN.md +1 -1
  12. package/docs/v10/PROGRESS.md +3 -0
  13. package/loki-ts/dist/loki.js +1185 -1139
  14. package/mcp/__init__.py +1 -1
  15. package/package.json +2 -2
  16. package/packages/control-plane/dist/server.js +192 -142
  17. package/plugins/loki-mode/.claude-plugin/plugin.json +1 -1
  18. package/web-app/dist/assets/{AdminPage-BKzSXu_j.js → AdminPage-DQh0uMEZ.js} +1 -1
  19. package/web-app/dist/assets/{Avatar-DJ7ngKyG.js → Avatar-84eTYVHr.js} +1 -1
  20. package/web-app/dist/assets/{Badge-DzYByk2v.js → Badge-Cdj4WuMp.js} +1 -1
  21. package/web-app/dist/assets/{Button-BxDDHZo6.js → Button-B4wS8oEx.js} +1 -1
  22. package/web-app/dist/assets/{CockpitPage-XhjPH9NC.js → CockpitPage-CmaQv_rL.js} +1 -1
  23. package/web-app/dist/assets/{ComparePage-do4LC1Kw.js → ComparePage-DfTjVQkq.js} +1 -1
  24. package/web-app/dist/assets/{ErrorBoundary-Tw_oy-Da.js → ErrorBoundary-C3TjOwpP.js} +1 -1
  25. package/web-app/dist/assets/{EvidenceReceiptPanel-BWlmi-B5.js → EvidenceReceiptPanel-A_CiIZ4X.js} +1 -1
  26. package/web-app/dist/assets/{GitHubIssuesPanel-CuyOWTsQ.js → GitHubIssuesPanel-SVaeYaPy.js} +1 -1
  27. package/web-app/dist/assets/{GitHubPRsPanel-DCCFA4Cg.js → GitHubPRsPanel-DJt7g4Pp.js} +1 -1
  28. package/web-app/dist/assets/{HomePage-zXruJ694.js → HomePage-YMXFjgBp.js} +2 -2
  29. package/web-app/dist/assets/{LoginPage-D2hTXZIt.js → LoginPage-DYg_NPth.js} +1 -1
  30. package/web-app/dist/assets/{MagicPage-8tcSJtKw.js → MagicPage-DGX4Lq5U.js} +1 -1
  31. package/web-app/dist/assets/{MetricsPage-BQbmcPiu.js → MetricsPage-uD_P4MCJ.js} +1 -1
  32. package/web-app/dist/assets/{NotFoundPage-VVysOMpk.js → NotFoundPage-DSmZyCJv.js} +1 -1
  33. package/web-app/dist/assets/{ProjectPage-WU7f9RkJ.js → ProjectPage-gCZUZcT-.js} +3 -3
  34. package/web-app/dist/assets/{ProjectsPage-DEI8Ha7d.js → ProjectsPage-YRevZmdN.js} +1 -1
  35. package/web-app/dist/assets/{SettingsPage-B9NeXoBw.js → SettingsPage-DwTsMRGS.js} +1 -1
  36. package/web-app/dist/assets/{ShowcasePage-CIRBbxd5.js → ShowcasePage-D3S-XKZm.js} +1 -1
  37. package/web-app/dist/assets/{SystemSettingsPage-CfuZUU6P.js → SystemSettingsPage-DQnfIRKG.js} +1 -1
  38. package/web-app/dist/assets/{TeamsPage-DF9nzDjA.js → TeamsPage-CWlL5x0m.js} +1 -1
  39. package/web-app/dist/assets/{TemplatesPage-BFyWWIT4.js → TemplatesPage-iutuIUEE.js} +1 -1
  40. package/web-app/dist/assets/{TerminalOutput-CYSWsLu3.js → TerminalOutput-D9yF6zBW.js} +1 -1
  41. package/web-app/dist/assets/{activity-BQ44JhWT.js → activity-9_w3VmWg.js} +1 -1
  42. package/web-app/dist/assets/{bell-CjAfaEDR.js → bell-D3OP8VZ7.js} +1 -1
  43. package/web-app/dist/assets/{bot-DgwH21q_.js → bot-DDG1cQxK.js} +1 -1
  44. package/web-app/dist/assets/{check-CHZWFNwB.js → check-EW0lJblv.js} +1 -1
  45. package/web-app/dist/assets/{chevron-left-B7Etn49H.js → chevron-left-B4rt_k4K.js} +1 -1
  46. package/web-app/dist/assets/{circle-alert-nPoVqFm8.js → circle-alert-DU98pynG.js} +1 -1
  47. package/web-app/dist/assets/{clock-C-sLUpGG.js → clock-AbKik9uE.js} +1 -1
  48. package/web-app/dist/assets/{cloud-D4K7FUJF.js → cloud-DwH-HIQ5.js} +1 -1
  49. package/web-app/dist/assets/{code-xml-BZHY2-WK.js → code-xml-ISq7rL8q.js} +1 -1
  50. package/web-app/dist/assets/{database-CEj7r6Ao.js → database-CJHcL02M.js} +1 -1
  51. package/web-app/dist/assets/{dollar-sign-DPHUDpsN.js → dollar-sign-C6-GwMUE.js} +1 -1
  52. package/web-app/dist/assets/{file-code-corner-CboHKdgp.js → file-code-corner-oa05HcOf.js} +1 -1
  53. package/web-app/dist/assets/{file-plus-DsA4DU-n.js → file-plus-p0HoytyR.js} +1 -1
  54. package/web-app/dist/assets/{globe-C7TzpMng.js → globe-CL_RV__2.js} +1 -1
  55. package/web-app/dist/assets/{hammer-B61u7zMJ.js → hammer-CRP8xWZl.js} +1 -1
  56. package/web-app/dist/assets/{index-cu9_aTCP.js → index-D86O9Ak6.js} +3 -3
  57. package/web-app/dist/assets/{layers-D6JO2rbt.js → layers-BJbaP6xJ.js} +1 -1
  58. package/web-app/dist/assets/{loader-circle-CUROrUhG.js → loader-circle-Btcxs-64.js} +1 -1
  59. package/web-app/dist/assets/{lock-BEhTudft.js → lock-Bd2Yj6rY.js} +1 -1
  60. package/web-app/dist/assets/{package-BkeBeiGM.js → package-tKCkzim3.js} +1 -1
  61. package/web-app/dist/assets/{plus-Bv-Q1BYs.js → plus-rxy1B7R4.js} +1 -1
  62. package/web-app/dist/assets/{refresh-cw-CeT9llPq.js → refresh-cw-Bykzqbq7.js} +1 -1
  63. package/web-app/dist/assets/{rotate-ccw-aUzPGF5J.js → rotate-ccw-B0zi3eqY.js} +1 -1
  64. package/web-app/dist/assets/{scroll-text-DibSs5wF.js → scroll-text-J8wWrWX-.js} +1 -1
  65. package/web-app/dist/assets/{server-DEH19wNA.js → server-B5cOTUHz.js} +1 -1
  66. package/web-app/dist/assets/{shield-alert-CtW0_p0i.js → shield-alert-CryIgWVO.js} +1 -1
  67. package/web-app/dist/assets/{thumbs-up-BMp9hCP5.js → thumbs-up-DSLZJsOW.js} +1 -1
  68. package/web-app/dist/assets/{trash-2-s4Vf7Z8i.js → trash-2-6P-i8jxc.js} +1 -1
  69. package/web-app/dist/assets/{trending-down-DnMzvTbm.js → trending-down-LGEVSvWI.js} +1 -1
  70. package/web-app/dist/assets/{trending-up-DnB-6eIb.js → trending-up-BBN_6tC-.js} +1 -1
  71. package/web-app/dist/assets/{upload-86CGmwiu.js → upload-1O3p1SX0.js} +1 -1
  72. package/web-app/dist/assets/{usePolling-BaPZfGcd.js → usePolling-CFAGN7AY.js} +1 -1
  73. package/web-app/dist/assets/{user-CLepiTkS.js → user-BkD7wEFM.js} +1 -1
  74. package/web-app/dist/index.html +1 -1
@@ -144,6 +144,11 @@ var init_redact = __esm(() => {
144
144
  [/xox[baprs]-[A-Za-z0-9-]{10,}/g, "[REDACTED:SLACK_TOKEN]"],
145
145
  [/AKIA[0-9A-Z]{16}/g, "[REDACTED:AWS_KEY]"],
146
146
  [/eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g, "[REDACTED:JWT]"],
147
+ [/\bSG\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}/g, "[REDACTED:SENDGRID_KEY]"],
148
+ [/\bSK[0-9a-f]{32}\b/g, "[REDACTED:TWILIO_KEY]"],
149
+ [/\bdckr_pat_[A-Za-z0-9_-]{20,}/g, "[REDACTED:DOCKER_TOKEN]"],
150
+ [/\bdop_v1_[a-f0-9]{64}\b/g, "[REDACTED:DIGITALOCEAN_TOKEN]"],
151
+ [/\bya29\.[A-Za-z0-9_-]{20,}/g, "[REDACTED:GOOGLE_OAUTH_TOKEN]"],
147
152
  [/AI[a-zA-Z0-9_-]{30,}/g, "[REDACTED:GOOGLE_KEY]"],
148
153
  [/glpat-[A-Za-z0-9_-]{20,}/g, "[REDACTED:GITLAB_TOKEN]"],
149
154
  [/npm_[A-Za-z0-9]{36}/g, "[REDACTED:NPM_TOKEN]"],
@@ -10853,6 +10858,114 @@ var init_run_control = __esm(() => {
10853
10858
  PARENT_PID = process.ppid;
10854
10859
  });
10855
10860
 
10861
+ // ../../loki-ts/src/features/receipt_dsse.ts
10862
+ import { createPublicKey as createPublicKey3, sign as sign2, verify as verify3 } from "crypto";
10863
+ import { readFileSync as readFileSync32 } from "fs";
10864
+ function pae(payloadType, body) {
10865
+ const t = Buffer.from(payloadType, "utf8");
10866
+ return Buffer.concat([Buffer.from(`DSSEv1 ${t.length} `), t, Buffer.from(` ${body.length} `), body]);
10867
+ }
10868
+ function verifyEnvelope(env, pubFor) {
10869
+ if (env.payloadType !== DSSE_PAYLOAD_TYPE)
10870
+ return { ok: false, reason: `unexpected payloadType: ${env.payloadType}` };
10871
+ const body = Buffer.from(env.payload, "base64");
10872
+ let unknown = "", kid = "", known = 0;
10873
+ for (const s of env.signatures) {
10874
+ if (!s || typeof s.keyid !== "string" || typeof s.sig !== "string")
10875
+ continue;
10876
+ const pub = pubFor(s.keyid);
10877
+ if (!pub) {
10878
+ unknown ||= s.keyid;
10879
+ continue;
10880
+ }
10881
+ known++;
10882
+ if (verify3(null, pae(env.payloadType, body), pub, Buffer.from(s.sig, "base64"))) {
10883
+ kid = s.keyid;
10884
+ break;
10885
+ }
10886
+ }
10887
+ if (!kid)
10888
+ return unknown && known === 0 ? { ok: false, unchecked: true, reason: `no key for keyid ${unknown} on this machine (use --pubkey FILE)` } : { ok: false, reason: "DSSE signature does not verify" };
10889
+ let st;
10890
+ try {
10891
+ st = JSON.parse(body.toString("utf8"));
10892
+ } catch {
10893
+ return { ok: false, reason: "payload is not JSON" };
10894
+ }
10895
+ if (st["_type"] !== STATEMENT_TYPE)
10896
+ return { ok: false, reason: "payload is not an in-toto Statement v1" };
10897
+ if (st["predicateType"] !== PREDICATE_TYPE)
10898
+ return { ok: false, reason: `unexpected predicateType: ${String(st["predicateType"])}` };
10899
+ const receipt = st["predicate"];
10900
+ if (!receipt || typeof receipt !== "object")
10901
+ return { ok: false, reason: "statement has no predicate" };
10902
+ const dig = st["subject"]?.[0]?.digest ?? {};
10903
+ if (dig["gitCommit"] !== receipt["head_sha"] || dig["gitTree"] !== undefined && dig["gitTree"] !== receipt["tree"])
10904
+ return { ok: false, reason: "subject digest does not match the receipt head_sha/tree" };
10905
+ return { ok: true, receipt, kid };
10906
+ }
10907
+ function outcomeOf(j) {
10908
+ try {
10909
+ return String(isEnvelope(j) ? JSON.parse(Buffer.from(j.payload, "base64").toString()).predicate.verdict : j["verdict"]);
10910
+ } catch {
10911
+ return "UNREADABLE";
10912
+ }
10913
+ }
10914
+ function envelopeRunIdProblem(j, runId) {
10915
+ if (!isEnvelope(j))
10916
+ return null;
10917
+ let id;
10918
+ try {
10919
+ id = JSON.parse(Buffer.from(j.payload, "base64").toString()).predicate?.run_id;
10920
+ } catch {
10921
+ return "envelope payload is not readable";
10922
+ }
10923
+ return id === runId ? null : `envelope predicate.run_id ${JSON.stringify(id)} does not match run id ${JSON.stringify(runId)}`;
10924
+ }
10925
+ function verifyDsseReceipt(env, d) {
10926
+ const c = verifyEnvelope(env, d.pubFor);
10927
+ if (!c.ok)
10928
+ return { verdict: c.unchecked ? "UNCHECKED" : "TAMPERED", reasons: [c.reason] };
10929
+ const computed = d.hash(c.receipt);
10930
+ if (c.receipt["receipt_sha256"] !== computed)
10931
+ return { verdict: "TAMPERED", reasons: [`receipt_sha256 mismatch: recorded ${JSON.stringify(c.receipt["receipt_sha256"])}, computed ${computed}`] };
10932
+ const jwt = c.receipt["verification"]?.jwt;
10933
+ const o = typeof jwt === "string" ? d.attest(jwt, computed) : { status: "tampered", reason: "receipt carries no attestation" };
10934
+ if (o.status !== "verified")
10935
+ return { verdict: o.status === "tampered" ? "TAMPERED" : "UNCHECKED", reasons: [o.reason ?? "attestation invalid"] };
10936
+ return { verdict: "VERIFIED", reasons: [], receiptSha256: computed };
10937
+ }
10938
+ function runIdGuard(receiptPath, runId) {
10939
+ try {
10940
+ return envelopeRunIdProblem(JSON.parse(readFileSync32(receiptPath, "utf8")), runId);
10941
+ } catch {
10942
+ return null;
10943
+ }
10944
+ }
10945
+ var DSSE_PAYLOAD_TYPE = "application/vnd.in-toto+json", STATEMENT_TYPE = "https://in-toto.io/Statement/v1", PREDICATE_TYPE = "https://autonomi.dev/loki/receipt/v10", isEnvelope = (x) => !!x && typeof x === "object" && typeof x.payloadType === "string" && typeof x.payload === "string" && Array.isArray(x.signatures);
10946
+ var init_receipt_dsse = () => {};
10947
+ // ../../loki-ts/src/contrib/forecast.ts
10948
+ var init_forecast = () => {};
10949
+
10950
+ // ../../loki-ts/src/commands/queue.ts
10951
+ var init_queue = __esm(() => {
10952
+ init_atomic();
10953
+ init_paths();
10954
+ init_forecast();
10955
+ });
10956
+
10957
+ // ../../loki-ts/src/commands/undo.ts
10958
+ var READ_ONLY_GIT;
10959
+ var init_undo = __esm(() => {
10960
+ init_paths();
10961
+ init_safe_git();
10962
+ init_verify_cmd();
10963
+ init_events();
10964
+ init_receipt_dsse();
10965
+ init_queue();
10966
+ READ_ONLY_GIT = new Set(["rev-parse", "log", "merge-base", "for-each-ref", "symbolic-ref", "rev-list", "cat-file", "show"]);
10967
+ });
10968
+
10856
10969
  // ../../loki-ts/src/util/intent_card.ts
10857
10970
  function acceptanceLines(plan) {
10858
10971
  const card = plan?.intent_card;
@@ -10871,6 +10984,8 @@ var init_run_status = __esm(() => {
10871
10984
  init_output();
10872
10985
  init_run_outputs();
10873
10986
  init_run_control();
10987
+ init_run_pid();
10988
+ init_undo();
10874
10989
  init_intent_card();
10875
10990
  TERMINAL2 = new Set(["stage.completed", "stage.failed", "stage.skipped"]);
10876
10991
  });
@@ -10915,7 +11030,7 @@ var init_run_cap = __esm(() => {
10915
11030
  });
10916
11031
 
10917
11032
  // ../../loki-ts/src/util/mutation_proof.ts
10918
- import { existsSync as existsSync26, mkdirSync as mkdirSync16, mkdtempSync as mkdtempSync3, readFileSync as readFileSync32, rmSync as rmSync10, symlinkSync, writeFileSync as writeFileSync19 } from "fs";
11033
+ import { existsSync as existsSync26, mkdirSync as mkdirSync16, mkdtempSync as mkdtempSync3, readFileSync as readFileSync33, rmSync as rmSync10, symlinkSync, writeFileSync as writeFileSync19 } from "fs";
10919
11034
  import { tmpdir as tmpdir4 } from "os";
10920
11035
  import { basename as basename14, dirname as dirname13, isAbsolute as isAbsolute6, join as join42, relative as relative3 } from "path";
10921
11036
  function mutationProof(i) {
@@ -10946,7 +11061,7 @@ function mutationProof(i) {
10946
11061
  if (!existsSync26(src))
10947
11062
  return np(`Wall file missing: ${rel}`);
10948
11063
  mkdirSync16(dirname13(join42(wt, rel)), { recursive: true });
10949
- writeFileSync19(join42(wt, rel), readFileSync32(src));
11064
+ writeFileSync19(join42(wt, rel), readFileSync33(src));
10950
11065
  }
10951
11066
  for (const rel of rels) {
10952
11067
  const parts = rel.split("/").slice(0, -1);
@@ -11097,7 +11212,7 @@ var init_shell = __esm(() => {
11097
11212
  });
11098
11213
 
11099
11214
  // ../../loki-ts/src/util/python.ts
11100
- import { accessSync, constants as constants3, existsSync as existsSync27, mkdtempSync as mkdtempSync4, readFileSync as readFileSync33, realpathSync as realpathSync18, rmSync as rmSync11, statSync as statSync16 } from "fs";
11215
+ import { accessSync, constants as constants3, existsSync as existsSync27, mkdtempSync as mkdtempSync4, readFileSync as readFileSync34, realpathSync as realpathSync18, rmSync as rmSync11, statSync as statSync16 } from "fs";
11101
11216
  import { spawnSync as spawnSync3 } from "child_process";
11102
11217
  import { tmpdir as tmpdir5 } from "os";
11103
11218
  async function findPython3() {
@@ -11547,7 +11662,7 @@ Example: test('name', () => { assert.strictEqual(fn(1), 2); }); Run: node --tes
11547
11662
 
11548
11663
  // ../../loki-ts/src/util/holdout.ts
11549
11664
  import { createHash as createHash12 } from "crypto";
11550
- import { appendFileSync as appendFileSync3, copyFileSync as copyFileSync2, existsSync as existsSync28, mkdirSync as mkdirSync17, readFileSync as readFileSync34, rmSync as rmSync12, writeFileSync as writeFileSync20 } from "fs";
11665
+ import { appendFileSync as appendFileSync3, copyFileSync as copyFileSync2, existsSync as existsSync28, mkdirSync as mkdirSync17, readFileSync as readFileSync35, rmSync as rmSync12, writeFileSync as writeFileSync20 } from "fs";
11551
11666
  import { tmpdir as tmpdir6 } from "os";
11552
11667
  import { basename as basename16, join as join43, relative as relative4 } from "path";
11553
11668
  function wallHoldoutRatio(env = process.env) {
@@ -11582,7 +11697,7 @@ function stashHoldout(o) {
11582
11697
  const files = held.map((name) => {
11583
11698
  copyFileSync2(join43(o.srcDir, name), join43(dir, name));
11584
11699
  rmSync12(join43(o.srcDir, name), { force: true });
11585
- return { name, runner: o.runnerOf(name), sha256: sha2(readFileSync34(join43(dir, name), "utf8")) };
11700
+ return { name, runner: o.runnerOf(name), sha256: sha2(readFileSync35(join43(dir, name), "utf8")) };
11586
11701
  });
11587
11702
  writeFileSync20(join43(dir, MANIFEST), JSON.stringify({ targetDir: o.targetDir, files }));
11588
11703
  return { dir, names: new Set(held) };
@@ -11591,14 +11706,14 @@ function stageHoldout(dir, repoDir) {
11591
11706
  const put = [], tests = [], missing = [];
11592
11707
  let man = null;
11593
11708
  try {
11594
- man = JSON.parse(readFileSync34(join43(dir, MANIFEST), "utf8"));
11709
+ man = JSON.parse(readFileSync35(join43(dir, MANIFEST), "utf8"));
11595
11710
  } catch {}
11596
11711
  if (!man)
11597
11712
  return { tests, missing: [`holdout store unreadable: ${basename16(dir)}`], cleanup: () => {} };
11598
11713
  mkdirSync17(man.targetDir, { recursive: true });
11599
11714
  man.files.forEach((f, i) => {
11600
11715
  const src = join43(dir, f.name);
11601
- if (!existsSync28(src) || sha2(readFileSync34(src, "utf8")) !== f.sha256) {
11716
+ if (!existsSync28(src) || sha2(readFileSync35(src, "utf8")) !== f.sha256) {
11602
11717
  missing.push(`holdout ${i + 1} missing or altered`);
11603
11718
  return;
11604
11719
  }
@@ -11623,7 +11738,7 @@ var sha2 = (s) => createHash12("sha256").update(s).digest("hex"), WALL_HOLDOUT_D
11623
11738
  var init_holdout = () => {};
11624
11739
 
11625
11740
  // ../../loki-ts/src/features/runner_config.ts
11626
- import { readFileSync as readFileSync35 } from "fs";
11741
+ import { readFileSync as readFileSync36 } from "fs";
11627
11742
  import { dirname as dirname15, join as join44, normalize as normalize2 } from "path";
11628
11743
  function tomlKey2(s, i = 0, eq2 = true) {
11629
11744
  const parts = [], ws = () => {
@@ -11982,7 +12097,7 @@ var PKG_KEYS, RAW_CONFIGS, RUNNER_CONFIGS, DEP_MAPS, RUNNER_DEP, LOCAL_SPEC, dep
11982
12097
  }
11983
12098
  }, headText = (dir, f) => {
11984
12099
  try {
11985
- return readFileSync35(join44(dir, f), "utf8");
12100
+ return readFileSync36(join44(dir, f), "utf8");
11986
12101
  } catch {
11987
12102
  return "";
11988
12103
  }
@@ -12022,7 +12137,7 @@ var init_runner_config = __esm(() => {
12022
12137
 
12023
12138
  // ../../loki-ts/src/e10ext/assert_delta.ts
12024
12139
  import { execFileSync as execFileSync3 } from "child_process";
12025
- import { mkdtempSync as mkdtempSync5, readFileSync as readFileSync36, rmSync as rmSync13 } from "fs";
12140
+ import { mkdtempSync as mkdtempSync5, readFileSync as readFileSync37, rmSync as rmSync13 } from "fs";
12026
12141
  import { tmpdir as tmpdir7 } from "os";
12027
12142
  import { join as join45 } from "path";
12028
12143
  import { basename as basename17 } from "path";
@@ -12065,7 +12180,7 @@ function assertDeltaNotes(repoDir, baseSha, headRef, path, task, baseCounts, hea
12065
12180
  return null;
12066
12181
  try {
12067
12182
  const show = (ref) => safeGit(repoDir, ["show", `${ref}:${path}`]);
12068
- const head = headRef ? show(headRef) : readFileSync36(join45(repoDir, path), "utf8");
12183
+ const head = headRef ? show(headRef) : readFileSync37(join45(repoDir, path), "utf8");
12069
12184
  const r = classifyTestEdit(path, show(baseSha), head, task, baseCounts, headCounts);
12070
12185
  return r[0]?.kind === "literal-only" ? r.map((e) => `assertion value changed (not shown to be required by the task): ${e.file}:${e.line} ${e.old} -> ${e.new}`) : null;
12071
12186
  } catch {
@@ -12277,6 +12392,7 @@ var init_runner_errors = __esm(() => {
12277
12392
  [/Interrupted: \d+ errors? during collection/, "collection error"],
12278
12393
  [/^_+ ERROR collecting /m, "collection error"],
12279
12394
  [/ImportError while importing test module/, "test module import error"],
12395
+ [/ImportError: Failed to import test module/, "unittest test module import error"],
12280
12396
  [/^ERROR: (?:file or directory not found|not found:)/m, "test path not found by the runner"],
12281
12397
  [/No test files found, exiting with code [1-9]/, "runner found no test files (wrong cwd or path)"],
12282
12398
  [/\[setup failed\]|cannot find package|no required module provides package/, "go package could not be set up"],
@@ -12480,11 +12596,11 @@ var init_wall_owned = __esm(() => {
12480
12596
 
12481
12597
  // ../../loki-ts/src/util/app_probe.ts
12482
12598
  import { spawnSync as spawnSync5 } from "child_process";
12483
- import { existsSync as existsSync29, mkdirSync as mkdirSync18, readFileSync as readFileSync37, renameSync as renameSync11, writeFileSync as writeFileSync21 } from "fs";
12599
+ import { existsSync as existsSync29, mkdirSync as mkdirSync18, readFileSync as readFileSync38, renameSync as renameSync11, writeFileSync as writeFileSync21 } from "fs";
12484
12600
  import { join as join48 } from "path";
12485
12601
  function readJson4(p) {
12486
12602
  try {
12487
- const v = JSON.parse(readFileSync37(p, "utf8"));
12603
+ const v = JSON.parse(readFileSync38(p, "utf8"));
12488
12604
  return v && typeof v === "object" ? v : null;
12489
12605
  } catch {
12490
12606
  return null;
@@ -12516,7 +12632,7 @@ async function appProbe(repoDir, lokiDir2, opts = {}) {
12516
12632
  return { checks, pid, url };
12517
12633
  }
12518
12634
  const ir = Number(m[1]), sr = Number(m[2]), hr = Number(m[3]);
12519
- const pidTxt = existsSync29(join48(dir, "app.pid")) ? readFileSync37(join48(dir, "app.pid"), "utf8").trim() : "";
12635
+ const pidTxt = existsSync29(join48(dir, "app.pid")) ? readFileSync38(join48(dir, "app.pid"), "utf8").trim() : "";
12520
12636
  pid = /^\d+$/.test(pidTxt) && sr >= 0 ? Number(pidTxt) : null;
12521
12637
  const st = readJson4(join48(dir, "state.json"));
12522
12638
  url = typeof st?.["url"] === "string" ? st["url"] : null;
@@ -12591,7 +12707,7 @@ app_runner_stop >/dev/null 2>&1
12591
12707
  });
12592
12708
 
12593
12709
  // ../../loki-ts/src/util/secure_scan.ts
12594
- import { existsSync as existsSync30, mkdirSync as mkdirSync19, mkdtempSync as mkdtempSync7, readFileSync as readFileSync38, realpathSync as realpathSync20, rmSync as rmSync15, statSync as statSync17, writeFileSync as writeFileSync22 } from "fs";
12710
+ import { existsSync as existsSync30, mkdirSync as mkdirSync19, mkdtempSync as mkdtempSync7, readFileSync as readFileSync39, realpathSync as realpathSync20, rmSync as rmSync15, statSync as statSync17, writeFileSync as writeFileSync22 } from "fs";
12595
12711
  import { tmpdir as tmpdir9 } from "os";
12596
12712
  import { dirname as dirname16, join as join49, resolve as resolve14, sep as sep11 } from "path";
12597
12713
  function fail(error) {
@@ -12771,7 +12887,7 @@ async function scanAddedLines(repoDir, opts = {}) {
12771
12887
  if (!st.isFile() || st.size > MAX_ADDED_FILE_BYTES)
12772
12888
  continue;
12773
12889
  const lines2 = new Map;
12774
- readFileSync38(join49(repoDir, p), "utf8").split(`
12890
+ readFileSync39(join49(repoDir, p), "utf8").split(`
12775
12891
  `).forEach((t, i) => lines2.set(i + 1, t));
12776
12892
  added.set(p, lines2);
12777
12893
  } catch {}
@@ -12938,7 +13054,7 @@ var init_route_block = __esm(() => {
12938
13054
  // ../../loki-ts/src/features/visual_evidence.ts
12939
13055
  import { spawn as spawn7 } from "child_process";
12940
13056
  import { createHash as createHash13, randomBytes as randomBytes5 } from "crypto";
12941
- import { existsSync as existsSync31, lstatSync as lstatSync11, mkdirSync as mkdirSync20, readdirSync as readdirSync16, readFileSync as readFileSync39, writeFileSync as writeFileSync23 } from "fs";
13057
+ import { existsSync as existsSync31, lstatSync as lstatSync11, mkdirSync as mkdirSync20, readdirSync as readdirSync16, readFileSync as readFileSync40, writeFileSync as writeFileSync23 } from "fs";
12942
13058
  import { createServer } from "net";
12943
13059
  import { dirname as dirname17, isAbsolute as isAbsolute8, join as join50, normalize as normalize3, relative as relative6, sep as sep12 } from "path";
12944
13060
  function routeFor(file) {
@@ -13017,7 +13133,7 @@ function openapiPaths(repoDir) {
13017
13133
  if (!existsSync31(p))
13018
13134
  continue;
13019
13135
  try {
13020
- const txt = readFileSync39(p, "utf8");
13136
+ const txt = readFileSync40(p, "utf8");
13021
13137
  const paths = f.endsWith(".json") ? Object.keys(JSON.parse(txt).paths ?? {}) : [...txt.matchAll(/^ {2}(\/[^\s:]*):\s*$/gm)].map((m) => m[1]);
13022
13138
  return paths.filter((x) => !x.includes("{")).slice(0, 10);
13023
13139
  } catch {
@@ -13135,14 +13251,14 @@ async function captureVisualEvidence(repoDir, runDir, changed, opts = {}) {
13135
13251
  const subs = ["backend", "frontend"].filter((d) => existsSync31(join50(repoDir, d, "package.json")));
13136
13252
  const has = (d) => {
13137
13253
  try {
13138
- return pickScript(JSON.parse(readFileSync39(join50(repoDir, d, "package.json"), "utf8"))) !== null;
13254
+ return pickScript(JSON.parse(readFileSync40(join50(repoDir, d, "package.json"), "utf8"))) !== null;
13139
13255
  } catch {
13140
13256
  return false;
13141
13257
  }
13142
13258
  };
13143
13259
  return skip(noRootReason(subs, subs.filter((d) => !has(d))));
13144
13260
  }
13145
- script = pickScript(JSON.parse(readFileSync39(pkgPath, "utf8")));
13261
+ script = pickScript(JSON.parse(readFileSync40(pkgPath, "utf8")));
13146
13262
  if (!script)
13147
13263
  return skip("no dev, preview or start script");
13148
13264
  }
@@ -13238,7 +13354,7 @@ function receiptScreensProblem(receiptPath, receipt) {
13238
13354
  return `visual evidence failed (LOKI_VISUAL_GATE=1): ${receipt["evidence_failed"]}`;
13239
13355
  return receipt["evidence_screens"] === undefined ? null : checkScreens(dirname17(receiptPath), receipt["evidence_screens"]);
13240
13356
  }
13241
- var visualEvidenceEnabled = (env = process.env) => env["LOKI_VISUAL_EVIDENCE"] !== "0", visualGateEnabled = (env = process.env) => env["LOKI_VISUAL_GATE"] === "1", PAGE_RE, isPageFile = (p) => PAGE_RE.test(p), screenName = (route) => (route === "/" ? "index" : route.slice(1).replace(/[^A-Za-z0-9._-]+/g, "_")) || "index", sha256File = (p) => createHash13("sha256").update(readFileSync39(p)).digest("hex"), playwrightBin = (repoDir) => {
13357
+ var visualEvidenceEnabled = (env = process.env) => env["LOKI_VISUAL_EVIDENCE"] !== "0", visualGateEnabled = (env = process.env) => env["LOKI_VISUAL_GATE"] === "1", PAGE_RE, isPageFile = (p) => PAGE_RE.test(p), screenName = (route) => (route === "/" ? "index" : route.slice(1).replace(/[^A-Za-z0-9._-]+/g, "_")) || "index", sha256File = (p) => createHash13("sha256").update(readFileSync40(p)).digest("hex"), playwrightBin = (repoDir) => {
13242
13358
  const bin = join50(repoDir, "node_modules", ".bin", "playwright");
13243
13359
  return existsSync31(bin) ? bin : null;
13244
13360
  }, playwrightTestPkg = (repoDir) => {
@@ -13308,7 +13424,7 @@ var init_pr = __esm(() => {
13308
13424
  });
13309
13425
 
13310
13426
  // ../../loki-ts/src/util/pr_lessons.ts
13311
- import { existsSync as existsSync32, mkdirSync as mkdirSync21, mkdtempSync as mkdtempSync8, readFileSync as readFileSync40, rmSync as rmSync16, writeFileSync as writeFileSync24 } from "fs";
13427
+ import { existsSync as existsSync32, mkdirSync as mkdirSync21, mkdtempSync as mkdtempSync8, readFileSync as readFileSync41, rmSync as rmSync16, writeFileSync as writeFileSync24 } from "fs";
13312
13428
  import { dirname as dirname18, join as join52 } from "path";
13313
13429
  import { createHash as createHash14 } from "crypto";
13314
13430
  function loadLessons(repoDir) {
@@ -13316,7 +13432,7 @@ function loadLessons(repoDir) {
13316
13432
  if (!existsSync32(p))
13317
13433
  return [];
13318
13434
  try {
13319
- const j = JSON.parse(readFileSync40(p, "utf-8"));
13435
+ const j = JSON.parse(readFileSync41(p, "utf-8"));
13320
13436
  return Array.isArray(j.lessons) ? j.lessons : [];
13321
13437
  } catch {
13322
13438
  return [];
@@ -13384,7 +13500,7 @@ var init_attempts = __esm(() => {
13384
13500
  var init_mcp_config = () => {};
13385
13501
 
13386
13502
  // ../../loki-ts/src/providers/claude_flags.ts
13387
- import { existsSync as existsSync33, readFileSync as readFileSync41 } from "fs";
13503
+ import { existsSync as existsSync33, readFileSync as readFileSync42 } from "fs";
13388
13504
  import { resolve as resolvePath, dirname as dirname19 } from "path";
13389
13505
  import { fileURLToPath as fileURLToPath4 } from "url";
13390
13506
  function claudeFlagSupported(flag, helpText) {
@@ -13439,7 +13555,7 @@ function designArchetypesText() {
13439
13555
  ]) {
13440
13556
  const p = resolvePath(moduleDir, ...rel);
13441
13557
  if (existsSync33(p))
13442
- return readFileSync41(p, "utf8");
13558
+ return readFileSync42(p, "utf8");
13443
13559
  }
13444
13560
  } catch {}
13445
13561
  return "";
@@ -13523,14 +13639,14 @@ var init_providers = __esm(() => {
13523
13639
  });
13524
13640
 
13525
13641
  // ../../loki-ts/src/runner/router/route_record.ts
13526
- import { existsSync as existsSync34, lstatSync as lstatSync12, mkdirSync as mkdirSync22, readFileSync as readFileSync42, writeFileSync as writeFileSync25 } from "fs";
13642
+ import { existsSync as existsSync34, lstatSync as lstatSync12, mkdirSync as mkdirSync22, readFileSync as readFileSync43, writeFileSync as writeFileSync25 } from "fs";
13527
13643
  import { join as join53 } from "path";
13528
13644
  function loadRouteRecord(runDir) {
13529
13645
  try {
13530
13646
  const p = join53(runDir, ROUTE_RECORD_FILE);
13531
13647
  if (!existsSync34(p) || !lstatSync12(p).isFile())
13532
13648
  return;
13533
- const v = JSON.parse(readFileSync42(p, "utf8"));
13649
+ const v = JSON.parse(readFileSync43(p, "utf8"));
13534
13650
  return typeof v === "object" && v !== null && !Array.isArray(v) ? v : undefined;
13535
13651
  } catch {
13536
13652
  return;
@@ -14368,7 +14484,7 @@ ${x}` : c.cmd };
14368
14484
  });
14369
14485
 
14370
14486
  // ../../loki-ts/src/project_model/conventions.ts
14371
- import { existsSync as existsSync37, readdirSync as readdirSync17, readFileSync as readFileSync43 } from "fs";
14487
+ import { existsSync as existsSync37, readdirSync as readdirSync17, readFileSync as readFileSync44 } from "fs";
14372
14488
  import { dirname as dirname22, join as join57 } from "path";
14373
14489
  function parseJsonc(text2) {
14374
14490
  let out2 = "", i = 0;
@@ -14444,7 +14560,7 @@ function conventionViolation(c, fileName, content) {
14444
14560
  }
14445
14561
  var readJson5 = (p) => {
14446
14562
  try {
14447
- const v = parseJsonc(readFileSync43(p, "utf8"));
14563
+ const v = parseJsonc(readFileSync44(p, "utf8"));
14448
14564
  return v && typeof v === "object" && !Array.isArray(v) ? v : null;
14449
14565
  } catch {
14450
14566
  return null;
@@ -14454,7 +14570,7 @@ var init_conventions = () => {};
14454
14570
 
14455
14571
  // ../../loki-ts/src/engine10/stages/wall.ts
14456
14572
  import { spawnSync as spawnSync6 } from "child_process";
14457
- import { existsSync as existsSync38, mkdirSync as mkdirSync24, mkdtempSync as mkdtempSync11, readFileSync as readFileSync44, readdirSync as readdirSync18, rmSync as rmSync19, writeFileSync as writeFileSync27 } from "fs";
14573
+ import { existsSync as existsSync38, mkdirSync as mkdirSync24, mkdtempSync as mkdtempSync11, readFileSync as readFileSync45, readdirSync as readdirSync18, rmSync as rmSync19, writeFileSync as writeFileSync27 } from "fs";
14458
14574
  import { tmpdir as tmpdir12 } from "os";
14459
14575
  import { dirname as dirname23, join as join58, relative as relative8 } from "path";
14460
14576
 
@@ -14515,7 +14631,7 @@ function loadTaskText(ctx, fromPrior) {
14515
14631
  const issueJsonPath = process.env.LOKI_E10_ISSUE_JSON ?? join58(ctx.runDir, "issue.json");
14516
14632
  if (existsSync38(issueJsonPath)) {
14517
14633
  try {
14518
- const issue = JSON.parse(readFileSync44(issueJsonPath, "utf8"));
14634
+ const issue = JSON.parse(readFileSync45(issueJsonPath, "utf8"));
14519
14635
  const text2 = [issue.title, issue.body].filter((s) => typeof s === "string" && s.length > 0).join(`
14520
14636
 
14521
14637
  `);
@@ -14580,14 +14696,14 @@ async function wallAuthor(ctx, signal, retry) {
14580
14696
  rmSync19(cwd, { recursive: true, force: true });
14581
14697
  return done({ status: "failed", data: { iteration_ids: [iterationId], model }, reason: "wall session aborted, killed, or timed out", killed: true });
14582
14698
  }
14583
- const all = readdirSync18(cwd).filter((f) => f.startsWith(WALL_PREFIX)), held = stashHoldout({ runId: ctx.runId, repoDir: ctx.repoDir, srcDir: cwd, targetDir, names: all.filter((n2) => !conventionViolation(conv2, n2, readFileSync44(join58(cwd, n2), "utf8"))), runnerOf: (n2) => guessRunner(n2, runners) }), generated = all.filter((n2) => !held?.names.has(n2));
14699
+ const all = readdirSync18(cwd).filter((f) => f.startsWith(WALL_PREFIX)), held = stashHoldout({ runId: ctx.runId, repoDir: ctx.repoDir, srcDir: cwd, targetDir, names: all.filter((n2) => !conventionViolation(conv2, n2, readFileSync45(join58(cwd, n2), "utf8"))), runnerOf: (n2) => guessRunner(n2, runners) }), generated = all.filter((n2) => !held?.names.has(n2));
14584
14700
  const sealedDir = join58(ctx.runDir, "wall");
14585
14701
  if (generated.length > 0)
14586
14702
  mkdirSync24(sealedDir, { recursive: true });
14587
14703
  const contents = new Map;
14588
14704
  const discarded = [];
14589
14705
  for (const name of generated) {
14590
- const content = readFileSync44(join58(cwd, name), "utf8"), bad = conventionViolation(conv2, name, content);
14706
+ const content = readFileSync45(join58(cwd, name), "utf8"), bad = conventionViolation(conv2, name, content);
14591
14707
  writeFileSync27(join58(sealedDir, name), content, "utf8");
14592
14708
  if (bad)
14593
14709
  discarded.push({ file: name, reason: `${bad}; wall test did not compile under the package config` });
@@ -14695,7 +14811,7 @@ var init_wall = __esm(() => {
14695
14811
  });
14696
14812
 
14697
14813
  // ../../loki-ts/src/e10ext/discard.ts
14698
- import { chmodSync as chmodSync5, closeSync as closeSync9, lstatSync as lstatSync14, mkdirSync as mkdirSync25, openSync as openSync9, readFileSync as readFileSync45, realpathSync as realpathSync23, rmdirSync, unlinkSync as unlinkSync6, writeFileSync as writeFileSync28 } from "fs";
14814
+ import { chmodSync as chmodSync5, closeSync as closeSync9, lstatSync as lstatSync14, mkdirSync as mkdirSync25, openSync as openSync9, readFileSync as readFileSync46, realpathSync as realpathSync23, rmdirSync, unlinkSync as unlinkSync6, writeFileSync as writeFileSync28 } from "fs";
14699
14815
  import { dirname as dirname24, join as join59, relative as relative9, sep as sep13 } from "path";
14700
14816
  function safeRestore(repoDir, f, want, mode) {
14701
14817
  const root = realpathSync23(repoDir), fp = join59(root, f), rel = relative9(root, dirname24(fp));
@@ -14720,7 +14836,7 @@ function safeRestore(repoDir, f, want, mode) {
14720
14836
  } catch {
14721
14837
  st = null;
14722
14838
  }
14723
- if (st?.isFile() && readFileSync45(fp).equals(want)) {
14839
+ if (st?.isFile() && readFileSync46(fp).equals(want)) {
14724
14840
  chmodSync5(fp, mode);
14725
14841
  return;
14726
14842
  }
@@ -14852,14 +14968,14 @@ var init_scope2 = __esm(() => {
14852
14968
  });
14853
14969
 
14854
14970
  // ../../loki-ts/src/council/role_agents.ts
14855
- import { existsSync as existsSync39, readdirSync as readdirSync19, readFileSync as readFileSync46 } from "fs";
14971
+ import { existsSync as existsSync39, readdirSync as readdirSync19, readFileSync as readFileSync47 } from "fs";
14856
14972
  import { homedir as homedir9 } from "os";
14857
14973
  import { join as join60 } from "path";
14858
14974
  function agentDirs(repoDir, env = process.env) {
14859
14975
  return [env["LOKI_AGENTS_PROJECT_DIR"] || join60(repoDir, ".loki", "agents"), env["LOKI_AGENTS_USER_DIR"] || join60(env["XDG_CONFIG_HOME"] || join60(homedir9(), ".config"), "loki", "agents")];
14860
14976
  }
14861
14977
  function parseAgent(file, stem2) {
14862
- const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(readFileSync46(file, "utf8"));
14978
+ const m = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(readFileSync47(file, "utf8"));
14863
14979
  if (!m)
14864
14980
  return null;
14865
14981
  const body = m[2].trim();
@@ -14958,15 +15074,35 @@ var init_child_ledger = __esm(() => {
14958
15074
  init_budget();
14959
15075
  });
14960
15076
 
15077
+ // ../../loki-ts/src/util/colors.ts
15078
+ function colorDisabled(env = process.env) {
15079
+ return (env["NO_COLOR"] ?? "").length > 0 || env["TERM"] === "dumb";
15080
+ }
15081
+ function color(code) {
15082
+ return NO_COLOR ? "" : code;
15083
+ }
15084
+ var NO_COLOR, RED, GREEN, YELLOW, BLUE, CYAN, BOLD, DIM, NC;
15085
+ var init_colors = __esm(() => {
15086
+ NO_COLOR = colorDisabled();
15087
+ RED = color("\x1B[0;31m");
15088
+ GREEN = color("\x1B[0;32m");
15089
+ YELLOW = color("\x1B[1;33m");
15090
+ BLUE = color("\x1B[0;34m");
15091
+ CYAN = color("\x1B[0;36m");
15092
+ BOLD = color("\x1B[1m");
15093
+ DIM = color("\x1B[2m");
15094
+ NC = color("\x1B[0m");
15095
+ });
15096
+
14961
15097
  // ../../loki-ts/src/util/run_summary.ts
14962
- import { existsSync as existsSync40, mkdirSync as mkdirSync27, readFileSync as readFileSync47, renameSync as renameSync12, statSync as statSync18, writeFileSync as writeFileSync29 } from "fs";
15098
+ import { existsSync as existsSync40, mkdirSync as mkdirSync27, readFileSync as readFileSync48, renameSync as renameSync12, statSync as statSync18, writeFileSync as writeFileSync29 } from "fs";
14963
15099
  import { join as join62 } from "path";
14964
15100
  function readRiskRecord(repoDir, sinceMs = 0) {
14965
15101
  try {
14966
15102
  const p = join62(repoDir, ".loki", "state", "risk-tier.json");
14967
15103
  if (statSync18(p).mtimeMs < sinceMs)
14968
15104
  return null;
14969
- const r = JSON.parse(readFileSync47(p, "utf8"));
15105
+ const r = JSON.parse(readFileSync48(p, "utf8"));
14970
15106
  return r && typeof r === "object" ? r : null;
14971
15107
  } catch {
14972
15108
  return null;
@@ -14977,10 +15113,11 @@ var init_run_summary = __esm(() => {
14977
15113
  init_redact();
14978
15114
  init_output();
14979
15115
  init_run_outputs();
15116
+ init_colors();
14980
15117
  });
14981
15118
 
14982
15119
  // ../../loki-ts/src/engine10/stages/xreview.ts
14983
- import { existsSync as existsSync41, readFileSync as readFileSync48 } from "fs";
15120
+ import { existsSync as existsSync41, readFileSync as readFileSync49 } from "fs";
14984
15121
  import { join as join63 } from "path";
14985
15122
  function minVerdict(verdict, review) {
14986
15123
  const ceiling = review?.level === "block" ? "PARTIAL" : verdict;
@@ -14998,7 +15135,7 @@ function explicitReview(repoDir, env) {
14998
15135
  if (!existsSync41(p))
14999
15136
  continue;
15000
15137
  try {
15001
- const m = /^review:[ \t]*["']?([A-Za-z]+)["']?[ \t]*(?:#.*)?$/m.exec(readFileSync48(p, "utf8"));
15138
+ const m = /^review:[ \t]*["']?([A-Za-z]+)["']?[ \t]*(?:#.*)?$/m.exec(readFileSync49(p, "utf8"));
15002
15139
  const v = asProvider(m?.[1]);
15003
15140
  if (v)
15004
15141
  return v;
@@ -15176,7 +15313,7 @@ See also: loki cost --detail (what a run ALREADY spent)
15176
15313
  });
15177
15314
 
15178
15315
  // ../../loki-ts/src/features/contract.ts
15179
- import { existsSync as existsSync42, lstatSync as lstatSync15, mkdirSync as mkdirSync28, readFileSync as readFileSync49, rmSync as rmSync20, writeFileSync as writeFileSync30 } from "fs";
15316
+ import { existsSync as existsSync42, lstatSync as lstatSync15, mkdirSync as mkdirSync28, readFileSync as readFileSync50, rmSync as rmSync20, writeFileSync as writeFileSync30 } from "fs";
15180
15317
  import { dirname as dirname27, join as join64 } from "path";
15181
15318
  import { createHash as createHash15 } from "crypto";
15182
15319
  function contractEnabled(env = process.env) {
@@ -15225,7 +15362,7 @@ function readContract(repoDir) {
15225
15362
  return { contract: null, notes: ["contract unreadable: too large"], sha256: null };
15226
15363
  let raw2;
15227
15364
  try {
15228
- raw2 = readFileSync49(p);
15365
+ raw2 = readFileSync50(p);
15229
15366
  } catch {
15230
15367
  return { contract: null, notes: ["contract unreadable: read failed"], sha256: null };
15231
15368
  }
@@ -15300,7 +15437,7 @@ var init_contract = __esm(() => {
15300
15437
 
15301
15438
  // ../../loki-ts/src/features/speed/seal_group.ts
15302
15439
  import { createHash as createHash16 } from "crypto";
15303
- import { existsSync as existsSync43, mkdirSync as mkdirSync29, readdirSync as readdirSync20, readFileSync as readFileSync50, renameSync as renameSync13, statSync as statSync19, writeFileSync as writeFileSync31 } from "fs";
15440
+ import { existsSync as existsSync43, mkdirSync as mkdirSync29, readdirSync as readdirSync20, readFileSync as readFileSync51, renameSync as renameSync13, statSync as statSync19, writeFileSync as writeFileSync31 } from "fs";
15304
15441
  import { dirname as dirname28, join as join65 } from "path";
15305
15442
  function sealGroup(runDir, rh) {
15306
15443
  const manifestPath = join65(runDir, "group", "manifest.json");
@@ -15331,7 +15468,7 @@ function sealGroup(runDir, rh) {
15331
15468
  const dir = join65(unitsDir(runDir), id), rp = join65(dir, "receipt.json"), ep = join65(dir, "events.jsonl");
15332
15469
  let bytes;
15333
15470
  try {
15334
- bytes = readFileSync50(rp);
15471
+ bytes = readFileSync51(rp);
15335
15472
  } catch {
15336
15473
  return fail2(`unit ${id} sub-receipt missing`);
15337
15474
  }
@@ -15348,7 +15485,7 @@ function sealGroup(runDir, rh) {
15348
15485
  unit_id: id,
15349
15486
  sub_receipt_sha256: sha3(bytes),
15350
15487
  receipt_sha256: sub["receipt_sha256"],
15351
- events_file_sha256: existsSync43(ep) ? sha3(readFileSync50(ep)) : null,
15488
+ events_file_sha256: existsSync43(ep) ? sha3(readFileSync51(ep)) : null,
15352
15489
  verdict,
15353
15490
  goal: text2(u["goal"], 200),
15354
15491
  files: (Array.isArray(u["files"]) ? u["files"] : []).map((f) => text2(f, 200)).filter(Boolean).slice(0, 50),
@@ -15392,13 +15529,13 @@ async function verifyGroup(receiptPath, receipt, rh, verifyOne, deps = {}) {
15392
15529
  try {
15393
15530
  if (!statSync19(dir).isDirectory())
15394
15531
  return bad(`unit ${id} is not a directory`);
15395
- bytes = readFileSync50(rp);
15532
+ bytes = readFileSync51(rp);
15396
15533
  } catch {
15397
15534
  return bad(`unit ${id} sub-receipt missing`);
15398
15535
  }
15399
15536
  if (sha3(bytes) !== e["sub_receipt_sha256"])
15400
15537
  return bad(`unit ${id} sub-receipt does not match its recorded hash`);
15401
- const evSha = existsSync43(ep) ? sha3(readFileSync50(ep)) : null;
15538
+ const evSha = existsSync43(ep) ? sha3(readFileSync51(ep)) : null;
15402
15539
  if (evSha !== (e["events_file_sha256"] ?? null))
15403
15540
  return bad(`unit ${id} events.jsonl does not match its recorded hash`);
15404
15541
  const sub = readJson6(rp);
@@ -15423,7 +15560,7 @@ function compositeVerdict(childVerdicts) {
15423
15560
  }
15424
15561
  var ID_RE, PASSING, sha3 = (b) => createHash16("sha256").update(b).digest("hex"), isObj10 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), text2 = (v, cap) => typeof v === "string" ? v.replace(/[\x00-\x1f\x7f]+/g, " ").trim().slice(0, cap) : "", num4 = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : 0, unitsDir = (runDir) => join65(runDir, "group", "units"), readJson6 = (p) => {
15425
15562
  try {
15426
- return JSON.parse(readFileSync50(p, "utf8"));
15563
+ return JSON.parse(readFileSync51(p, "utf8"));
15427
15564
  } catch {
15428
15565
  return;
15429
15566
  }
@@ -15441,7 +15578,7 @@ var init_seal_group = __esm(() => {
15441
15578
  });
15442
15579
 
15443
15580
  // ../../loki-ts/src/supply/supply_guard.ts
15444
- import { existsSync as existsSync44, readFileSync as readFileSync51, statSync as statSync20 } from "fs";
15581
+ import { existsSync as existsSync44, readFileSync as readFileSync52, statSync as statSync20 } from "fs";
15445
15582
  import { basename as basename21, join as join66 } from "path";
15446
15583
  function supplyEnabled(env) {
15447
15584
  return env["LOKI_SUPPLY_GUARD"] !== "0";
@@ -15463,7 +15600,7 @@ function readDeclared(repoDir) {
15463
15600
  try {
15464
15601
  if (statSync20(p).size > MAX_FILE_BYTES)
15465
15602
  return { deps: [], problem: "declaration file too large" };
15466
- const j = JSON.parse(readFileSync51(p, "utf8"));
15603
+ const j = JSON.parse(readFileSync52(p, "utf8"));
15467
15604
  if (!Array.isArray(j))
15468
15605
  return { deps: [], problem: "declaration is not a JSON array" };
15469
15606
  const deps = [];
@@ -15487,7 +15624,7 @@ function readAllowlist(repoDir) {
15487
15624
  if (!existsSync44(p))
15488
15625
  return new Set;
15489
15626
  try {
15490
- return new Set(readFileSync51(p, "utf8").split(`
15627
+ return new Set(readFileSync52(p, "utf8").split(`
15491
15628
  `).map((l) => l.replace(/#.*$/, "").trim()).filter(Boolean));
15492
15629
  } catch {
15493
15630
  return new Set;
@@ -15670,7 +15807,7 @@ var MIN_AGE_DAYS = 7, DECLARED_FILE = "supply-declared.json", MAX_CHECKED = 50,
15670
15807
  }
15671
15808
  }, PUBLIC_HOSTS, hostOf = (u) => u.trim().toLowerCase().replace(/^[a-z][a-z0-9+.-]*:\/\//, "").replace(/^www\./, "").split(/[/?#\s]/)[0].replace(/^[^@]*@/, "").replace(/:\d+$/, ""), privateUrl = (u) => /[a-z0-9]/i.test(u) && !PUBLIC_HOSTS.has(hostOf(u)), readSmall = (p) => {
15672
15809
  try {
15673
- return statSync20(p).size <= MAX_FILE_BYTES ? readFileSync51(p, "utf8") : "";
15810
+ return statSync20(p).size <= MAX_FILE_BYTES ? readFileSync52(p, "utf8") : "";
15674
15811
  } catch {
15675
15812
  return "";
15676
15813
  }
@@ -15686,7 +15823,7 @@ var init_supply_guard = __esm(() => {
15686
15823
 
15687
15824
  // ../../loki-ts/src/engine10/stages/seal.ts
15688
15825
  import { createHash as createHash17 } from "crypto";
15689
- import { existsSync as existsSync45, readdirSync as readdirSync21, mkdirSync as mkdirSync30, readFileSync as readFileSync52, writeFileSync as writeFileSync32 } from "fs";
15826
+ import { existsSync as existsSync45, readdirSync as readdirSync21, mkdirSync as mkdirSync30, readFileSync as readFileSync53, writeFileSync as writeFileSync32 } from "fs";
15690
15827
  import { basename as basename22, isAbsolute as isAbsolute11, join as join67, relative as relative10 } from "path";
15691
15828
  function sanitizeReason(s) {
15692
15829
  const collapsed = s.replace(/[\x00-\x1f\x7f]+/g, " ").trim();
@@ -15996,7 +16133,7 @@ var init_seal = __esm(() => {
15996
16133
  provider: ctx.provider,
15997
16134
  model: ctx.model,
15998
16135
  resumed: o.intake?.resumed === true,
15999
- events_sha256: sha2562(existsSync45(eventsPath) ? readFileSync52(eventsPath) : ""),
16136
+ events_sha256: sha2562(existsSync45(eventsPath) ? readFileSync53(eventsPath) : ""),
16000
16137
  ...await sealEvidence(ctx.repoDir, ctx.runDir, o, notProven, signal, ctx.emit),
16001
16138
  log_seal: true,
16002
16139
  ...receiptBlock(process.env, cost.usd, cost.unmetered === true, totalS),
@@ -16045,93 +16182,6 @@ var init_seal = __esm(() => {
16045
16182
  };
16046
16183
  });
16047
16184
 
16048
- // ../../loki-ts/src/features/receipt_dsse.ts
16049
- import { createPublicKey as createPublicKey3, sign as sign2, verify as verify3 } from "crypto";
16050
- import { readFileSync as readFileSync53 } from "fs";
16051
- function pae(payloadType, body) {
16052
- const t = Buffer.from(payloadType, "utf8");
16053
- return Buffer.concat([Buffer.from(`DSSEv1 ${t.length} `), t, Buffer.from(` ${body.length} `), body]);
16054
- }
16055
- function verifyEnvelope(env, pubFor) {
16056
- if (env.payloadType !== DSSE_PAYLOAD_TYPE)
16057
- return { ok: false, reason: `unexpected payloadType: ${env.payloadType}` };
16058
- const body = Buffer.from(env.payload, "base64");
16059
- let unknown = "", kid = "", known = 0;
16060
- for (const s of env.signatures) {
16061
- if (!s || typeof s.keyid !== "string" || typeof s.sig !== "string")
16062
- continue;
16063
- const pub = pubFor(s.keyid);
16064
- if (!pub) {
16065
- unknown ||= s.keyid;
16066
- continue;
16067
- }
16068
- known++;
16069
- if (verify3(null, pae(env.payloadType, body), pub, Buffer.from(s.sig, "base64"))) {
16070
- kid = s.keyid;
16071
- break;
16072
- }
16073
- }
16074
- if (!kid)
16075
- return unknown && known === 0 ? { ok: false, unchecked: true, reason: `no key for keyid ${unknown} on this machine (use --pubkey FILE)` } : { ok: false, reason: "DSSE signature does not verify" };
16076
- let st;
16077
- try {
16078
- st = JSON.parse(body.toString("utf8"));
16079
- } catch {
16080
- return { ok: false, reason: "payload is not JSON" };
16081
- }
16082
- if (st["_type"] !== STATEMENT_TYPE)
16083
- return { ok: false, reason: "payload is not an in-toto Statement v1" };
16084
- if (st["predicateType"] !== PREDICATE_TYPE)
16085
- return { ok: false, reason: `unexpected predicateType: ${String(st["predicateType"])}` };
16086
- const receipt = st["predicate"];
16087
- if (!receipt || typeof receipt !== "object")
16088
- return { ok: false, reason: "statement has no predicate" };
16089
- const dig = st["subject"]?.[0]?.digest ?? {};
16090
- if (dig["gitCommit"] !== receipt["head_sha"] || dig["gitTree"] !== undefined && dig["gitTree"] !== receipt["tree"])
16091
- return { ok: false, reason: "subject digest does not match the receipt head_sha/tree" };
16092
- return { ok: true, receipt, kid };
16093
- }
16094
- function outcomeOf(j) {
16095
- try {
16096
- return String(isEnvelope(j) ? JSON.parse(Buffer.from(j.payload, "base64").toString()).predicate.verdict : j["verdict"]);
16097
- } catch {
16098
- return "UNREADABLE";
16099
- }
16100
- }
16101
- function envelopeRunIdProblem(j, runId) {
16102
- if (!isEnvelope(j))
16103
- return null;
16104
- let id;
16105
- try {
16106
- id = JSON.parse(Buffer.from(j.payload, "base64").toString()).predicate?.run_id;
16107
- } catch {
16108
- return "envelope payload is not readable";
16109
- }
16110
- return id === runId ? null : `envelope predicate.run_id ${JSON.stringify(id)} does not match run id ${JSON.stringify(runId)}`;
16111
- }
16112
- function verifyDsseReceipt(env, d) {
16113
- const c = verifyEnvelope(env, d.pubFor);
16114
- if (!c.ok)
16115
- return { verdict: c.unchecked ? "UNCHECKED" : "TAMPERED", reasons: [c.reason] };
16116
- const computed = d.hash(c.receipt);
16117
- if (c.receipt["receipt_sha256"] !== computed)
16118
- return { verdict: "TAMPERED", reasons: [`receipt_sha256 mismatch: recorded ${JSON.stringify(c.receipt["receipt_sha256"])}, computed ${computed}`] };
16119
- const jwt = c.receipt["verification"]?.jwt;
16120
- const o = typeof jwt === "string" ? d.attest(jwt, computed) : { status: "tampered", reason: "receipt carries no attestation" };
16121
- if (o.status !== "verified")
16122
- return { verdict: o.status === "tampered" ? "TAMPERED" : "UNCHECKED", reasons: [o.reason ?? "attestation invalid"] };
16123
- return { verdict: "VERIFIED", reasons: [], receiptSha256: computed };
16124
- }
16125
- function runIdGuard(receiptPath, runId) {
16126
- try {
16127
- return envelopeRunIdProblem(JSON.parse(readFileSync53(receiptPath, "utf8")), runId);
16128
- } catch {
16129
- return null;
16130
- }
16131
- }
16132
- var DSSE_PAYLOAD_TYPE = "application/vnd.in-toto+json", STATEMENT_TYPE = "https://in-toto.io/Statement/v1", PREDICATE_TYPE = "https://autonomi.dev/loki/receipt/v10", isEnvelope = (x) => !!x && typeof x === "object" && typeof x.payloadType === "string" && typeof x.payload === "string" && Array.isArray(x.signatures);
16133
- var init_receipt_dsse = () => {};
16134
-
16135
16185
  // ../../loki-ts/src/util/composite_seal.ts
16136
16186
  import { existsSync as existsSync46, readFileSync as readFileSync54 } from "fs";
16137
16187
  import { basename as basename23, dirname as dirname30, join as join68 } from "path";