@attalabs/vinaya 0.21.0 → 0.22.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 (117) hide show
  1. package/README.md +3 -2
  2. package/aeg-root/enforcement.md +2 -1
  3. package/aeg-root/roles/archivist.md +1 -1
  4. package/aeg-root/roles/planner.md +1 -1
  5. package/aeg-root/templates/pr-report-template.md +2 -0
  6. package/aeg-root/tranche-model.md +3 -3
  7. package/dist/checks/bin/check-body-bare-digits.js +115 -9
  8. package/dist/checks/bin/check-branch-topology.js +111 -5
  9. package/dist/checks/bin/check-brief-shape.js +111 -5
  10. package/dist/checks/bin/check-changeset-coverage.js +113 -7
  11. package/dist/checks/bin/check-closes-n.js +111 -5
  12. package/dist/checks/bin/check-coherence.js +115 -9
  13. package/dist/checks/bin/check-dead-branch-push.js +111 -5
  14. package/dist/checks/bin/check-dispatch-readiness.js +116 -10
  15. package/dist/checks/bin/check-doc-coverage-push.js +116 -10
  16. package/dist/checks/bin/check-doc-coverage.js +116 -10
  17. package/dist/checks/bin/check-doctrine-portability.js +115 -9
  18. package/dist/checks/bin/check-evidence-fresh.js +111 -5
  19. package/dist/checks/bin/check-first-push-dispatch.js +113 -7
  20. package/dist/checks/bin/check-issue-assignment.js +111 -5
  21. package/dist/checks/bin/check-main-branch-refusal.js +111 -5
  22. package/dist/checks/bin/check-no-disk-state.js +111 -5
  23. package/dist/checks/bin/check-quoted-command.js +121 -12
  24. package/dist/checks/bin/check-reader-resolvable-prose.js +152 -20
  25. package/dist/checks/bin/check-registry-gates.js +131 -10
  26. package/dist/checks/bin/check-retired-vocabulary.js +144 -12
  27. package/dist/checks/bin/check-review-gate.js +113 -7
  28. package/dist/checks/bin/check-single-plan-pr.js +111 -5
  29. package/dist/checks/bin/check-test-plan.js +111 -5
  30. package/dist/checks/bin/check-token-collection-wired.js +113 -7
  31. package/dist/checks/bin/check-token-report.js +4096 -0
  32. package/dist/checks/bin/check-workspace-escape.js +113 -7
  33. package/dist/index.js +177 -104
  34. package/package.json +1 -1
  35. package/studio-standalone/apps/vinaya-studio/web/.next/BUILD_ID +1 -1
  36. package/studio-standalone/apps/vinaya-studio/web/.next/build-manifest.json +3 -3
  37. package/studio-standalone/apps/vinaya-studio/web/.next/prerender-manifest.json +3 -3
  38. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.html +1 -1
  39. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.rsc +1 -1
  40. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  41. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  42. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  43. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  44. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  45. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page/server-reference-manifest.json +2 -2
  46. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  47. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  48. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page/server-reference-manifest.json +2 -2
  49. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page.js.nft.json +1 -1
  50. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page_client-reference-manifest.js +1 -1
  51. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page/server-reference-manifest.json +2 -2
  52. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page.js.nft.json +1 -1
  53. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page_client-reference-manifest.js +1 -1
  54. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page/server-reference-manifest.json +2 -2
  55. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page.js.nft.json +1 -1
  56. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page_client-reference-manifest.js +1 -1
  57. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page/server-reference-manifest.json +2 -2
  58. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page.js.nft.json +1 -1
  59. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page_client-reference-manifest.js +1 -1
  60. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page/server-reference-manifest.json +2 -2
  61. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page.js.nft.json +1 -1
  62. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page_client-reference-manifest.js +1 -1
  63. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page/server-reference-manifest.json +2 -2
  64. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page.js.nft.json +1 -1
  65. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page_client-reference-manifest.js +1 -1
  66. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page/server-reference-manifest.json +2 -2
  67. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page.js.nft.json +1 -1
  68. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page_client-reference-manifest.js +1 -1
  69. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page/server-reference-manifest.json +2 -2
  70. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page.js.nft.json +1 -1
  71. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page_client-reference-manifest.js +1 -1
  72. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/1q96_modules_@clerk_nextjs_dist_esm_app-router_client_keyless-creator-reader_0lom2js.js +1 -1
  73. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0053k9k._.js +1 -1
  74. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0112h-k._.js +1 -1
  75. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__02c71kv._.js +1 -1
  76. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__0ozbaq0._.js → [root-of-the-server]__069-_41._.js} +1 -1
  77. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0o771t1._.js +1 -1
  78. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0puovz5._.js +1 -1
  79. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1hs0dcu._.js +1 -1
  80. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1wc4-ip._.js +1 -1
  81. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_03x_w6q._.js +1 -1
  82. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0gvm3og._.js +1 -1
  83. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0lwxg63._.js +1 -1
  84. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0o54suy._.js +1 -1
  85. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1-6rzip._.js +1 -1
  86. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1mrtj0f._.js +1 -1
  87. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1n0cnq-._.js +1 -1
  88. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/apps_vinaya-studio_web_src_app_studio_06it6s-._.js +1 -1
  89. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/node_modules_1vo08dj._.js +2 -2
  90. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_animate_components_index_ts_186fje1._.js +1 -1
  91. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_brutal_components_index_ts_0n_lcc4._.js +1 -1
  92. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_retro_components_index_ts_0wvpm_z._.js +1 -1
  93. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_retro_components_index_ts_1_cfi48._.js +1 -1
  94. package/studio-standalone/apps/vinaya-studio/web/.next/server/middleware-build-manifest.js +3 -3
  95. package/studio-standalone/apps/vinaya-studio/web/.next/server/pages/500.html +1 -1
  96. package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.js +1 -1
  97. package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.json +3 -3
  98. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/00pi8vhg8w6gi.js +1 -0
  99. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0r4i_ks9z02bw.js → 03q0q9n6-xah8.js} +1 -1
  100. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/0vc2u252q5q6o.js +1 -0
  101. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1k916ih3p4nsg.js → 13g16cu00g570.js} +1 -1
  102. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/1hufpuody6vjv.js +1 -0
  103. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{2hmannd4bjhzy.js → 1sfxfunirkcr6.js} +1 -1
  104. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1t2kft7bxzuxn.js → 206ajg8f1a-_h.js} +1 -1
  105. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1hfhxjy577l5d.js → 267o-tsrnuwnv.js} +1 -1
  106. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{25kbt5k-xb2a5.js → 279qq4twinc97.js} +1 -1
  107. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{112g08xpx3kro.js → 2ka8dg687auhj.js} +1 -1
  108. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0up5x3jg-cwov.js → 2rn89uwtf2lwc.js} +1 -1
  109. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{2_k6j1o9q5nn4.js → 37hnluhzj9bei.js} +1 -1
  110. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{3mqu_uhluy19i.css → 3qc67qhcvbg0o.css} +1 -1
  111. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1yqs2zgvwa4p1.js → 3zugx9esh2x51.js} +1 -1
  112. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/0_jnwbarv-cqk.js +0 -1
  113. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/1ybrihl5_aocy.js +0 -1
  114. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/3r5efmleneaco.js +0 -1
  115. /package/studio-standalone/apps/vinaya-studio/web/.next/static/{crNCHQ9uAgKOYC6DKkZma → Fmyc42qzLwFcWWHLLNy-G}/_buildManifest.js +0 -0
  116. /package/studio-standalone/apps/vinaya-studio/web/.next/static/{crNCHQ9uAgKOYC6DKkZma → Fmyc42qzLwFcWWHLLNy-G}/_clientMiddlewareManifest.js +0 -0
  117. /package/studio-standalone/apps/vinaya-studio/web/.next/static/{crNCHQ9uAgKOYC6DKkZma → Fmyc42qzLwFcWWHLLNy-G}/_ssgManifest.js +0 -0
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/checks/bin/check-doc-coverage-push.ts
4
4
  import { execFileSync as execFileSync4 } from "node:child_process";
