@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.
- package/README.md +3 -2
- package/aeg-root/enforcement.md +2 -1
- package/aeg-root/roles/archivist.md +1 -1
- package/aeg-root/roles/planner.md +1 -1
- package/aeg-root/templates/pr-report-template.md +2 -0
- package/aeg-root/tranche-model.md +3 -3
- package/dist/checks/bin/check-body-bare-digits.js +115 -9
- package/dist/checks/bin/check-branch-topology.js +111 -5
- package/dist/checks/bin/check-brief-shape.js +111 -5
- package/dist/checks/bin/check-changeset-coverage.js +113 -7
- package/dist/checks/bin/check-closes-n.js +111 -5
- package/dist/checks/bin/check-coherence.js +115 -9
- package/dist/checks/bin/check-dead-branch-push.js +111 -5
- package/dist/checks/bin/check-dispatch-readiness.js +116 -10
- package/dist/checks/bin/check-doc-coverage-push.js +116 -10
- package/dist/checks/bin/check-doc-coverage.js +116 -10
- package/dist/checks/bin/check-doctrine-portability.js +115 -9
- package/dist/checks/bin/check-evidence-fresh.js +111 -5
- package/dist/checks/bin/check-first-push-dispatch.js +113 -7
- package/dist/checks/bin/check-issue-assignment.js +111 -5
- package/dist/checks/bin/check-main-branch-refusal.js +111 -5
- package/dist/checks/bin/check-no-disk-state.js +111 -5
- package/dist/checks/bin/check-quoted-command.js +121 -12
- package/dist/checks/bin/check-reader-resolvable-prose.js +152 -20
- package/dist/checks/bin/check-registry-gates.js +131 -10
- package/dist/checks/bin/check-retired-vocabulary.js +144 -12
- package/dist/checks/bin/check-review-gate.js +113 -7
- package/dist/checks/bin/check-single-plan-pr.js +111 -5
- package/dist/checks/bin/check-test-plan.js +111 -5
- package/dist/checks/bin/check-token-collection-wired.js +113 -7
- package/dist/checks/bin/check-token-report.js +4096 -0
- package/dist/checks/bin/check-workspace-escape.js +113 -7
- package/dist/index.js +177 -104
- package/package.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/BUILD_ID +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/build-manifest.json +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/prerender-manifest.json +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.html +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page_client-reference-manifest.js +1 -1
- 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
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0053k9k._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0112h-k._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__02c71kv._.js +1 -1
- 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
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0o771t1._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0puovz5._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1hs0dcu._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1wc4-ip._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_03x_w6q._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0gvm3og._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0lwxg63._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0o54suy._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1-6rzip._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1mrtj0f._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1n0cnq-._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/apps_vinaya-studio_web_src_app_studio_06it6s-._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/node_modules_1vo08dj._.js +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_animate_components_index_ts_186fje1._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_brutal_components_index_ts_0n_lcc4._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_retro_components_index_ts_0wvpm_z._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_retro_components_index_ts_1_cfi48._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/middleware-build-manifest.js +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/server/pages/500.html +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.json +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/00pi8vhg8w6gi.js +1 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0r4i_ks9z02bw.js → 03q0q9n6-xah8.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/0vc2u252q5q6o.js +1 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1k916ih3p4nsg.js → 13g16cu00g570.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/1hufpuody6vjv.js +1 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{2hmannd4bjhzy.js → 1sfxfunirkcr6.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1t2kft7bxzuxn.js → 206ajg8f1a-_h.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1hfhxjy577l5d.js → 267o-tsrnuwnv.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{25kbt5k-xb2a5.js → 279qq4twinc97.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{112g08xpx3kro.js → 2ka8dg687auhj.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0up5x3jg-cwov.js → 2rn89uwtf2lwc.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{2_k6j1o9q5nn4.js → 37hnluhzj9bei.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{3mqu_uhluy19i.css → 3qc67qhcvbg0o.css} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1yqs2zgvwa4p1.js → 3zugx9esh2x51.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/0_jnwbarv-cqk.js +0 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/1ybrihl5_aocy.js +0 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/3r5efmleneaco.js +0 -1
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{crNCHQ9uAgKOYC6DKkZma → Fmyc42qzLwFcWWHLLNy-G}/_buildManifest.js +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{crNCHQ9uAgKOYC6DKkZma → Fmyc42qzLwFcWWHLLNy-G}/_clientMiddlewareManifest.js +0 -0
- /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-reader-resolvable-prose.ts
|
|
4
|
-
import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as
|
|
4
|
+
import { existsSync as existsSync4, 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
|
|
1960
|
+
const primaryPointerPath = transcriptPointerPath(projectDir, tmpDir);
|
|
1961
|
+
const legacyPointerPath = legacyTranscriptPointerPath(projectDir, tmpDir);
|
|
1860
1962
|
const currentSessionId = deps.env.CLAUDE_CODE_SESSION_ID;
|
|
1861
|
-
|
|
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 ${
|
|
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 =
|
|
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 (
|
|
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
|
|
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(
|
|
4356
|
+
const raw = JSON.parse(readFileSync3(path, "utf-8"));
|
|
4248
4357
|
return stripGlobalOnlyKeys(VinayaConfigSchema.parse(raw), path);
|
|
4249
4358
|
} catch {
|
|
4250
4359
|
return null;
|
|
@@ -4327,11 +4436,22 @@ function resolveChangedFiles(base = process.env.BASE_SHA || "origin/main") {
|
|
|
4327
4436
|
// src/checks/bin/check-reader-resolvable-prose.ts
|
|
4328
4437
|
var CHECK_NAME = "reader-resolvable-prose";
|
|
4329
4438
|
var proseGates = loadConfig()?.proseGates;
|
|
4330
|
-
|
|
4439
|
+
function resolveCheckDoctrineRoot() {
|
|
4440
|
+
if (proseGates?.doctrineRoot !== undefined)
|
|
4441
|
+
return proseGates.doctrineRoot;
|
|
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();
|
|
4331
4451
|
var READER_FACING_PREFIX = proseGates?.readerFacingPrefix ?? null;
|
|
4332
4452
|
var READER_FACING_SUFFIX = proseGates?.readerFacingSuffix ?? null;
|
|
4333
4453
|
var READER_FACING_ACTIVE = READER_FACING_PREFIX !== null && READER_FACING_SUFFIX !== null;
|
|
4334
|
-
var LEGACY_SLUG_DIR = proseGates?.legacySlugDir ?? `${DOCTRINE_ROOT}/tranches/completed
|
|
4454
|
+
var LEGACY_SLUG_DIR = proseGates?.legacySlugDir ?? (DOCTRINE_ROOT === null ? null : `${DOCTRINE_ROOT}/tranches/completed`);
|
|
4335
4455
|
function collect(dir, out = []) {
|
|
4336
4456
|
let entries;
|
|
4337
4457
|
try {
|
|
@@ -4358,27 +4478,39 @@ function collect(dir, out = []) {
|
|
|
4358
4478
|
return out;
|
|
4359
4479
|
}
|
|
4360
4480
|
function readAll(paths) {
|
|
4361
|
-
return paths.map((p) => ({ path: p, content:
|
|
4481
|
+
return paths.map((p) => ({ path: p, content: readFileSync4(p, "utf8") }));
|
|
4362
4482
|
}
|
|
4363
|
-
function legacySlugs() {
|
|
4364
|
-
if (!existsSync4(
|
|
4483
|
+
function legacySlugs(legacySlugDir) {
|
|
4484
|
+
if (!existsSync4(legacySlugDir))
|
|
4365
4485
|
return { slugs: [], dormant: true };
|
|
4366
4486
|
try {
|
|
4367
|
-
const slugs = readdirSync2(
|
|
4487
|
+
const slugs = readdirSync2(legacySlugDir).filter((f) => f.endsWith(".md") && !f.endsWith(".tokens.md")).map((f) => f.slice(0, -3)).filter((slug) => !/-v[0-9]+$/.test(slug));
|
|
4368
4488
|
return { slugs, dormant: false };
|
|
4369
4489
|
} catch (err) {
|
|
4370
|
-
console.log(`${CHECK_NAME}: could not read ${
|
|
4490
|
+
console.log(`${CHECK_NAME}: could not read ${legacySlugDir} (${err instanceof Error ? err.message : String(err)}) — legacy-slug class treated as dormant.`);
|
|
4371
4491
|
return { slugs: [], dormant: true };
|
|
4372
4492
|
}
|
|
4373
4493
|
}
|
|
4374
4494
|
function main() {
|
|
4495
|
+
if (DOCTRINE_ROOT === null) {
|
|
4496
|
+
console.log(`${CHECK_NAME}: doctrine root unresolvable — sweep did not run.`);
|
|
4497
|
+
emitCheckError({
|
|
4498
|
+
schema: CHECK_SCHEMA_VERSION,
|
|
4499
|
+
check: CHECK_NAME,
|
|
4500
|
+
severity: "error",
|
|
4501
|
+
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.",
|
|
4502
|
+
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)."
|
|
4503
|
+
});
|
|
4504
|
+
process.exit(2);
|
|
4505
|
+
}
|
|
4375
4506
|
const shipsPrefix = `${DOCTRINE_ROOT}/`;
|
|
4376
4507
|
const shipsPaths = collect(DOCTRINE_ROOT).filter((p) => p.endsWith(".md"));
|
|
4377
4508
|
const readerFacingPaths = READER_FACING_ACTIVE && READER_FACING_SUFFIX !== null ? collect(READER_FACING_PREFIX).filter((p) => p.endsWith(READER_FACING_SUFFIX)) : [];
|
|
4378
4509
|
const files = readAll([...shipsPaths, ...readerFacingPaths]);
|
|
4379
4510
|
const glossaryPath = join5(DOCTRINE_ROOT, "glossary.md");
|
|
4380
|
-
const glossaryTerms = existsSync4(glossaryPath) ? parseGlossaryTerms(
|
|
4381
|
-
const
|
|
4511
|
+
const glossaryTerms = existsSync4(glossaryPath) ? parseGlossaryTerms(readFileSync4(glossaryPath, "utf8")) : [];
|
|
4512
|
+
const legacySlugDir = LEGACY_SLUG_DIR ?? `${DOCTRINE_ROOT}/tranches/completed`;
|
|
4513
|
+
const { slugs, dormant: legacySlugsDormant } = legacySlugs(legacySlugDir);
|
|
4382
4514
|
const readerFacingPrefix = READER_FACING_ACTIVE && READER_FACING_PREFIX !== null ? `${READER_FACING_PREFIX}/` : "/no-reader-facing-surface";
|
|
4383
4515
|
const readerFacingSuffix = READER_FACING_ACTIVE && READER_FACING_SUFFIX !== null ? READER_FACING_SUFFIX : "/page.tsx";
|
|
4384
4516
|
const findings = checkReaderResolvableProse(files, glossaryTerms, readerFacingPrefix, readerFacingSuffix, slugs, shipsPrefix);
|
|
@@ -4386,7 +4518,7 @@ function main() {
|
|
|
4386
4518
|
const changed = changedFilesList === null ? null : new Set(changedFilesList);
|
|
4387
4519
|
const pathBase = repoRoot() ?? process.cwd();
|
|
4388
4520
|
const reportable = changed === null ? findings : findings.filter((f) => changed.has(resolve2(pathBase, f.file)));
|
|
4389
|
-
console.log(`${CHECK_NAME}: doctrine root "${DOCTRINE_ROOT}"; reader-facing class ${READER_FACING_ACTIVE ? "ran" : "dormant — proseGates.readerFacingPrefix/readerFacingSuffix not both set"}; ` + `legacy-slug class ${legacySlugsDormant ? `dormant — ${
|
|
4521
|
+
console.log(`${CHECK_NAME}: doctrine root "${DOCTRINE_ROOT}"; reader-facing class ${READER_FACING_ACTIVE ? "ran" : "dormant — proseGates.readerFacingPrefix/readerFacingSuffix not both set"}; ` + `legacy-slug class ${legacySlugsDormant ? `dormant — ${legacySlugDir} is absent` : `ran (${slugs.length} slug(s))`}; ` + `${findings.length} finding(s) swept, ${reportable.length} in this diff`);
|
|
4390
4522
|
for (const finding of reportable) {
|
|
4391
4523
|
emitCheckError({
|
|
4392
4524
|
schema: CHECK_SCHEMA_VERSION,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/checks/bin/check-registry-gates.ts
|
|
4
4
|
import { execSync, execFileSync as execFileSync2 } from "node:child_process";
|
|
5
|
-
import { existsSync as existsSync3, readdirSync, readFileSync, statSync } from "node:fs";
|
|
5
|
+
import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync2, statSync } from "node:fs";
|
|
6
6
|
import matter2 from "gray-matter";
|
|
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
|
|
1961
|
+
const primaryPointerPath = transcriptPointerPath(projectDir, tmpDir);
|
|
1962
|
+
const legacyPointerPath = legacyTranscriptPointerPath(projectDir, tmpDir);
|
|
1861
1963
|
const currentSessionId = deps.env.CLAUDE_CODE_SESSION_ID;
|
|
1862
|
-
|
|
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 ${
|
|
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 =
|
|
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
|
}
|
|
@@ -4078,6 +4184,21 @@ var REGISTRY = [
|
|
|
4078
4184
|
},
|
|
4079
4185
|
1
|
|
4080
4186
|
],
|
|
4187
|
+
[
|
|
4188
|
+
{
|
|
4189
|
+
name: "token-report",
|
|
4190
|
+
run: bin("check-token-report"),
|
|
4191
|
+
scope: "diff",
|
|
4192
|
+
timeoutMs: 15000,
|
|
4193
|
+
requiresOpenPr: true,
|
|
4194
|
+
env: {
|
|
4195
|
+
PR_BODY: { optional: true },
|
|
4196
|
+
CLAUDE_PROJECT_DIR: { optional: true },
|
|
4197
|
+
CLAUDE_CODE_SESSION_ID: { optional: true }
|
|
4198
|
+
}
|
|
4199
|
+
},
|
|
4200
|
+
1
|
|
4201
|
+
],
|
|
4081
4202
|
[
|
|
4082
4203
|
{
|
|
4083
4204
|
name: "no-disk-state",
|
|
@@ -4336,7 +4457,7 @@ function globCandidateFiles() {
|
|
|
4336
4457
|
return out;
|
|
4337
4458
|
}
|
|
4338
4459
|
function findCrossingFiles(candidateFiles) {
|
|
4339
|
-
return candidateFiles.filter((path) =>
|
|
4460
|
+
return candidateFiles.filter((path) => readFileSync2(path, "utf8").split(`
|
|
4340
4461
|
`).some((line) => isGithubCrossingLine(line)));
|
|
4341
4462
|
}
|
|
4342
4463
|
function readRoles() {
|
|
@@ -4344,7 +4465,7 @@ function readRoles() {
|
|
|
4344
4465
|
return [];
|
|
4345
4466
|
return readdirSync(ROLES_DIR).filter((name) => name.endsWith(".md")).map((name) => {
|
|
4346
4467
|
const rel = `${ROLES_DIR}/${name}`;
|
|
4347
|
-
const { data } = matter2(
|
|
4468
|
+
const { data } = matter2(readFileSync2(rel, "utf8"));
|
|
4348
4469
|
return {
|
|
4349
4470
|
file: rel,
|
|
4350
4471
|
role_id: typeof data.role_id === "string" ? data.role_id : "",
|
|
@@ -4358,7 +4479,7 @@ function readContracts() {
|
|
|
4358
4479
|
return [];
|
|
4359
4480
|
return readdirSync(CONTRACTS_DIR).filter((name) => name.endsWith(".md")).map((name) => {
|
|
4360
4481
|
const rel = `${CONTRACTS_DIR}/${name}`;
|
|
4361
|
-
const { data } = matter2(
|
|
4482
|
+
const { data } = matter2(readFileSync2(rel, "utf8"));
|
|
4362
4483
|
return {
|
|
4363
4484
|
file: rel,
|
|
4364
4485
|
producer: typeof data.producer === "string" ? data.producer : "",
|
|
@@ -4439,7 +4560,7 @@ async function main() {
|
|
|
4439
4560
|
});
|
|
4440
4561
|
process.exit(0);
|
|
4441
4562
|
}
|
|
4442
|
-
const enforcementContent =
|
|
4563
|
+
const enforcementContent = readFileSync2(ENFORCEMENT_PATH, "utf8");
|
|
4443
4564
|
const rows = parseEnforcementRegistry(enforcementContent);
|
|
4444
4565
|
const ring0Rows = rows.filter((r) => r.ring === "ring0");
|
|
4445
4566
|
const candidateFiles = globCandidateFiles();
|