@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
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/checks/bin/check-retired-vocabulary.ts
4
- import { readdirSync as readdirSync2, readFileSync as readFileSync3, statSync } from "node:fs";
4
+ import { readdirSync as readdirSync2, readFileSync as readFileSync4, statSync } from "node:fs";
5
5
  import { join as join5, resolve as resolve2 } from "node:path";
6
6
  // ../../packages/aeg-core/src/gate-audience.ts
7
7
  var GATE_AUDIENCE = {
@@ -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
  }
@@ -3915,7 +4021,7 @@ function findWorkspaceEscapes(files, knownPaths, workspaceDirs = DEFAULT_WORKSPA
3915
4021
  return findings;
3916
4022
  }
3917
4023
  // src/commands/doctrine.ts
3918
- import { existsSync as existsSync2, readdirSync, readFileSync } from "node:fs";
4024
+ import { existsSync as existsSync2, readdirSync, readFileSync as readFileSync2 } from "node:fs";
3919
4025
  import { dirname as dirname2, join as join2, sep } from "node:path";
3920
4026
  import matter2 from "gray-matter";
3921
4027
 
@@ -3943,15 +4049,18 @@ function resolveDoctrineRoot(pkg = packageRoot(import.meta.url)) {
3943
4049
  if (!pkg.split(sep).includes("node_modules"))
3944
4050
  candidates.push(join2(dirname2(dirname2(pkg)), "aeg-root"));
3945
4051
  for (const root of candidates) {
3946
- if (existsSync2(join2(root, ...ENTRY_SEGMENTS)))
4052
+ if (hasDoctrineEntry(root))
3947
4053
  return root;
3948
4054
  }
3949
4055
  return null;
3950
4056
  }
4057
+ function hasDoctrineEntry(root) {
4058
+ return existsSync2(join2(root, ...ENTRY_SEGMENTS));
4059
+ }
3951
4060
 
3952
4061
  // src/lib/config.ts
3953
4062
  import { execFileSync as execFileSync2 } from "node:child_process";
3954
- import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync2, realpathSync, writeFileSync } from "node:fs";
4063
+ import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync3, realpathSync, writeFileSync } from "node:fs";
3955
4064
  import { homedir } from "node:os";
3956
4065
  import { dirname as dirname3, join as join3, resolve } from "node:path";
3957
4066
  import { z } from "zod";