5
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
5
+ import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
6
6
  // ../../packages/aeg-core/src/gate-audience.ts
7
7
  var GATE_AUDIENCE = {
8
8
  "check-branch-topology": { shippedAs: "branch-topology", ring: 0 },
@@ -1792,6 +1792,99 @@ var DERIVED_STATUSES = [
1792
1792
  "incoherent"
1793
1793
  ];
1794
1794
  var DERIVABLE_STATUSES = DERIVED_STATUSES.filter((s) => s !== "backlog");
1795
+ // ../../packages/aeg-core/src/parse-ledger.ts
1796
+ function rowFromCells(cells) {
1797
+ if (cells.length < 7)
1798
+ return null;
1799
+ const phase = (cells[0] ?? "").trim();
1800
+ if (!phase)
1801
+ return null;
1802
+ return {
1803
+ phase,
1804
+ role: (cells[1] ?? "").trim(),
1805
+ agentModel: (cells[2] ?? "").trim(),
1806
+ tokensIn: parseIntCell(cells[3] ?? ""),
1807
+ tokensOut: parseIntCell(cells[4] ?? ""),
1808
+ cost: parseCostCell(cells[5] ?? ""),
1809
+ date: (cells[6] ?? "").trim()
1810
+ };
1811
+ }
1812
+ function parseIntCell(cell) {
1813
+ const trimmed = cell.replace(/`/g, "").trim();
1814
+ if (!trimmed || isEmDashOrDash(trimmed))
1815
+ return null;
1816
+ const normalized = trimmed.replace(/[,_\s]/g, "");
1817
+ if (!/^-?\d+$/.test(normalized))
1818
+ return null;
1819
+ return Number(normalized);
1820
+ }
1821
+ function parseCostCell(cell) {
1822
+ const trimmed = cell.replace(/`/g, "").trim();
1823
+ if (!trimmed || isEmDashOrDash(trimmed))
1824
+ return null;
1825
+ const normalized = trimmed.replace(/^\$/, "").replace(/[,_\s]/g, "");
1826
+ if (!/^-?\d+(\.\d+)?$/.test(normalized))
1827
+ return null;
1828
+ return Number(normalized);
1829
+ }
1830
+ function isEmDashOrDash(s) {
1831
+ const t = s.trim();
1832
+ return t === "—" || t === "-" || t === "–";
1833
+ }
1834
+ // ../../packages/aeg-core/src/parse-token-report.ts
1835
+ var TOKEN_REPORT_HEADING = /^\s*(?:#{1,6}\s*Token report\s*|\*\*Token report\*\*)\s*$/i;
1836
+ var INLINE_FIELD_LIST = /Phase:\s*([^|]+?)\s*\|\s*Role:\s*([^|]+?)\s*\|\s*Agent\/Model:\s*([^|]+?)\s*\|\s*Tokens in:\s*([^|]+?)\s*\|\s*Tokens out:\s*([^|]+?)\s*\|\s*Cost:\s*([^|]+?)\s*\|\s*Date:\s*(.+?)\s*$/im;
1837
+ function parseTokenReportEntries(body) {
1838
+ const lines = body.split(/\r?\n/);
1839
+ const headingIdxs = [];
1840
+ lines.forEach((line, i) => {
1841
+ if (TOKEN_REPORT_HEADING.test(line))
1842
+ headingIdxs.push(i);
1843
+ });
1844
+ const out = [];
1845
+ for (let h = 0;h < headingIdxs.length; h++) {
1846
+ const start = headingIdxs[h] + 1;
1847
+ const end = h + 1 < headingIdxs.length ? headingIdxs[h + 1] : lines.length;
1848
+ const section = lines.slice(start, end).join(`
1849
+ `);
1850
+ const tableRows = parseTableSection(section);
1851
+ if (tableRows.length > 0) {
1852
+ out.push(...tableRows);
1853
+ continue;
1854
+ }
1855
+ const inlineRow = parseInlineFieldList(section);
1856
+ if (inlineRow)
1857
+ out.push(inlineRow);
1858
+ }
1859
+ return out;
1860
+ }
1861
+ function parseTableSection(section) {
1862
+ const lines = section.split(/\r?\n/);
1863
+ let i = 0;
1864
+ for (;i < lines.length; i++) {
1865
+ if ((lines[i] ?? "").trim().startsWith("|"))
1866
+ break;
1867
+ }
1868
+ if (i + 1 >= lines.length)
1869
+ return [];
1870
+ i += 2;
1871
+ const out = [];
1872
+ for (;i < lines.length; i++) {
1873
+ const trimmed = (lines[i] ?? "").trim();
1874
+ if (!trimmed.startsWith("|"))
1875
+ break;
1876
+ const row = rowFromCells(splitTableRow(trimmed));
1877
+ if (row)
1878
+ out.push(row);
1879
+ }
1880
+ return out;
1881
+ }
1882
+ function parseInlineFieldList(section) {
1883
+ const m = section.match(INLINE_FIELD_LIST);
1884
+ if (!m)
1885
+ return null;
1886
+ return rowFromCells([m[1], m[2], m[3], m[4], m[5], m[6], m[7]]);
1887
+ }
1795
1888
  // ../../packages/aeg-core/src/report-tokens.ts
1796
1889
  var DASH_LOOKALIKES = {
1797
1890
  "-": "‑",
@@ -1800,6 +1893,7 @@ var DASH_LOOKALIKES = {
1800
1893
  };
1801
1894
  var DASH_CHARS = new Set(Object.keys(DASH_LOOKALIKES));
1802
1895
  // ../../packages/aeg-core/src/claude-code-transcript.ts
1896
+ import { createHash } from "node:crypto";
1803
1897
  function summarizeTranscript(jsonl) {
1804
1898
  const seen = new Set;
1805
1899
  const components = {
@@ -1848,7 +1942,14 @@ function numberOr(value, fallback) {
1848
1942
  function sanitizeKey(value) {
1849
1943
  return value.replace(/[^A-Za-z0-9]+/g, "-");
1850
1944
  }
1945
+ function collisionResistantKey(value) {
1946
+ const digest = createHash("sha256").update(value).digest("hex");
1947
+ return `${sanitizeKey(value)}-${digest}`;
1948
+ }
1851
1949
  function transcriptPointerPath(projectDir, tmpDir) {
1950
+ return `${tmpDir}/claude-transcript-${collisionResistantKey(projectDir)}.txt`;
1951
+ }
1952
+ function legacyTranscriptPointerPath(projectDir, tmpDir) {
1852
1953
  return `${tmpDir}/claude-transcript-${sanitizeKey(projectDir)}.txt`;
1853
1954
  }
1854
1955
  function resolvePointer(explicitTranscriptPath, deps) {
@@ -1856,13 +1957,15 @@ function resolvePointer(explicitTranscriptPath, deps) {
1856
1957
  return { path: explicitTranscriptPath, corroborated: true };
1857
1958
  const projectDir = deps.env.CLAUDE_PROJECT_DIR ?? deps.cwd;
1858
1959
  const tmpDir = deps.env.TMPDIR ?? "/tmp";
1859
- const pointerPath = transcriptPointerPath(projectDir, tmpDir);
1960
+ const primaryPointerPath = transcriptPointerPath(projectDir, tmpDir);
1961
+ const legacyPointerPath = legacyTranscriptPointerPath(projectDir, tmpDir);
1860
1962
  const currentSessionId = deps.env.CLAUDE_CODE_SESSION_ID;
1861
- if (!deps.exists(pointerPath)) {
1963
+ const pointerPath = deps.exists(primaryPointerPath) ? primaryPointerPath : deps.exists(legacyPointerPath) ? legacyPointerPath : undefined;
1964
+ if (!pointerPath) {
1862
1965
  return {
1863
1966
  pointerExisted: false,
1864
1967
  corroborated: false,
1865
- error: `No transcript pointer at ${pointerPath} and no --transcript given. ` + "Either this repo installs no track-transcript.sh Stop hook (lacking one is not a defect — " + "name the transcript directly instead), or no session has completed a turn yet."
1968
+ error: `No transcript pointer at ${primaryPointerPath} (nor its pre-migration name ${legacyPointerPath}) ` + "and no --transcript given. Either this repo installs no track-transcript.sh Stop hook (lacking one " + "is not a defect — name the transcript directly instead), or no session has completed a turn yet."
1866
1969
  };
1867
1970
  }
1868
1971
  let contents;
@@ -1937,6 +2040,9 @@ function isTokenCollectionWiringBroken(capability) {
1937
2040
  return false;
1938
2041
  return capability.reason !== "no-transcript-resolved";
1939
2042
  }
2043
+ // ../../packages/aeg-core/src/metering-io-guard.ts
2044
+ import { closeSync, constants as fsConstants, fstatSync, openSync, readFileSync } from "node:fs";
2045
+ var GUARD_OPEN_FLAGS = fsConstants.O_RDONLY | fsConstants.O_NONBLOCK | fsConstants.O_NOFOLLOW;
1940
2046
  // ../../packages/aeg-core/src/file-classify.ts
1941
2047
  function isCodeFile(p) {
1942
2048
  if (p.endsWith(".md"))
@@ -2143,7 +2249,7 @@ function overrideActive(opts) {
2143
2249
  return false;
2144
2250
  }
2145
2251
  // ../../packages/aeg-core/src/premise-check.ts
2146
- import { createHash } from "node:crypto";
2252
+ import { createHash as createHash2 } from "node:crypto";
2147
2253
  var ASSERTION_KINDS = new Set(["contains", "absent", "sha256"]);
2148
2254
  function isPremiseHeader(line) {
2149
2255
  const stripped = line.replace(/[*#]/g, "").trim();
@@ -2188,7 +2294,7 @@ function checkPremises(assertions, fileReader) {
2188
2294
  } else if (a.kind === "absent" && content.includes(a.value)) {
2189
2295
  failures.push(`premise-check: ${a.path} now contains "${a.value}", but the brief pinned it absent — the premise has moved; re-dig before proceeding.`);
2190
2296
  } else if (a.kind === "sha256") {
2191
- const actual = createHash("sha256").update(content).digest("hex");
2297
+ const actual = createHash2("sha256").update(content).digest("hex");
2192
2298
  if (actual !== a.value.toLowerCase()) {
2193
2299
  failures.push(`premise-check: ${a.path} sha256 mismatch (brief pinned ${a.value}, file is now ${actual}) — the file changed since this brief was authored; re-dig before proceeding.`);
2194
2300
  }
@@ -3988,7 +4094,7 @@ function emitCheckError(error) {
3988
4094
 
3989
4095
  // src/lib/config.ts
3990
4096
  import { execFileSync as execFileSync3 } from "node:child_process";
3991
- import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
4097
+ import { existsSync, mkdirSync, readFileSync as readFileSync2, realpathSync, writeFileSync } from "node:fs";
3992
4098
  import { homedir } from "node:os";
3993
4099
  import { dirname, join as join2, resolve } from "node:path";
3994
4100
  import { z } from "zod";
@@ -4281,7 +4387,7 @@ function loadConfig() {
4281
4387
  if (!path)
4282
4388
  return null;
4283
4389
  try {
4284
- const raw = JSON.parse(readFileSync(path, "utf-8"));
4390
+ const raw = JSON.parse(readFileSync2(path, "utf-8"));
4285
4391
  return stripGlobalOnlyKeys(VinayaConfigSchema.parse(raw), path);
4286
4392
  } catch {
4287
4393
  return null;
@@ -4307,7 +4413,7 @@ function resolvePrBody() {
4307
4413
  return process.env.PR_BODY;
4308
4414
  if (process.env.PR_BODY_FILE) {
4309
4415
  try {
4310
- return readFileSync2(process.env.PR_BODY_FILE, "utf8");
4416
+ return readFileSync3(process.env.PR_BODY_FILE, "utf8");
4311
4417
  } catch {
4312
4418
  return "";
4313
4419
  }
@@ -4342,7 +4448,7 @@ function main() {
4342
4448
  }
4343
4449
  if (changed.length === 0)
4344
4450
  process.exit(0);
4345
- const content = existsSync2(DOC_OWNERS_PATH) ? readFileSync2(DOC_OWNERS_PATH, "utf8") : null;
4451
+ const content = existsSync2(DOC_OWNERS_PATH) ? readFileSync3(DOC_OWNERS_PATH, "utf8") : null;
4346
4452
  const result = evaluateC5(changed, content, resolvePrBody(), existsSync2, waiverActiveFromEnv(), (p) => fileDiffAgainst(ref, p));
4347
4453
  for (const message of result.errors) {
4348
4454
  emitCheckError({
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/checks/bin/check-doc-coverage.ts
4
4
  import { execFileSync as execFileSync4 } from "node:child_process";
5
- import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
5
+ import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
6
6
  // ../../packages/aeg-core/src/gate-audience.ts
7
7
  var GATE_AUDIENCE = {
8
8
  "check-branch-topology": { shippedAs: "branch-topology", ring: 0 },
@@ -1792,6 +1792,99 @@ var DERIVED_STATUSES = [
1792
1792
  "incoherent"
1793
1793
  ];
1794
1794
  var DERIVABLE_STATUSES = DERIVED_STATUSES.filter((s) => s !== "backlog");
1795
+ // ../../packages/aeg-core/src/parse-ledger.ts
1796
+ function rowFromCells(cells) {
1797
+ if (cells.length < 7)
1798
+ return null;
1799
+ const phase = (cells[0] ?? "").trim();
1800
+ if (!phase)
1801
+ return null;
1802
+ return {
1803
+ phase,
1804
+ role: (cells[1] ?? "").trim(),
1805
+ agentModel: (cells[2] ?? "").trim(),
1806
+ tokensIn: parseIntCell(cells[3] ?? ""),
1807
+ tokensOut: parseIntCell(cells[4] ?? ""),
1808
+ cost: parseCostCell(cells[5] ?? ""),
1809
+ date: (cells[6] ?? "").trim()
1810
+ };
1811
+ }
1812
+ function parseIntCell(cell) {
1813
+ const trimmed = cell.replace(/`/g, "").trim();
1814
+ if (!trimmed || isEmDashOrDash(trimmed))
1815
+ return null;
1816
+ const normalized = trimmed.replace(/[,_\s]/g, "");
1817
+ if (!/^-?\d+$/.test(normalized))
1818
+ return null;
1819
+ return Number(normalized);
1820
+ }
1821
+ function parseCostCell(cell) {
1822
+ const trimmed = cell.replace(/`/g, "").trim();
1823
+ if (!trimmed || isEmDashOrDash(trimmed))
1824
+ return null;
1825
+ const normalized = trimmed.replace(/^\$/, "").replace(/[,_\s]/g, "");
1826
+ if (!/^-?\d+(\.\d+)?$/.test(normalized))
1827
+ return null;
1828
+ return Number(normalized);
1829
+ }
1830
+ function isEmDashOrDash(s) {
1831
+ const t = s.trim();
1832
+ return t === "—" || t === "-" || t === "–";
1833
+ }
1834
+ // ../../packages/aeg-core/src/parse-token-report.ts
1835
+ var TOKEN_REPORT_HEADING = /^\s*(?:#{1,6}\s*Token report\s*|\*\*Token report\*\*)\s*$/i;
1836
+ var INLINE_FIELD_LIST = /Phase:\s*([^|]+?)\s*\|\s*Role:\s*([^|]+?)\s*\|\s*Agent\/Model:\s*([^|]+?)\s*\|\s*Tokens in:\s*([^|]+?)\s*\|\s*Tokens out:\s*([^|]+?)\s*\|\s*Cost:\s*([^|]+?)\s*\|\s*Date:\s*(.+?)\s*$/im;
1837
+ function parseTokenReportEntries(body) {
1838
+ const lines = body.split(/\r?\n/);
1839
+ const headingIdxs = [];
1840
+ lines.forEach((line, i) => {
1841
+ if (TOKEN_REPORT_HEADING.test(line))
1842
+ headingIdxs.push(i);
1843
+ });
1844
+ const out = [];
1845
+ for (let h = 0;h < headingIdxs.length; h++) {
1846
+ const start = headingIdxs[h] + 1;
1847
+ const end = h + 1 < headingIdxs.length ? headingIdxs[h + 1] : lines.length;
1848
+ const section = lines.slice(start, end).join(`
1849
+ `);
1850
+ const tableRows = parseTableSection(section);
1851
+ if (tableRows.length > 0) {
1852
+ out.push(...tableRows);
1853
+ continue;
1854
+ }
1855
+ const inlineRow = parseInlineFieldList(section);
1856
+ if (inlineRow)
1857
+ out.push(inlineRow);
1858
+ }
1859
+ return out;
1860
+ }
1861
+ function parseTableSection(section) {
1862
+ const lines = section.split(/\r?\n/);
1863
+ let i = 0;
1864
+ for (;i < lines.length; i++) {
1865
+ if ((lines[i] ?? "").trim().startsWith("|"))
1866
+ break;
1867
+ }
1868
+ if (i + 1 >= lines.length)
1869
+ return [];
1870
+ i += 2;
1871
+ const out = [];
1872
+ for (;i < lines.length; i++) {
1873
+ const trimmed = (lines[i] ?? "").trim();
1874
+ if (!trimmed.startsWith("|"))
1875
+ break;
1876
+ const row = rowFromCells(splitTableRow(trimmed));
1877
+ if (row)
1878
+ out.push(row);
1879
+ }
1880
+ return out;
1881
+ }
1882
+ function parseInlineFieldList(section) {
1883
+ const m = section.match(INLINE_FIELD_LIST);
1884
+ if (!m)
1885
+ return null;
1886
+ return rowFromCells([m[1], m[2], m[3], m[4], m[5], m[6], m[7]]);
1887
+ }
1795
1888
  // ../../packages/aeg-core/src/report-tokens.ts
1796
1889
  var DASH_LOOKALIKES = {
1797
1890
  "-": "‑",
@@ -1800,6 +1893,7 @@ var DASH_LOOKALIKES = {
1800
1893
  };
1801
1894
  var DASH_CHARS = new Set(Object.keys(DASH_LOOKALIKES));
1802
1895
  // ../../packages/aeg-core/src/claude-code-transcript.ts
1896
+ import { createHash } from "node:crypto";
1803
1897
  function summarizeTranscript(jsonl) {
1804
1898
  const seen = new Set;
1805
1899
  const components = {
@@ -1848,7 +1942,14 @@ function numberOr(value, fallback) {
1848
1942
  function sanitizeKey(value) {
1849
1943
  return value.replace(/[^A-Za-z0-9]+/g, "-");
1850
1944
  }
1945
+ function collisionResistantKey(value) {
1946
+ const digest = createHash("sha256").update(value).digest("hex");
1947
+ return `${sanitizeKey(value)}-${digest}`;
1948
+ }
1851
1949
  function transcriptPointerPath(projectDir, tmpDir) {
1950
+ return `${tmpDir}/claude-transcript-${collisionResistantKey(projectDir)}.txt`;
1951
+ }
1952
+ function legacyTranscriptPointerPath(projectDir, tmpDir) {
1852
1953
  return `${tmpDir}/claude-transcript-${sanitizeKey(projectDir)}.txt`;
1853
1954
  }
1854
1955
  function resolvePointer(explicitTranscriptPath, deps) {
@@ -1856,13 +1957,15 @@ function resolvePointer(explicitTranscriptPath, deps) {
1856
1957
  return { path: explicitTranscriptPath, corroborated: true };
1857
1958
  const projectDir = deps.env.CLAUDE_PROJECT_DIR ?? deps.cwd;
1858
1959
  const tmpDir = deps.env.TMPDIR ?? "/tmp";
1859
- const pointerPath = transcriptPointerPath(projectDir, tmpDir);
1960
+ const primaryPointerPath = transcriptPointerPath(projectDir, tmpDir);
1961
+ const legacyPointerPath = legacyTranscriptPointerPath(projectDir, tmpDir);
1860
1962
  const currentSessionId = deps.env.CLAUDE_CODE_SESSION_ID;
1861
- if (!deps.exists(pointerPath)) {
1963
+ const pointerPath = deps.exists(primaryPointerPath) ? primaryPointerPath : deps.exists(legacyPointerPath) ? legacyPointerPath : undefined;
1964
+ if (!pointerPath) {
1862
1965
  return {
1863
1966
  pointerExisted: false,
1864
1967
  corroborated: false,
1865
- error: `No transcript pointer at ${pointerPath} and no --transcript given. ` + "Either this repo installs no track-transcript.sh Stop hook (lacking one is not a defect — " + "name the transcript directly instead), or no session has completed a turn yet."
1968
+ error: `No transcript pointer at ${primaryPointerPath} (nor its pre-migration name ${legacyPointerPath}) ` + "and no --transcript given. Either this repo installs no track-transcript.sh Stop hook (lacking one " + "is not a defect — name the transcript directly instead), or no session has completed a turn yet."
1866
1969
  };
1867
1970
  }
1868
1971
  let contents;
@@ -1937,6 +2040,9 @@ function isTokenCollectionWiringBroken(capability) {
1937
2040
  return false;
1938
2041
  return capability.reason !== "no-transcript-resolved";
1939
2042
  }
2043
+ // ../../packages/aeg-core/src/metering-io-guard.ts
2044
+ import { closeSync, constants as fsConstants, fstatSync, openSync, readFileSync } from "node:fs";
2045
+ var GUARD_OPEN_FLAGS = fsConstants.O_RDONLY | fsConstants.O_NONBLOCK | fsConstants.O_NOFOLLOW;
1940
2046
  // ../../packages/aeg-core/src/file-classify.ts
1941
2047
  function isCodeFile(p) {
1942
2048
  if (p.endsWith(".md"))
@@ -2143,7 +2249,7 @@ function overrideActive(opts) {
2143
2249
  return false;
2144
2250
  }
2145
2251
  // ../../packages/aeg-core/src/premise-check.ts
2146
- import { createHash } from "node:crypto";
2252
+ import { createHash as createHash2 } from "node:crypto";
2147
2253
  var ASSERTION_KINDS = new Set(["contains", "absent", "sha256"]);
2148
2254
  function isPremiseHeader(line) {
2149
2255
  const stripped = line.replace(/[*#]/g, "").trim();
@@ -2188,7 +2294,7 @@ function checkPremises(assertions, fileReader) {
2188
2294
  } else if (a.kind === "absent" && content.includes(a.value)) {
2189
2295
  failures.push(`premise-check: ${a.path} now contains "${a.value}", but the brief pinned it absent — the premise has moved; re-dig before proceeding.`);
2190
2296
  } else if (a.kind === "sha256") {
2191
- const actual = createHash("sha256").update(content).digest("hex");
2297
+ const actual = createHash2("sha256").update(content).digest("hex");
2192
2298
  if (actual !== a.value.toLowerCase()) {
2193
2299
  failures.push(`premise-check: ${a.path} sha256 mismatch (brief pinned ${a.value}, file is now ${actual}) — the file changed since this brief was authored; re-dig before proceeding.`);
2194
2300
  }
@@ -3988,7 +4094,7 @@ function emitCheckError(error) {
3988
4094
 
3989
4095
  // src/lib/config.ts
3990
4096
  import { execFileSync as execFileSync3 } from "node:child_process";
3991
- import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
4097
+ import { existsSync, mkdirSync, readFileSync as readFileSync2, realpathSync, writeFileSync } from "node:fs";
3992
4098
  import { homedir } from "node:os";
3993
4099
  import { dirname, join as join2, resolve } from "node:path";
3994
4100
  import { z } from "zod";
@@ -4281,7 +4387,7 @@ function loadConfig() {
4281
4387
  if (!path)
4282
4388
  return null;
4283
4389
  try {
4284
- const raw = JSON.parse(readFileSync(path, "utf-8"));
4390
+ const raw = JSON.parse(readFileSync2(path, "utf-8"));
4285
4391
  return stripGlobalOnlyKeys(VinayaConfigSchema.parse(raw), path);
4286
4392
  } catch {
4287
4393
  return null;
@@ -4307,7 +4413,7 @@ function resolvePrBody() {
4307
4413
  return process.env.PR_BODY;
4308
4414
  if (process.env.PR_BODY_FILE) {
4309
4415
  try {
4310
- return readFileSync2(process.env.PR_BODY_FILE, "utf8");
4416
+ return readFileSync3(process.env.PR_BODY_FILE, "utf8");
4311
4417
  } catch {
4312
4418
  return "";
4313
4419
  }
@@ -4365,7 +4471,7 @@ function main() {
4365
4471
  if (changed.length === 0) {
4366
4472
  process.exit(0);
4367
4473
  }
4368
- const content = existsSync2(DOC_OWNERS_PATH) ? readFileSync2(DOC_OWNERS_PATH, "utf8") : null;
4474
+ const content = existsSync2(DOC_OWNERS_PATH) ? readFileSync3(DOC_OWNERS_PATH, "utf8") : null;
4369
4475
  const result = evaluateC5(changed, content, resolvePrBody(), existsSync2, waiverActive(), (p) => fileDiffAgainst(ref, p));
4370
4476
  if (result.errors.length > 0) {
4371
4477
  for (const message of result.errors) {
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/checks/bin/check-doctrine-portability.ts
4
4
  import { execFileSync as execFileSync3 } from "node:child_process";
5
- import { readdirSync, readFileSync as readFileSync2, statSync } from "node:fs";
5
+ import { readdirSync, readFileSync as readFileSync3, statSync } from "node:fs";
6
6
  import { join as join2 } from "node:path";
7
7
  // ../../packages/aeg-core/src/gate-audience.ts
8
8
  var GATE_AUDIENCE = {
@@ -1793,6 +1793,99 @@ var DERIVED_STATUSES = [
1793
1793
  "incoherent"
1794
1794
  ];
1795
1795
  var DERIVABLE_STATUSES = DERIVED_STATUSES.filter((s) => s !== "backlog");
1796
+ // ../../packages/aeg-core/src/parse-ledger.ts
1797
+ function rowFromCells(cells) {
1798
+ if (cells.length < 7)
1799
+ return null;
1800
+ const phase = (cells[0] ?? "").trim();
1801
+ if (!phase)
1802
+ return null;
1803
+ return {
1804
+ phase,
1805
+ role: (cells[1] ?? "").trim(),
1806
+ agentModel: (cells[2] ?? "").trim(),
1807
+ tokensIn: parseIntCell(cells[3] ?? ""),
1808
+ tokensOut: parseIntCell(cells[4] ?? ""),
1809
+ cost: parseCostCell(cells[5] ?? ""),
1810
+ date: (cells[6] ?? "").trim()
1811
+ };
1812
+ }
1813
+ function parseIntCell(cell) {
1814
+ const trimmed = cell.replace(/`/g, "").trim();
1815
+ if (!trimmed || isEmDashOrDash(trimmed))
1816
+ return null;
1817
+ const normalized = trimmed.replace(/[,_\s]/g, "");
1818
+ if (!/^-?\d+$/.test(normalized))
1819
+ return null;
1820
+ return Number(normalized);
1821
+ }
1822
+ function parseCostCell(cell) {
1823
+ const trimmed = cell.replace(/`/g, "").trim();
1824
+ if (!trimmed || isEmDashOrDash(trimmed))
1825
+ return null;
1826
+ const normalized = trimmed.replace(/^\$/, "").replace(/[,_\s]/g, "");
1827
+ if (!/^-?\d+(\.\d+)?$/.test(normalized))
1828
+ return null;
1829
+ return Number(normalized);
1830
+ }
1831
+ function isEmDashOrDash(s) {
1832
+ const t = s.trim();
1833
+ return t === "—" || t === "-" || t === "–";
1834
+ }
1835
+ // ../../packages/aeg-core/src/parse-token-report.ts
1836
+ var TOKEN_REPORT_HEADING = /^\s*(?:#{1,6}\s*Token report\s*|\*\*Token report\*\*)\s*$/i;
1837
+ var INLINE_FIELD_LIST = /Phase:\s*([^|]+?)\s*\|\s*Role:\s*([^|]+?)\s*\|\s*Agent\/Model:\s*([^|]+?)\s*\|\s*Tokens in:\s*([^|]+?)\s*\|\s*Tokens out:\s*([^|]+?)\s*\|\s*Cost:\s*([^|]+?)\s*\|\s*Date:\s*(.+?)\s*$/im;
1838
+ function parseTokenReportEntries(body) {
1839
+ const lines = body.split(/\r?\n/);
1840
+ const headingIdxs = [];
1841
+ lines.forEach((line, i) => {
1842
+ if (TOKEN_REPORT_HEADING.test(line))
1843
+ headingIdxs.push(i);
1844
+ });
1845
+ const out = [];
1846
+ for (let h = 0;h < headingIdxs.length; h++) {
1847
+ const start = headingIdxs[h] + 1;
1848
+ const end = h + 1 < headingIdxs.length ? headingIdxs[h + 1] : lines.length;
1849
+ const section = lines.slice(start, end).join(`
1850
+ `);
1851
+ const tableRows = parseTableSection(section);
1852
+ if (tableRows.length > 0) {
1853
+ out.push(...tableRows);
1854
+ continue;
1855
+ }
1856
+ const inlineRow = parseInlineFieldList(section);
1857
+ if (inlineRow)
1858
+ out.push(inlineRow);
1859
+ }
1860
+ return out;
1861
+ }
1862
+ function parseTableSection(section) {
1863
+ const lines = section.split(/\r?\n/);
1864
+ let i = 0;
1865
+ for (;i < lines.length; i++) {
1866
+ if ((lines[i] ?? "").trim().startsWith("|"))
1867
+ break;
1868
+ }
1869
+ if (i + 1 >= lines.length)
1870
+ return [];
1871
+ i += 2;
1872
+ const out = [];
1873
+ for (;i < lines.length; i++) {
1874
+ const trimmed = (lines[i] ?? "").trim();
1875
+ if (!trimmed.startsWith("|"))
1876
+ break;
1877
+ const row = rowFromCells(splitTableRow(trimmed));
1878
+ if (row)
1879
+ out.push(row);
1880
+ }
1881
+ return out;
1882
+ }
1883
+ function parseInlineFieldList(section) {
1884
+ const m = section.match(INLINE_FIELD_LIST);
1885
+ if (!m)
1886
+ return null;
1887
+ return rowFromCells([m[1], m[2], m[3], m[4], m[5], m[6], m[7]]);
1888
+ }
1796
1889
  // ../../packages/aeg-core/src/report-tokens.ts
1797
1890
  var DASH_LOOKALIKES = {
1798
1891
  "-": "‑",
@@ -1801,6 +1894,7 @@ var DASH_LOOKALIKES = {
1801
1894
  };
1802
1895
  var DASH_CHARS = new Set(Object.keys(DASH_LOOKALIKES));
1803
1896
  // ../../packages/aeg-core/src/claude-code-transcript.ts
1897
+ import { createHash } from "node:crypto";
1804
1898
  function summarizeTranscript(jsonl) {
1805
1899
  const seen = new Set;
1806
1900
  const components = {
@@ -1849,7 +1943,14 @@ function numberOr(value, fallback) {
1849
1943
  function sanitizeKey(value) {
1850
1944
  return value.replace(/[^A-Za-z0-9]+/g, "-");
1851
1945
  }
1946
+ function collisionResistantKey(value) {
1947
+ const digest = createHash("sha256").update(value).digest("hex");
1948
+ return `${sanitizeKey(value)}-${digest}`;
1949
+ }
1852
1950
  function transcriptPointerPath(projectDir, tmpDir) {
1951
+ return `${tmpDir}/claude-transcript-${collisionResistantKey(projectDir)}.txt`;
1952
+ }
1953
+ function legacyTranscriptPointerPath(projectDir, tmpDir) {
1853
1954
  return `${tmpDir}/claude-transcript-${sanitizeKey(projectDir)}.txt`;
1854
1955
  }
1855
1956
  function resolvePointer(explicitTranscriptPath, deps) {
@@ -1857,13 +1958,15 @@ function resolvePointer(explicitTranscriptPath, deps) {
1857
1958
  return { path: explicitTranscriptPath, corroborated: true };
1858
1959
  const projectDir = deps.env.CLAUDE_PROJECT_DIR ?? deps.cwd;
1859
1960
  const tmpDir = deps.env.TMPDIR ?? "/tmp";
1860
- const pointerPath = transcriptPointerPath(projectDir, tmpDir);
1961
+ const primaryPointerPath = transcriptPointerPath(projectDir, tmpDir);
1962
+ const legacyPointerPath = legacyTranscriptPointerPath(projectDir, tmpDir);
1861
1963
  const currentSessionId = deps.env.CLAUDE_CODE_SESSION_ID;
1862
- if (!deps.exists(pointerPath)) {
1964
+ const pointerPath = deps.exists(primaryPointerPath) ? primaryPointerPath : deps.exists(legacyPointerPath) ? legacyPointerPath : undefined;
1965
+ if (!pointerPath) {
1863
1966
  return {
1864
1967
  pointerExisted: false,
1865
1968
  corroborated: false,
1866
- error: `No transcript pointer at ${pointerPath} and no --transcript given. ` + "Either this repo installs no track-transcript.sh Stop hook (lacking one is not a defect — " + "name the transcript directly instead), or no session has completed a turn yet."
1969
+ error: `No transcript pointer at ${primaryPointerPath} (nor its pre-migration name ${legacyPointerPath}) ` + "and no --transcript given. Either this repo installs no track-transcript.sh Stop hook (lacking one " + "is not a defect — name the transcript directly instead), or no session has completed a turn yet."
1867
1970
  };
1868
1971
  }
1869
1972
  let contents;
@@ -1938,6 +2041,9 @@ function isTokenCollectionWiringBroken(capability) {
1938
2041
  return false;
1939
2042
  return capability.reason !== "no-transcript-resolved";
1940
2043
  }
2044
+ // ../../packages/aeg-core/src/metering-io-guard.ts
2045
+ import { closeSync, constants as fsConstants, fstatSync, openSync, readFileSync } from "node:fs";
2046
+ var GUARD_OPEN_FLAGS = fsConstants.O_RDONLY | fsConstants.O_NONBLOCK | fsConstants.O_NOFOLLOW;
1941
2047
  // ../../packages/aeg-core/src/file-classify.ts
1942
2048
  function isCodeFile(p) {
1943
2049
  if (p.endsWith(".md"))
@@ -2144,7 +2250,7 @@ function overrideActive(opts) {
2144
2250
  return false;
2145
2251
  }
2146
2252
  // ../../packages/aeg-core/src/premise-check.ts
2147
- import { createHash } from "node:crypto";
2253
+ import { createHash as createHash2 } from "node:crypto";
2148
2254
  var ASSERTION_KINDS = new Set(["contains", "absent", "sha256"]);
2149
2255
  function isPremiseHeader(line) {
2150
2256
  const stripped = line.replace(/[*#]/g, "").trim();
@@ -2189,7 +2295,7 @@ function checkPremises(assertions, fileReader) {
2189
2295
  } else if (a.kind === "absent" && content.includes(a.value)) {
2190
2296
  failures.push(`premise-check: ${a.path} now contains "${a.value}", but the brief pinned it absent — the premise has moved; re-dig before proceeding.`);
2191
2297
  } else if (a.kind === "sha256") {
2192
- const actual = createHash("sha256").update(content).digest("hex");
2298
+ const actual = createHash2("sha256").update(content).digest("hex");
2193
2299
  if (actual !== a.value.toLowerCase()) {
2194
2300
  failures.push(`premise-check: ${a.path} sha256 mismatch (brief pinned ${a.value}, file is now ${actual}) — the file changed since this brief was authored; re-dig before proceeding.`);
2195
2301
  }
@@ -3917,7 +4023,7 @@ function findWorkspaceEscapes(files, knownPaths, workspaceDirs = DEFAULT_WORKSPA
3917
4023
  }
3918
4024
  // src/lib/config.ts
3919
4025
  import { execFileSync as execFileSync2 } from "node:child_process";
3920
- import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
4026
+ import { existsSync, mkdirSync, readFileSync as readFileSync2, realpathSync, writeFileSync } from "node:fs";
3921
4027
  import { homedir } from "node:os";
3922
4028
  import { dirname, join, resolve } from "node:path";
3923
4029
  import { z } from "zod";
@@ -4210,7 +4316,7 @@ function loadConfig() {
4210
4316
  if (!path)
4211
4317
  return null;
4212
4318
  try {
4213
- const raw = JSON.parse(readFileSync(path, "utf-8"));
4319
+ const raw = JSON.parse(readFileSync2(path, "utf-8"));
4214
4320
  return stripGlobalOnlyKeys(VinayaConfigSchema.parse(raw), path);
4215
4321
  } catch {
4216
4322
  return null;
@@ -4262,7 +4368,7 @@ function collectWorkingTree(dir, out = []) {
4262
4368
  return out;
4263
4369
  }
4264
4370
  function readWorkingTree(paths) {
4265
- return paths.map((p) => ({ path: p, content: readFileSync2(p, "utf8") }));
4371
+ return paths.map((p) => ({ path: p, content: readFileSync3(p, "utf8") }));
4266
4372
  }
4267
4373
  function collectAtRef(ref, dir) {
4268
4374
  const listing = git(["ls-tree", "-r", "--name-only", ref, "--", dir]);