@@ -4244,7 +4353,7 @@ function loadConfig() {
4244
4353
  if (!path)
4245
4354
  return null;
4246
4355
  try {
4247
- const raw = JSON.parse(readFileSync2(path, "utf-8"));
4356
+ const raw = JSON.parse(readFileSync3(path, "utf-8"));
4248
4357
  return stripGlobalOnlyKeys(VinayaConfigSchema.parse(raw), path);
4249
4358
  } catch {
4250
4359
  return null;
@@ -4326,7 +4435,19 @@ function resolveChangedFiles(base = process.env.BASE_SHA || "origin/main") {
4326
4435
 
4327
4436
  // src/checks/bin/check-retired-vocabulary.ts
4328
4437
  var CHECK_NAME = "retired-vocabulary";
4329
- var DOCTRINE_ROOT = loadConfig()?.proseGates?.doctrineRoot ?? resolveDoctrineRoot() ?? "aeg-root";
4438
+ function resolveCheckDoctrineRoot() {
4439
+ const configured = loadConfig()?.proseGates?.doctrineRoot;
4440
+ if (configured !== undefined)
4441
+ return configured;
4442
+ const root = repoRoot();
4443
+ if (root !== null) {
4444
+ const candidate = join5(root, "aeg-root");
4445
+ if (hasDoctrineEntry(candidate))
4446
+ return candidate;
4447
+ }
4448
+ return resolveDoctrineRoot();
4449
+ }
4450
+ var DOCTRINE_ROOT = resolveCheckDoctrineRoot();
4330
4451
  function isSweptFile(name) {
4331
4452
  return /\.(md|ts|tsx|yml)$/.test(name) || name === "doc-owners" || name === "packages";
4332
4453
  }
@@ -4356,9 +4477,20 @@ function collect(dir, out = []) {
4356
4477
  return out;
4357
4478
  }
4358
4479
  function readAll(paths) {
4359
- return paths.map((p) => ({ path: p, content: readFileSync3(p, "utf8") }));
4480
+ return paths.map((p) => ({ path: p, content: readFileSync4(p, "utf8") }));
4360
4481
  }
4361
4482
  function main() {
4483
+ if (DOCTRINE_ROOT === null) {
4484
+ console.log(`${CHECK_NAME}: doctrine root unresolvable — sweep did not run.`);
4485
+ emitCheckError({
4486
+ schema: CHECK_SCHEMA_VERSION,
4487
+ check: CHECK_NAME,
4488
+ severity: "error",
4489
+ message: "doctrine root unresolvable: no aeg-root found at the repo root under check, and no bundled copy found " + "relative to this package's own install.",
4490
+ agent_recovery_prompt: "Set proseGates.doctrineRoot in vinaya.config.json to the doctrine tree this repo actually uses, or " + "confirm aeg-root/ exists at the repo root (or that this package's own bundled aeg-root/ is present)."
4491
+ });
4492
+ process.exit(2);
4493
+ }
4362
4494
  const paths = collect(DOCTRINE_ROOT);
4363
4495
  const files = readAll(paths);
4364
4496
  const findings = scanRetiredVocabulary(files);
@@ -1791,6 +1791,99 @@ var DERIVED_STATUSES = [
1791
1791
  "incoherent"
1792
1792
  ];
1793
1793
  var DERIVABLE_STATUSES = DERIVED_STATUSES.filter((s) => s !== "backlog");
1794
+ // ../../packages/aeg-core/src/parse-ledger.ts
1795
+ function rowFromCells(cells) {
1796
+ if (cells.length < 7)
1797
+ return null;
1798
+ const phase = (cells[0] ?? "").trim();
1799
+ if (!phase)
1800
+ return null;
1801
+ return {
1802
+ phase,
1803
+ role: (cells[1] ?? "").trim(),
1804
+ agentModel: (cells[2] ?? "").trim(),
1805
+ tokensIn: parseIntCell(cells[3] ?? ""),
1806
+ tokensOut: parseIntCell(cells[4] ?? ""),
1807
+ cost: parseCostCell(cells[5] ?? ""),
1808
+ date: (cells[6] ?? "").trim()
1809
+ };
1810
+ }
1811
+ function parseIntCell(cell) {
1812
+ const trimmed = cell.replace(/`/g, "").trim();
1813
+ if (!trimmed || isEmDashOrDash(trimmed))
1814
+ return null;
1815
+ const normalized = trimmed.replace(/[,_\s]/g, "");
1816
+ if (!/^-?\d+$/.test(normalized))
1817
+ return null;
1818
+ return Number(normalized);
1819
+ }
1820
+ function parseCostCell(cell) {
1821
+ const trimmed = cell.replace(/`/g, "").trim();
1822
+ if (!trimmed || isEmDashOrDash(trimmed))
1823
+ return null;
1824
+ const normalized = trimmed.replace(/^\$/, "").replace(/[,_\s]/g, "");
1825
+ if (!/^-?\d+(\.\d+)?$/.test(normalized))
1826
+ return null;
1827
+ return Number(normalized);
1828
+ }
1829
+ function isEmDashOrDash(s) {
1830
+ const t = s.trim();
1831
+ return t === "—" || t === "-" || t === "–";
1832
+ }
1833
+ // ../../packages/aeg-core/src/parse-token-report.ts
1834
+ var TOKEN_REPORT_HEADING = /^\s*(?:#{1,6}\s*Token report\s*|\*\*Token report\*\*)\s*$/i;
1835
+ 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;
1836
+ function parseTokenReportEntries(body) {
1837
+ const lines = body.split(/\r?\n/);
1838
+ const headingIdxs = [];
1839
+ lines.forEach((line, i) => {
1840
+ if (TOKEN_REPORT_HEADING.test(line))
1841
+ headingIdxs.push(i);
1842
+ });
1843
+ const out = [];
1844
+ for (let h = 0;h < headingIdxs.length; h++) {
1845
+ const start = headingIdxs[h] + 1;
1846
+ const end = h + 1 < headingIdxs.length ? headingIdxs[h + 1] : lines.length;
1847
+ const section = lines.slice(start, end).join(`
1848
+ `);
1849
+ const tableRows = parseTableSection(section);
1850
+ if (tableRows.length > 0) {
1851
+ out.push(...tableRows);
1852
+ continue;
1853
+ }
1854
+ const inlineRow = parseInlineFieldList(section);
1855
+ if (inlineRow)
1856
+ out.push(inlineRow);
1857
+ }
1858
+ return out;
1859
+ }
1860
+ function parseTableSection(section) {
1861
+ const lines = section.split(/\r?\n/);
1862
+ let i = 0;
1863
+ for (;i < lines.length; i++) {
1864
+ if ((lines[i] ?? "").trim().startsWith("|"))
1865
+ break;
1866
+ }
1867
+ if (i + 1 >= lines.length)
1868
+ return [];
1869
+ i += 2;
1870
+ const out = [];
1871
+ for (;i < lines.length; i++) {
1872
+ const trimmed = (lines[i] ?? "").trim();
1873
+ if (!trimmed.startsWith("|"))
1874
+ break;
1875
+ const row = rowFromCells(splitTableRow(trimmed));
1876
+ if (row)
1877
+ out.push(row);
1878
+ }
1879
+ return out;
1880
+ }
1881
+ function parseInlineFieldList(section) {
1882
+ const m = section.match(INLINE_FIELD_LIST);
1883
+ if (!m)
1884
+ return null;
1885
+ return rowFromCells([m[1], m[2], m[3], m[4], m[5], m[6], m[7]]);
1886
+ }
1794
1887
  // ../../packages/aeg-core/src/report-tokens.ts
1795
1888
  var DASH_LOOKALIKES = {
1796
1889
  "-": "‑",
@@ -1799,6 +1892,7 @@ var DASH_LOOKALIKES = {
1799
1892
  };
1800
1893
  var DASH_CHARS = new Set(Object.keys(DASH_LOOKALIKES));
1801
1894
  // ../../packages/aeg-core/src/claude-code-transcript.ts
1895
+ import { createHash } from "node:crypto";
1802
1896
  function summarizeTranscript(jsonl) {
1803
1897
  const seen = new Set;
1804
1898
  const components = {
@@ -1847,7 +1941,14 @@ function numberOr(value, fallback) {
1847
1941
  function sanitizeKey(value) {
1848
1942
  return value.replace(/[^A-Za-z0-9]+/g, "-");
1849
1943
  }
1944
+ function collisionResistantKey(value) {
1945
+ const digest = createHash("sha256").update(value).digest("hex");
1946
+ return `${sanitizeKey(value)}-${digest}`;
1947
+ }
1850
1948
  function transcriptPointerPath(projectDir, tmpDir) {
1949
+ return `${tmpDir}/claude-transcript-${collisionResistantKey(projectDir)}.txt`;
1950
+ }
1951
+ function legacyTranscriptPointerPath(projectDir, tmpDir) {
1851
1952
  return `${tmpDir}/claude-transcript-${sanitizeKey(projectDir)}.txt`;
1852
1953
  }
1853
1954
  function resolvePointer(explicitTranscriptPath, deps) {
@@ -1855,13 +1956,15 @@ function resolvePointer(explicitTranscriptPath, deps) {
1855
1956
  return { path: explicitTranscriptPath, corroborated: true };
1856
1957
  const projectDir = deps.env.CLAUDE_PROJECT_DIR ?? deps.cwd;
1857
1958
  const tmpDir = deps.env.TMPDIR ?? "/tmp";
1858
- const pointerPath = transcriptPointerPath(projectDir, tmpDir);
1959
+ const primaryPointerPath = transcriptPointerPath(projectDir, tmpDir);
1960
+ const legacyPointerPath = legacyTranscriptPointerPath(projectDir, tmpDir);
1859
1961
  const currentSessionId = deps.env.CLAUDE_CODE_SESSION_ID;
1860
- if (!deps.exists(pointerPath)) {
1962
+ const pointerPath = deps.exists(primaryPointerPath) ? primaryPointerPath : deps.exists(legacyPointerPath) ? legacyPointerPath : undefined;
1963
+ if (!pointerPath) {
1861
1964
  return {
1862
1965
  pointerExisted: false,
1863
1966
  corroborated: false,
1864
- 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."
1967
+ 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."
1865
1968
  };
1866
1969
  }
1867
1970
  let contents;
@@ -1936,6 +2039,9 @@ function isTokenCollectionWiringBroken(capability) {
1936
2039
  return false;
1937
2040
  return capability.reason !== "no-transcript-resolved";
1938
2041
  }
2042
+ // ../../packages/aeg-core/src/metering-io-guard.ts
2043
+ import { closeSync, constants as fsConstants, fstatSync, openSync, readFileSync } from "node:fs";
2044
+ var GUARD_OPEN_FLAGS = fsConstants.O_RDONLY | fsConstants.O_NONBLOCK | fsConstants.O_NOFOLLOW;
1939
2045
  // ../../packages/aeg-core/src/file-classify.ts
1940
2046
  function isCodeFile(p) {
1941
2047
  if (p.endsWith(".md"))
@@ -2142,7 +2248,7 @@ function overrideActive(opts) {
2142
2248
  return false;
2143
2249
  }
2144
2250
  // ../../packages/aeg-core/src/premise-check.ts
2145
- import { createHash } from "node:crypto";
2251
+ import { createHash as createHash2 } from "node:crypto";
2146
2252
  var ASSERTION_KINDS = new Set(["contains", "absent", "sha256"]);
2147
2253
  function isPremiseHeader(line) {
2148
2254
  const stripped = line.replace(/[*#]/g, "").trim();
@@ -2187,7 +2293,7 @@ function checkPremises(assertions, fileReader) {
2187
2293
  } else if (a.kind === "absent" && content.includes(a.value)) {
2188
2294
  failures.push(`premise-check: ${a.path} now contains "${a.value}", but the brief pinned it absent — the premise has moved; re-dig before proceeding.`);
2189
2295
  } else if (a.kind === "sha256") {
2190
- const actual = createHash("sha256").update(content).digest("hex");
2296
+ const actual = createHash2("sha256").update(content).digest("hex");
2191
2297
  if (actual !== a.value.toLowerCase()) {
2192
2298
  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.`);
2193
2299
  }
@@ -3922,7 +4028,7 @@ function emitCheckError(error) {
3922
4028
 
3923
4029
  // src/lib/config.ts
3924
4030
  import { execFileSync as execFileSync2 } from "node:child_process";
3925
- import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
4031
+ import { existsSync, mkdirSync, readFileSync as readFileSync2, realpathSync, writeFileSync } from "node:fs";
3926
4032
  import { homedir } from "node:os";
3927
4033
  import { dirname, join, resolve } from "node:path";
3928
4034
  import { z } from "zod";
@@ -4215,7 +4321,7 @@ function loadConfig() {
4215
4321
  if (!path)
4216
4322
  return null;
4217
4323
  try {
4218
- const raw = JSON.parse(readFileSync(path, "utf-8"));
4324
+ const raw = JSON.parse(readFileSync2(path, "utf-8"));
4219
4325
  return stripGlobalOnlyKeys(VinayaConfigSchema.parse(raw), path);
4220
4326
  } catch {
4221
4327
  return null;
@@ -1791,6 +1791,99 @@ var DERIVED_STATUSES = [
1791
1791
  "incoherent"
1792
1792
  ];
1793
1793
  var DERIVABLE_STATUSES = DERIVED_STATUSES.filter((s) => s !== "backlog");
1794
+ // ../../packages/aeg-core/src/parse-ledger.ts
1795
+ function rowFromCells(cells) {
1796
+ if (cells.length < 7)
1797
+ return null;
1798
+ const phase = (cells[0] ?? "").trim();
1799
+ if (!phase)
1800
+ return null;
1801
+ return {
1802
+ phase,
1803
+ role: (cells[1] ?? "").trim(),
1804
+ agentModel: (cells[2] ?? "").trim(),
1805
+ tokensIn: parseIntCell(cells[3] ?? ""),
1806
+ tokensOut: parseIntCell(cells[4] ?? ""),
1807
+ cost: parseCostCell(cells[5] ?? ""),
1808
+ date: (cells[6] ?? "").trim()
1809
+ };
1810
+ }
1811
+ function parseIntCell(cell) {
1812
+ const trimmed = cell.replace(/`/g, "").trim();
1813
+ if (!trimmed || isEmDashOrDash(trimmed))
1814
+ return null;
1815
+ const normalized = trimmed.replace(/[,_\s]/g, "");
1816
+ if (!/^-?\d+$/.test(normalized))
1817
+ return null;
1818
+ return Number(normalized);
1819
+ }
1820
+ function parseCostCell(cell) {
1821
+ const trimmed = cell.replace(/`/g, "").trim();
1822
+ if (!trimmed || isEmDashOrDash(trimmed))
1823
+ return null;
1824
+ const normalized = trimmed.replace(/^\$/, "").replace(/[,_\s]/g, "");
1825
+ if (!/^-?\d+(\.\d+)?$/.test(normalized))
1826
+ return null;
1827
+ return Number(normalized);
1828
+ }
1829
+ function isEmDashOrDash(s) {
1830
+ const t = s.trim();
1831
+ return t === "—" || t === "-" || t === "–";
1832
+ }
1833
+ // ../../packages/aeg-core/src/parse-token-report.ts
1834
+ var TOKEN_REPORT_HEADING = /^\s*(?:#{1,6}\s*Token report\s*|\*\*Token report\*\*)\s*$/i;
1835
+ 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;
1836
+ function parseTokenReportEntries(body) {
1837
+ const lines = body.split(/\r?\n/);
1838
+ const headingIdxs = [];
1839
+ lines.forEach((line, i) => {
1840
+ if (TOKEN_REPORT_HEADING.test(line))
1841
+ headingIdxs.push(i);
1842
+ });
1843
+ const out = [];
1844
+ for (let h = 0;h < headingIdxs.length; h++) {
1845
+ const start = headingIdxs[h] + 1;
1846
+ const end = h + 1 < headingIdxs.length ? headingIdxs[h + 1] : lines.length;
1847
+ const section = lines.slice(start, end).join(`
1848
+ `);
1849
+ const tableRows = parseTableSection(section);
1850
+ if (tableRows.length > 0) {
1851
+ out.push(...tableRows);
1852
+ continue;
1853
+ }
1854
+ const inlineRow = parseInlineFieldList(section);
1855
+ if (inlineRow)
1856
+ out.push(inlineRow);
1857
+ }
1858
+ return out;
1859
+ }
1860
+ function parseTableSection(section) {
1861
+ const lines = section.split(/\r?\n/);
1862
+ let i = 0;
1863
+ for (;i < lines.length; i++) {
1864
+ if ((lines[i] ?? "").trim().startsWith("|"))
1865
+ break;
1866
+ }
1867
+ if (i + 1 >= lines.length)
1868
+ return [];
1869
+ i += 2;
1870
+ const out = [];
1871
+ for (;i < lines.length; i++) {
1872
+ const trimmed = (lines[i] ?? "").trim();
1873
+ if (!trimmed.startsWith("|"))
1874
+ break;
1875
+ const row = rowFromCells(splitTableRow(trimmed));
1876
+ if (row)
1877
+ out.push(row);
1878
+ }
1879
+ return out;
1880
+ }
1881
+ function parseInlineFieldList(section) {
1882
+ const m = section.match(INLINE_FIELD_LIST);
1883
+ if (!m)
1884
+ return null;
1885
+ return rowFromCells([m[1], m[2], m[3], m[4], m[5], m[6], m[7]]);
1886
+ }
1794
1887
  // ../../packages/aeg-core/src/report-tokens.ts
1795
1888
  var DASH_LOOKALIKES = {
1796
1889
  "-": "‑",
@@ -1799,6 +1892,7 @@ var DASH_LOOKALIKES = {
1799
1892
  };
1800
1893
  var DASH_CHARS = new Set(Object.keys(DASH_LOOKALIKES));
1801
1894
  // ../../packages/aeg-core/src/claude-code-transcript.ts
1895
+ import { createHash } from "node:crypto";
1802
1896
  function summarizeTranscript(jsonl) {
1803
1897
  const seen = new Set;
1804
1898
  const components = {
@@ -1847,7 +1941,14 @@ function numberOr(value, fallback) {
1847
1941
  function sanitizeKey(value) {
1848
1942
  return value.replace(/[^A-Za-z0-9]+/g, "-");
1849
1943
  }
1944
+ function collisionResistantKey(value) {
1945
+ const digest = createHash("sha256").update(value).digest("hex");
1946
+ return `${sanitizeKey(value)}-${digest}`;
1947
+ }
1850
1948
  function transcriptPointerPath(projectDir, tmpDir) {
1949
+ return `${tmpDir}/claude-transcript-${collisionResistantKey(projectDir)}.txt`;
1950
+ }
1951
+ function legacyTranscriptPointerPath(projectDir, tmpDir) {
1851
1952
  return `${tmpDir}/claude-transcript-${sanitizeKey(projectDir)}.txt`;
1852
1953
  }
1853
1954
  function resolvePointer(explicitTranscriptPath, deps) {
@@ -1855,13 +1956,15 @@ function resolvePointer(explicitTranscriptPath, deps) {
1855
1956
  return { path: explicitTranscriptPath, corroborated: true };
1856
1957
  const projectDir = deps.env.CLAUDE_PROJECT_DIR ?? deps.cwd;
1857
1958
  const tmpDir = deps.env.TMPDIR ?? "/tmp";
1858
- const pointerPath = transcriptPointerPath(projectDir, tmpDir);
1959
+ const primaryPointerPath = transcriptPointerPath(projectDir, tmpDir);
1960
+ const legacyPointerPath = legacyTranscriptPointerPath(projectDir, tmpDir);
1859
1961
  const currentSessionId = deps.env.CLAUDE_CODE_SESSION_ID;
1860
- if (!deps.exists(pointerPath)) {
1962
+ const pointerPath = deps.exists(primaryPointerPath) ? primaryPointerPath : deps.exists(legacyPointerPath) ? legacyPointerPath : undefined;
1963
+ if (!pointerPath) {
1861
1964
  return {
1862
1965
  pointerExisted: false,
1863
1966
  corroborated: false,
1864
- 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."
1967
+ 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."
1865
1968
  };
1866
1969
  }
1867
1970
  let contents;
@@ -1936,6 +2039,9 @@ function isTokenCollectionWiringBroken(capability) {
1936
2039
  return false;
1937
2040
  return capability.reason !== "no-transcript-resolved";
1938
2041
  }
2042
+ // ../../packages/aeg-core/src/metering-io-guard.ts
2043
+ import { closeSync, constants as fsConstants, fstatSync, openSync, readFileSync } from "node:fs";
2044
+ var GUARD_OPEN_FLAGS = fsConstants.O_RDONLY | fsConstants.O_NONBLOCK | fsConstants.O_NOFOLLOW;
1939
2045
  // ../../packages/aeg-core/src/file-classify.ts
1940
2046
  function isCodeFile(p) {
1941
2047
  if (p.endsWith(".md"))
@@ -2142,7 +2248,7 @@ function overrideActive(opts) {
2142
2248
  return false;
2143
2249
  }
2144
2250
  // ../../packages/aeg-core/src/premise-check.ts
2145
- import { createHash } from "node:crypto";
2251
+ import { createHash as createHash2 } from "node:crypto";
2146
2252
  var ASSERTION_KINDS = new Set(["contains", "absent", "sha256"]);
2147
2253
  function isPremiseHeader(line) {
2148
2254
  const stripped = line.replace(/[*#]/g, "").trim();
@@ -2187,7 +2293,7 @@ function checkPremises(assertions, fileReader) {
2187
2293
  } else if (a.kind === "absent" && content.includes(a.value)) {
2188
2294
  failures.push(`premise-check: ${a.path} now contains "${a.value}", but the brief pinned it absent — the premise has moved; re-dig before proceeding.`);
2189
2295
  } else if (a.kind === "sha256") {
2190
- const actual = createHash("sha256").update(content).digest("hex");
2296
+ const actual = createHash2("sha256").update(content).digest("hex");
2191
2297
  if (actual !== a.value.toLowerCase()) {
2192
2298
  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.`);
2193
2299
  }