@attalabs/vinaya 0.28.0 → 0.29.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 +1 -1
- package/aeg-root/contracts/planner-developer.md +4 -1
- package/aeg-root/contracts/planner-operator.md +86 -0
- package/aeg-root/contracts/principal-operator.md +88 -0
- package/aeg-root/roles/developer.md +2 -1
- package/aeg-root/roles/operator.md +133 -0
- package/aeg-root/roles/planner.md +4 -0
- package/aeg-root/skills/aeg-context-packets/SKILL.md +123 -0
- package/aeg-root/skills/aeg-context-packets/examples/operator-start.md +30 -0
- package/aeg-root/templates/brief-template.md +6 -2
- package/dist/checks/bin/check-body-bare-digits.js +376 -16
- package/dist/checks/bin/check-branch-topology.js +403 -16
- package/dist/checks/bin/check-brief-shape.js +380 -19
- package/dist/checks/bin/check-changeset-coverage.js +673 -33
- package/dist/checks/bin/check-closes-n.js +403 -16
- package/dist/checks/bin/check-coherence.js +410 -16
- package/dist/checks/bin/check-dead-branch-push.js +369 -16
- package/dist/checks/bin/check-dispatch-readiness.js +410 -16
- package/dist/checks/bin/check-doc-coverage-push.js +670 -30
- package/dist/checks/bin/check-doc-coverage.js +672 -32
- package/dist/checks/bin/check-doctrine-no-procedures.js +376 -16
- package/dist/checks/bin/check-doctrine-portability.js +670 -30
- package/dist/checks/bin/check-evidence-fresh.js +762 -113
- package/dist/checks/bin/check-exec-bits.js +668 -28
- package/dist/checks/bin/check-first-push-dispatch.js +410 -16
- package/dist/checks/bin/check-issue-assignment.js +403 -16
- package/dist/checks/bin/check-issue-milestone-attach.js +369 -16
- package/dist/checks/bin/check-issue-objectives-numbering.js +369 -16
- package/dist/checks/bin/check-issue-parts-coverage.js +369 -16
- package/dist/checks/bin/check-issue-surface-globs.js +410 -16
- package/dist/checks/bin/check-issue-title-grammar.js +369 -16
- package/dist/checks/bin/check-issue-tranche-label.js +369 -16
- package/dist/checks/bin/check-main-branch-refusal.js +369 -16
- package/dist/checks/bin/check-no-disk-state.js +369 -16
- package/dist/checks/bin/check-pr-premise-reassert.js +376 -16
- package/dist/checks/bin/check-pr-report-density.js +369 -16
- package/dist/checks/bin/check-quoted-command.js +671 -31
- package/dist/checks/bin/check-reader-resolvable-prose.js +674 -34
- package/dist/checks/bin/check-registry-gates.js +369 -16
- package/dist/checks/bin/check-retired-vocabulary.js +669 -29
- package/dist/checks/bin/check-review-gate.js +391 -16
- package/dist/checks/bin/check-single-plan-pr.js +369 -16
- package/dist/checks/bin/check-surface-scope.js +403 -16
- package/dist/checks/bin/check-test-plan.js +369 -16
- package/dist/checks/bin/check-token-collection-wired.js +369 -16
- package/dist/checks/bin/check-token-report.js +382 -19
- package/dist/checks/bin/check-workspace-escape.js +668 -28
- package/dist/index.js +15307 -10932
- package/dist/lib/pre-push-select-tests.js +154 -11
- 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/page.js +2 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error/page.js.nft.json +1 -1
- 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 +8 -7
- 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 +8 -7
- 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 +9 -8
- 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 +9 -8
- 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 +8 -7
- 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 +16 -4
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page.js +10 -8
- 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 +8 -7
- 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 +8 -7
- 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 +9 -8
- 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]__08f5pba._.js +3 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__1o_0tjy._.js → [root-of-the-server]__0h9yhwx._.js} +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__0053k9k._.js → [root-of-the-server]__0ls23oh._.js} +3 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__0puovz5._.js → [root-of-the-server]__0nye8tb._.js} +3 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__18kqy4q._.js → [root-of-the-server]__0tfykr-._.js} +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__0o771t1._.js → [root-of-the-server]__0th3gyp._.js} +3 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1-zcufa._.js +51 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__0p8q38b._.js → [root-of-the-server]__11svemm._.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__02c71kv._.js → [root-of-the-server]__140m1i_._.js} +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1bh2awk._.js +3 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__0112h-k._.js → [root-of-the-server]__1gjqmhq._.js} +3 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1qmxez3._.js +4 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1r47dr7._.js +28 -0
- 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/_01fv4fj._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_0gvm3og._.js → _096f46i._.js} +3 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_0lwxg63._.js → _0af2one._.js} +3 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_1n0cnq-._.js → _0zf4d27._.js} +45 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_03x_w6q._.js → _1-wo68i._.js} +3 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/apps_vinaya-studio_web_src_app_studio_projects_[name]_tranches_[slug]_05ufo8i._.js +1 -12
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/node_modules_1wdusod._.js +3 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{node_modules_1vo08dj._.js → node_modules_@clerk_nextjs_dist_esm_app-router_server-actions_1x7vfhn.js} +3 -4
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/node_modules_next_1khj-jh._.js +3 -0
- 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 +17 -5
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{3_9xytdmiv1xi.js → 25f3-jtiv8p5n.js} +4 -4
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0bn8c8v5q429o.js → 27-6ym7lp2v8o.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{3-6a3tinbdb-7.js → 3daxns3o--9me.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/tsconfig.json +12 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0z6dav-._.js +0 -51
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__13rrmhr._.js +0 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__17h4sy8._.js +0 -45
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1hs0dcu._.js +0 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/node_modules_next_17sz44y._.js +0 -3
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{DMofV2-9FrHE7100GfrpI → -UC6GS6zDHeiawEYgYbTN}/_buildManifest.js +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{DMofV2-9FrHE7100GfrpI → -UC6GS6zDHeiawEYgYbTN}/_clientMiddlewareManifest.js +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{DMofV2-9FrHE7100GfrpI → -UC6GS6zDHeiawEYgYbTN}/_ssgManifest.js +0 -0
|
@@ -3,9 +3,9 @@ import { createRequire } from "node:module";
|
|
|
3
3
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
4
4
|
|
|
5
5
|
// src/checks/bin/check-doctrine-portability.ts
|
|
6
|
-
import { execFileSync as
|
|
7
|
-
import { readdirSync, readFileSync as
|
|
8
|
-
import { join as
|
|
6
|
+
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
7
|
+
import { readdirSync, readFileSync as readFileSync4, statSync } from "node:fs";
|
|
8
|
+
import { join as join6 } from "node:path";
|
|
9
9
|
// ../../packages/aeg-core/src/gate-audience.ts
|
|
10
10
|
var GATE_AUDIENCE = {
|
|
11
11
|
"check-branch-topology": { shippedAs: "branch-topology", ring: 0 },
|
|
@@ -1646,6 +1646,52 @@ var systemEnv3 = {
|
|
|
1646
1646
|
...process.env,
|
|
1647
1647
|
PATH: [process.env.PATH, "/opt/homebrew/bin", "/usr/local/bin", "/usr/bin", "/bin"].filter(Boolean).join(":")
|
|
1648
1648
|
};
|
|
1649
|
+
var defaultExec = () => execFileAsync3("git", ["remote", "get-url", "origin"], { env: systemEnv3, timeout: 5000 });
|
|
1650
|
+
var cached;
|
|
1651
|
+
var inflight;
|
|
1652
|
+
async function resolveRepo(exec = defaultExec) {
|
|
1653
|
+
if (cached !== undefined)
|
|
1654
|
+
return cached;
|
|
1655
|
+
const fromEnv = process.env.AEG_REPO;
|
|
1656
|
+
if (fromEnv) {
|
|
1657
|
+
const parsed = parseOwnerRepo(fromEnv);
|
|
1658
|
+
if (parsed) {
|
|
1659
|
+
cached = parsed;
|
|
1660
|
+
return cached;
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
if (inflight)
|
|
1664
|
+
return inflight;
|
|
1665
|
+
inflight = (async () => {
|
|
1666
|
+
try {
|
|
1667
|
+
const { stdout } = await exec();
|
|
1668
|
+
cached = parseGitRemoteUrl(stdout.trim());
|
|
1669
|
+
return cached;
|
|
1670
|
+
} catch (err) {
|
|
1671
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1672
|
+
console.warn(`[aeg-forge-state] resolveRepo: git remote lookup failed (will retry): ${message}`);
|
|
1673
|
+
return null;
|
|
1674
|
+
} finally {
|
|
1675
|
+
inflight = undefined;
|
|
1676
|
+
}
|
|
1677
|
+
})();
|
|
1678
|
+
return inflight;
|
|
1679
|
+
}
|
|
1680
|
+
function parseGitRemoteUrl(url) {
|
|
1681
|
+
const ssh = url.match(/^git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/);
|
|
1682
|
+
if (ssh?.[1] && ssh[2])
|
|
1683
|
+
return { owner: ssh[1], repo: ssh[2] };
|
|
1684
|
+
const https = url.match(/^https?:\/\/(?:[^@]+@)?github\.com\/([^/]+)\/(.+?)(?:\.git)?\/?$/);
|
|
1685
|
+
if (https?.[1] && https[2])
|
|
1686
|
+
return { owner: https[1], repo: https[2] };
|
|
1687
|
+
return null;
|
|
1688
|
+
}
|
|
1689
|
+
function parseOwnerRepo(value) {
|
|
1690
|
+
const match = value.match(/^([^/]+)\/(.+)$/);
|
|
1691
|
+
if (!match?.[1] || !match[2])
|
|
1692
|
+
return null;
|
|
1693
|
+
return { owner: match[1], repo: match[2] };
|
|
1694
|
+
}
|
|
1649
1695
|
// ../../packages/aeg-core/src/anchored-region.ts
|
|
1650
1696
|
function anchoredRegionBounds(body, field) {
|
|
1651
1697
|
const masked = maskCode(body);
|
|
@@ -1958,6 +2004,7 @@ var OBJECTIVES_VERSION_PATTERN = /^[ \t]*(?:\*{1,3}|_{1,3})?Objectives version:\
|
|
|
1958
2004
|
var RULING_ORDINAL_PATTERN = /^[ \t]*(?:\*{1,3}|_{1,3})?Ruling ordinal:\s*(\d+)(?!\d)/im;
|
|
1959
2005
|
var BRIEF_HASH_PATTERN = /^[ \t]*(?:\*{1,3}|_{1,3})?Brief hash:\s*([0-9a-f]{64})(?![A-Za-z0-9])/im;
|
|
1960
2006
|
var POLICY_DIGEST_PATTERN = /^[ \t]*(?:\*{1,3}|_{1,3})?Policy digest:\s*([0-9a-f]{64})(?![A-Za-z0-9])/im;
|
|
2007
|
+
var BASE_SHA_PATTERN = /^[ \t]*(?:\*{1,3}|_{1,3})?Judged base:\s*([0-9a-f]{7,40})(?![A-Za-z0-9])/im;
|
|
1961
2008
|
function firstFiveLines(comment) {
|
|
1962
2009
|
return comment.split(`
|
|
1963
2010
|
`).slice(0, 5).join(`
|
|
@@ -1993,6 +2040,15 @@ function extractPolicyDigest(comment) {
|
|
|
1993
2040
|
const m = firstElevenLines(comment).match(POLICY_DIGEST_PATTERN);
|
|
1994
2041
|
return m ? m[1].toLowerCase() : null;
|
|
1995
2042
|
}
|
|
2043
|
+
function firstThirteenLines(comment) {
|
|
2044
|
+
return comment.split(`
|
|
2045
|
+
`).slice(0, 13).join(`
|
|
2046
|
+
`);
|
|
2047
|
+
}
|
|
2048
|
+
function extractBaseSha(comment) {
|
|
2049
|
+
const m = firstThirteenLines(comment).match(BASE_SHA_PATTERN);
|
|
2050
|
+
return m ? m[1].toLowerCase() : null;
|
|
2051
|
+
}
|
|
1996
2052
|
var FINDING_SEVERITY_LINE = /^\d+\.\s+\[([A-Z][A-Z]*)\]\s+(.+?)\s+—/gm;
|
|
1997
2053
|
function extractFindingSeverities(comment) {
|
|
1998
2054
|
return [...comment.matchAll(FINDING_SEVERITY_LINE)].map((m) => ({
|
|
@@ -2010,6 +2066,7 @@ function extractVerdict(comments, valuePattern, missingLabel) {
|
|
|
2010
2066
|
rulingOrdinal: null,
|
|
2011
2067
|
briefHash: null,
|
|
2012
2068
|
policyDigest: null,
|
|
2069
|
+
baseSha: null,
|
|
2013
2070
|
findingSeverities: [],
|
|
2014
2071
|
danglingNote: `no ${missingLabel} verdict comment found on this PR`
|
|
2015
2072
|
};
|
|
@@ -2024,6 +2081,7 @@ function extractVerdict(comments, valuePattern, missingLabel) {
|
|
|
2024
2081
|
rulingOrdinal: null,
|
|
2025
2082
|
briefHash: null,
|
|
2026
2083
|
policyDigest: null,
|
|
2084
|
+
baseSha: null,
|
|
2027
2085
|
findingSeverities: [],
|
|
2028
2086
|
danglingNote: `the most recent ${missingLabel} verdict comment carries a VERDICT-shaped line outside the first-five-line read window`
|
|
2029
2087
|
};
|
|
@@ -2035,6 +2093,7 @@ function extractVerdict(comments, valuePattern, missingLabel) {
|
|
|
2035
2093
|
rulingOrdinal: extractRulingOrdinal(latest),
|
|
2036
2094
|
briefHash: extractBriefHash(latest),
|
|
2037
2095
|
policyDigest: extractPolicyDigest(latest),
|
|
2096
|
+
baseSha: extractBaseSha(latest),
|
|
2038
2097
|
findingSeverities: extractFindingSeverities(latest),
|
|
2039
2098
|
danglingNote: null
|
|
2040
2099
|
};
|
|
@@ -3948,7 +4007,11 @@ function briefHash(brief) {
|
|
|
3948
4007
|
`).digest("hex");
|
|
3949
4008
|
}
|
|
3950
4009
|
function policyDigest(policy) {
|
|
3951
|
-
return createHash4("sha256").update(JSON.stringify({
|
|
4010
|
+
return createHash4("sha256").update(JSON.stringify({
|
|
4011
|
+
codeReviewThreshold: policy.codeReviewThreshold,
|
|
4012
|
+
securityThreshold: policy.securityThreshold,
|
|
4013
|
+
maxRounds: policy.maxRounds
|
|
4014
|
+
})).digest("hex");
|
|
3952
4015
|
}
|
|
3953
4016
|
function isBoundToHead(echoed, headSha) {
|
|
3954
4017
|
if (!echoed.headSha)
|
|
@@ -3964,8 +4027,12 @@ function isBoundByPatchIdentity(echoed, headSha, patchIdOf) {
|
|
|
3964
4027
|
return false;
|
|
3965
4028
|
return judged === current;
|
|
3966
4029
|
}
|
|
3967
|
-
function
|
|
3968
|
-
|
|
4030
|
+
function isBoundToBase(echoed, currentBase) {
|
|
4031
|
+
if (currentBase === null)
|
|
4032
|
+
return true;
|
|
4033
|
+
if (!echoed.baseSha)
|
|
4034
|
+
return false;
|
|
4035
|
+
return currentBase.toLowerCase().startsWith(echoed.baseSha.toLowerCase());
|
|
3969
4036
|
}
|
|
3970
4037
|
function isBoundToObjectives(echoed, currentVersion) {
|
|
3971
4038
|
if (currentVersion === null)
|
|
@@ -3986,14 +4053,18 @@ function isBoundToPolicy(echoed, currentDigest) {
|
|
|
3986
4053
|
return echoed.policyDigest === currentDigest;
|
|
3987
4054
|
}
|
|
3988
4055
|
function compareManifest(echoed, current, patchIdOf) {
|
|
3989
|
-
const
|
|
4056
|
+
const exactHead = isBoundToHead(echoed, current.headSha);
|
|
4057
|
+
const patchHead = exactHead ? false : isBoundByPatchIdentity(echoed, current.headSha, patchIdOf);
|
|
4058
|
+
const head = exactHead || patchHead;
|
|
4059
|
+
const base = patchHead ? true : isBoundToBase(echoed, current.baseSha);
|
|
3990
4060
|
const briefHashBound = isBoundToBriefHash(echoed, current.briefHash);
|
|
3991
4061
|
const objectivesVersion2 = isBoundToObjectives(echoed, current.objectivesVersion);
|
|
3992
4062
|
const rulingOrdinal = isBoundToRulings(echoed, current.rulingOrdinal);
|
|
3993
4063
|
const policyDigestBound = isBoundToPolicy(echoed, current.policyDigest);
|
|
3994
4064
|
return {
|
|
3995
|
-
bound: head && briefHashBound && objectivesVersion2 && rulingOrdinal && policyDigestBound,
|
|
4065
|
+
bound: head && base && briefHashBound && objectivesVersion2 && rulingOrdinal && policyDigestBound,
|
|
3996
4066
|
head,
|
|
4067
|
+
base,
|
|
3997
4068
|
briefHash: briefHashBound,
|
|
3998
4069
|
objectivesVersion: objectivesVersion2,
|
|
3999
4070
|
rulingOrdinal,
|
|
@@ -4045,6 +4116,7 @@ function checkReviewGate(input) {
|
|
|
4045
4116
|
const securityClean = securityTextClean && securityPolicyClean;
|
|
4046
4117
|
const currentManifest = {
|
|
4047
4118
|
headSha: input.headSha,
|
|
4119
|
+
baseSha: input.baseSha ?? null,
|
|
4048
4120
|
briefHash: input.briefHash ?? null,
|
|
4049
4121
|
objectivesVersion: input.objectivesVersion,
|
|
4050
4122
|
rulingOrdinal: input.rulingOrdinal,
|
|
@@ -4052,6 +4124,7 @@ function checkReviewGate(input) {
|
|
|
4052
4124
|
};
|
|
4053
4125
|
const codeReviewEchoed = {
|
|
4054
4126
|
headSha: codeReview.headSha,
|
|
4127
|
+
baseSha: codeReview.baseSha,
|
|
4055
4128
|
briefHash: codeReview.briefHash,
|
|
4056
4129
|
objectivesVersion: codeReview.objectivesVersion,
|
|
4057
4130
|
rulingOrdinal: codeReview.rulingOrdinal,
|
|
@@ -4059,6 +4132,7 @@ function checkReviewGate(input) {
|
|
|
4059
4132
|
};
|
|
4060
4133
|
const securityEchoed = {
|
|
4061
4134
|
headSha: security.headSha,
|
|
4135
|
+
baseSha: security.baseSha,
|
|
4062
4136
|
briefHash: security.briefHash,
|
|
4063
4137
|
objectivesVersion: security.objectivesVersion,
|
|
4064
4138
|
rulingOrdinal: security.rulingOrdinal,
|
|
@@ -4086,6 +4160,8 @@ function checkReviewGate(input) {
|
|
|
4086
4160
|
problems.push(`code-reviewer verdict says APPROVE but carries a finding (${codeReviewPolicyEvaluation.blockingFindings.map((f) => f.severity).join(", ")}) at or above this repository's code-review policy threshold (${policy.codeReviewThreshold}) — a reviewer's own APPROVE never overrides policy`);
|
|
4087
4161
|
} else if (!codeReviewBound) {
|
|
4088
4162
|
problems.push(`the newest code-review verdict covers ${codeReview.headSha ?? "no recorded commit"}, head is ${input.headSha}`);
|
|
4163
|
+
} else if (!codeReviewBinding.base) {
|
|
4164
|
+
problems.push(`the newest code-review verdict was cast against base ${codeReview.baseSha ?? "no recorded base"}, the PR's base is now ${currentManifest.baseSha ?? "unresolved"} (a base-only change under an unchanged candidate — same patch text on a new base is not automatically equivalent)`);
|
|
4089
4165
|
} else if (!codeReviewObjectivesBound) {
|
|
4090
4166
|
problems.push(`the newest code-review verdict was cast against objectives version ${codeReview.objectivesVersion ?? "none"}, the Issue's list is now ${input.objectivesVersion}`);
|
|
4091
4167
|
} else if (!codeReviewRulingsBound) {
|
|
@@ -4101,6 +4177,8 @@ function checkReviewGate(input) {
|
|
|
4101
4177
|
problems.push(`security-review verdict says PASS but carries a finding (${securityPolicyEvaluation.blockingFindings.map((f) => f.severity).join(", ")}) at or above this repository's security policy threshold (${policy.securityThreshold}) — a reviewer's own PASS never overrides policy`);
|
|
4102
4178
|
} else if (!securityBound) {
|
|
4103
4179
|
problems.push(`the newest security-review verdict covers ${security.headSha ?? "no recorded commit"}, head is ${input.headSha}`);
|
|
4180
|
+
} else if (!securityBinding.base) {
|
|
4181
|
+
problems.push(`the newest security-review verdict was cast against base ${security.baseSha ?? "no recorded base"}, the PR's base is now ${currentManifest.baseSha ?? "unresolved"} (a base-only change under an unchanged candidate — same patch text on a new base is not automatically equivalent)`);
|
|
4104
4182
|
} else if (!securityObjectivesBound) {
|
|
4105
4183
|
problems.push(`the newest security-review verdict was cast against objectives version ${security.objectivesVersion ?? "none"}, the Issue's list is now ${input.objectivesVersion}`);
|
|
4106
4184
|
} else if (!securityRulingsBound) {
|
|
@@ -4958,8 +5036,8 @@ var TaskToolErrorSchema = z.object({
|
|
|
4958
5036
|
detail: z.string().optional()
|
|
4959
5037
|
});
|
|
4960
5038
|
var TaskToolRefSchema = z.union([
|
|
4961
|
-
z.object({ tranche: z.string().min(1), id: z.string().min(1) }),
|
|
4962
|
-
z.object({ issue: z.number().int().positive() })
|
|
5039
|
+
z.object({ tranche: z.string().min(1), id: z.string().min(1) }).strict(),
|
|
5040
|
+
z.object({ issue: z.number().int().positive() }).strict()
|
|
4963
5041
|
]);
|
|
4964
5042
|
var MAX_PAGE_LIMIT = 100;
|
|
4965
5043
|
var PageRequestSchema = z.object({
|
|
@@ -4973,7 +5051,7 @@ var ObservedSchema = z.object({
|
|
|
4973
5051
|
});
|
|
4974
5052
|
var TaskStatusInputSchema = z.object({
|
|
4975
5053
|
task: TaskToolRefSchema.optional()
|
|
4976
|
-
}).merge(PageRequestSchema);
|
|
5054
|
+
}).merge(PageRequestSchema).strict();
|
|
4977
5055
|
var TaskStatusItemSchema = z.object({
|
|
4978
5056
|
task: TaskToolRefSchema,
|
|
4979
5057
|
issue: z.number().int().positive(),
|
|
@@ -4997,9 +5075,20 @@ var EscalationEvidenceSchema = z.object({
|
|
|
4997
5075
|
reviewer: z.string().nullable(),
|
|
4998
5076
|
security: z.string().nullable()
|
|
4999
5077
|
});
|
|
5078
|
+
var EscalationRunIdentitySchema = z.object({
|
|
5079
|
+
runId: z.string(),
|
|
5080
|
+
pid: z.number().int().positive(),
|
|
5081
|
+
host: z.string()
|
|
5082
|
+
});
|
|
5083
|
+
var EscalationInputVersionsSchema = z.object({
|
|
5084
|
+
briefHash: z.string().nullable(),
|
|
5085
|
+
objectivesVersion: z.string().nullable(),
|
|
5086
|
+
rulingOrdinal: z.number().int().nonnegative(),
|
|
5087
|
+
policyDigest: z.string()
|
|
5088
|
+
});
|
|
5000
5089
|
var TaskEscalationReadInputSchema = z.object({
|
|
5001
5090
|
task: TaskToolRefSchema
|
|
5002
|
-
}).merge(PageRequestSchema);
|
|
5091
|
+
}).merge(PageRequestSchema).strict();
|
|
5003
5092
|
var TaskEscalationPacketSchema = z.object({
|
|
5004
5093
|
reason: z.string(),
|
|
5005
5094
|
detail: z.string().nullable(),
|
|
@@ -5007,7 +5096,9 @@ var TaskEscalationPacketSchema = z.object({
|
|
|
5007
5096
|
evidence: EscalationEvidenceSchema.nullable(),
|
|
5008
5097
|
attemptedRecovery: z.string(),
|
|
5009
5098
|
requestedAuthority: RequestedAuthoritySchema,
|
|
5010
|
-
permittedNextActions: z.array(z.string())
|
|
5099
|
+
permittedNextActions: z.array(z.string()),
|
|
5100
|
+
runIdentity: EscalationRunIdentitySchema.nullable(),
|
|
5101
|
+
inputVersions: EscalationInputVersionsSchema.nullable()
|
|
5011
5102
|
}).merge(ObservedSchema);
|
|
5012
5103
|
var TaskEscalationReadResultSchema = z.object({
|
|
5013
5104
|
items: z.array(TaskEscalationPacketSchema),
|
|
@@ -5016,15 +5107,48 @@ var TaskEscalationReadResultSchema = z.object({
|
|
|
5016
5107
|
var TaskStartInputSchema = z.object({
|
|
5017
5108
|
tranche: z.string().min(1),
|
|
5018
5109
|
id: z.string().min(1)
|
|
5110
|
+
}).strict();
|
|
5111
|
+
var TaskStartResultSchema = z.object({
|
|
5112
|
+
requestId: z.string().min(1),
|
|
5113
|
+
run: z.object({ tranche: z.string().min(1), id: z.string().min(1) }),
|
|
5114
|
+
started: z.boolean(),
|
|
5115
|
+
startedAt: z.string(),
|
|
5116
|
+
mode: z.literal("attended")
|
|
5019
5117
|
});
|
|
5020
5118
|
var TaskResumeInputSchema = z.object({
|
|
5021
5119
|
task: TaskToolRefSchema
|
|
5022
|
-
});
|
|
5120
|
+
}).strict();
|
|
5023
5121
|
var TaskCancelInputSchema = z.object({
|
|
5024
5122
|
task: TaskToolRefSchema,
|
|
5025
5123
|
reason: z.string().min(1)
|
|
5124
|
+
}).strict();
|
|
5125
|
+
var TaskResumeResultSchema = z.object({
|
|
5126
|
+
task: z.number().int().positive(),
|
|
5127
|
+
pr: z.number().int().positive(),
|
|
5128
|
+
escalationId: z.string().min(1),
|
|
5129
|
+
outcome: z.enum(["started", "already_resumed"]),
|
|
5130
|
+
authenticatedBy: z.string().min(1),
|
|
5131
|
+
authenticatedFrom: z.string().min(1)
|
|
5026
5132
|
});
|
|
5027
|
-
var
|
|
5133
|
+
var TaskCancelOutcomeSchema = z.enum(["confirmed", "pending", "uncertain"]);
|
|
5134
|
+
var TaskCancelResultSchema = z.object({
|
|
5135
|
+
task: z.number().int().positive(),
|
|
5136
|
+
pr: z.number().int().positive(),
|
|
5137
|
+
escalationId: z.string().min(1),
|
|
5138
|
+
outcome: TaskCancelOutcomeSchema,
|
|
5139
|
+
authenticatedBy: z.string().min(1),
|
|
5140
|
+
authenticatedFrom: z.string().min(1),
|
|
5141
|
+
fencedEffectKeys: z.array(z.string())
|
|
5142
|
+
});
|
|
5143
|
+
var TASK_TOOL_NAMES = [
|
|
5144
|
+
"task_start",
|
|
5145
|
+
"task_status",
|
|
5146
|
+
"task_escalation_read",
|
|
5147
|
+
"task_resume",
|
|
5148
|
+
"task_cancel"
|
|
5149
|
+
];
|
|
5150
|
+
var OPERATOR_STATUS_FOLLOW = "task_status_follow";
|
|
5151
|
+
var OPERATOR_TOOL_GRANT = [...TASK_TOOL_NAMES, OPERATOR_STATUS_FOLLOW];
|
|
5028
5152
|
// ../../packages/aeg-core/src/first-push-dispatch-gate.ts
|
|
5029
5153
|
function parseTaskBranch(branch) {
|
|
5030
5154
|
const m = /^task\/([^/]+)\/([^/]+)$/.exec(branch);
|
|
@@ -5247,6 +5371,9 @@ function findWorkspaceEscapes(files, knownPaths, workspaceDirs = DEFAULT_WORKSPA
|
|
|
5247
5371
|
}
|
|
5248
5372
|
return findings;
|
|
5249
5373
|
}
|
|
5374
|
+
// ../../packages/aeg-core/src/log/envelope.ts
|
|
5375
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
5376
|
+
|
|
5250
5377
|
// ../../packages/aeg-core/src/log/schema.ts
|
|
5251
5378
|
import { z as z2 } from "zod";
|
|
5252
5379
|
var ROLE_VALUES = [
|
|
@@ -5348,7 +5475,8 @@ var DispatchOutcomeSchema = z2.discriminatedUnion("type", [
|
|
|
5348
5475
|
}).strict(),
|
|
5349
5476
|
z2.object({ type: z2.literal("brief"), comment_id: z2.number().int(), hash: z2.string() }).strict(),
|
|
5350
5477
|
z2.object({ type: z2.literal("plan"), issues: z2.array(z2.number().int()) }).strict(),
|
|
5351
|
-
z2.object({ type: z2.literal("archive"), provenance_comment_id: z2.number().int() }).strict()
|
|
5478
|
+
z2.object({ type: z2.literal("archive"), provenance_comment_id: z2.number().int() }).strict(),
|
|
5479
|
+
z2.object({ type: z2.literal("completed") }).strict()
|
|
5352
5480
|
]);
|
|
5353
5481
|
var dispatchShared = {
|
|
5354
5482
|
meta: HeaderMetaSchema,
|
|
@@ -5408,7 +5536,8 @@ var DevReviewLoopEventSchema = z2.discriminatedUnion("event", [
|
|
|
5408
5536
|
round: z2.number().int(),
|
|
5409
5537
|
head: z2.string(),
|
|
5410
5538
|
all_approve: z2.boolean(),
|
|
5411
|
-
blockers: z2.number().int().nonnegative()
|
|
5539
|
+
blockers: z2.number().int().nonnegative(),
|
|
5540
|
+
findings: z2.array(ReviewFindingSchema).optional()
|
|
5412
5541
|
}).strict(),
|
|
5413
5542
|
z2.object({
|
|
5414
5543
|
...loopShared,
|
|
@@ -5587,7 +5716,9 @@ var roleAttemptShared = {
|
|
|
5587
5716
|
kind: z2.literal("role_attempt"),
|
|
5588
5717
|
...envelopeTail,
|
|
5589
5718
|
actor: z2.string().nullable(),
|
|
5590
|
-
attempt: z2.number().int().nullable()
|
|
5719
|
+
attempt: z2.number().int().nullable(),
|
|
5720
|
+
effect_id: z2.string(),
|
|
5721
|
+
model: z2.string().nullable()
|
|
5591
5722
|
};
|
|
5592
5723
|
var RoleAttemptEventSchema = z2.discriminatedUnion("event", [
|
|
5593
5724
|
z2.object({
|
|
@@ -5646,6 +5777,144 @@ var LogEventSchema = z2.union([
|
|
|
5646
5777
|
HandoffEventSchema,
|
|
5647
5778
|
EffectEventSchema
|
|
5648
5779
|
]);
|
|
5780
|
+
|
|
5781
|
+
// ../../packages/aeg-core/src/log/envelope.ts
|
|
5782
|
+
function isRole(value) {
|
|
5783
|
+
return value !== undefined && ROLE_VALUES.includes(value);
|
|
5784
|
+
}
|
|
5785
|
+
function actorIdFromEnv(role) {
|
|
5786
|
+
return role === undefined || role === "" ? null : role;
|
|
5787
|
+
}
|
|
5788
|
+
function lineageFieldFromEnv(value) {
|
|
5789
|
+
return value === undefined || value === "" ? null : value;
|
|
5790
|
+
}
|
|
5791
|
+
function attemptFromEnv(value) {
|
|
5792
|
+
if (value === undefined || value === "")
|
|
5793
|
+
return null;
|
|
5794
|
+
const n = Number(value);
|
|
5795
|
+
return Number.isInteger(n) ? n : null;
|
|
5796
|
+
}
|
|
5797
|
+
function provenanceFor(input) {
|
|
5798
|
+
if (input.provenance)
|
|
5799
|
+
return input.provenance;
|
|
5800
|
+
if (input.env.role || input.env.task)
|
|
5801
|
+
return "env_correlated";
|
|
5802
|
+
return "unavailable";
|
|
5803
|
+
}
|
|
5804
|
+
function issueFromTask(task) {
|
|
5805
|
+
if (task === undefined || task === "")
|
|
5806
|
+
return null;
|
|
5807
|
+
const n = Number(task);
|
|
5808
|
+
return Number.isInteger(n) ? n : null;
|
|
5809
|
+
}
|
|
5810
|
+
function roundFromEnv(round) {
|
|
5811
|
+
if (round === undefined || round === "")
|
|
5812
|
+
return;
|
|
5813
|
+
const n = Number(round);
|
|
5814
|
+
return Number.isInteger(n) ? n : undefined;
|
|
5815
|
+
}
|
|
5816
|
+
function buildHeader(input) {
|
|
5817
|
+
const role = isRole(input.env.role) ? input.env.role : "unattributed";
|
|
5818
|
+
const round = roundFromEnv(input.env.round);
|
|
5819
|
+
const subject = {
|
|
5820
|
+
issue: issueFromTask(input.env.task),
|
|
5821
|
+
role,
|
|
5822
|
+
...round !== undefined ? { round } : {},
|
|
5823
|
+
...input.subject ?? {}
|
|
5824
|
+
};
|
|
5825
|
+
return {
|
|
5826
|
+
meta: {
|
|
5827
|
+
schema: 2,
|
|
5828
|
+
ts: input.now.toISOString(),
|
|
5829
|
+
run_id: input.runId,
|
|
5830
|
+
seq: input.seq,
|
|
5831
|
+
repo: input.repo,
|
|
5832
|
+
vinaya: input.vinaya,
|
|
5833
|
+
doctrine: input.doctrine,
|
|
5834
|
+
host: input.host,
|
|
5835
|
+
machine: createHash5("sha256").update(input.hostname).digest("hex"),
|
|
5836
|
+
event_id: input.eventId,
|
|
5837
|
+
process_id: input.processId,
|
|
5838
|
+
actor_id: actorIdFromEnv(input.env.role),
|
|
5839
|
+
lineage: {
|
|
5840
|
+
run: lineageFieldFromEnv(input.env.run),
|
|
5841
|
+
attempt: attemptFromEnv(input.env.attempt),
|
|
5842
|
+
parent: lineageFieldFromEnv(input.env.parent)
|
|
5843
|
+
},
|
|
5844
|
+
input_versions: {
|
|
5845
|
+
objectives_version: input.inputVersions?.objectivesVersion ?? null,
|
|
5846
|
+
brief_hash: input.inputVersions?.briefHash ?? null,
|
|
5847
|
+
ruling_ordinal: input.inputVersions?.rulingOrdinal ?? null,
|
|
5848
|
+
policy_digest: input.inputVersions?.policyDigest ?? null
|
|
5849
|
+
},
|
|
5850
|
+
provenance: provenanceFor(input)
|
|
5851
|
+
},
|
|
5852
|
+
subject
|
|
5853
|
+
};
|
|
5854
|
+
}
|
|
5855
|
+
// ../../packages/aeg-core/src/log/redact.ts
|
|
5856
|
+
var GITHUB_TOKEN_PATTERN = /\b(?:gho_|ghp_|ghs_|ghu_|ghr_|github_pat_)[A-Za-z0-9_]+\b/g;
|
|
5857
|
+
var CLASSIC_GITHUB_PAT_PATTERN = /\b((?:token|GITHUB_TOKEN|PAT|api[_-]?key|api[_-]?token)\s*[:=]\s*)[a-f0-9]{40}\b/gi;
|
|
5858
|
+
var BEARER_TOKEN_PATTERN = /\bBearer\s+\S+/g;
|
|
5859
|
+
var AWS_ACCESS_KEY_PATTERN = /\bAKIA[0-9A-Z]{16}\b/g;
|
|
5860
|
+
var SLACK_TOKEN_PATTERN = /\bxox[baprs]-[0-9A-Za-z-]+\b/g;
|
|
5861
|
+
var STRIPE_KEY_PATTERN = /\b(?:sk|pk|rk)_(?:live|test)_[0-9A-Za-z]{10,}\b/g;
|
|
5862
|
+
var ANTHROPIC_KEY_PATTERN = /\bsk-ant-[A-Za-z0-9_-]{20,}\b/g;
|
|
5863
|
+
var OPENAI_KEY_PATTERN = /\bsk-(?!ant-)[A-Za-z0-9]{20,}\b/g;
|
|
5864
|
+
var NPM_TOKEN_PATTERN = /\bnpm_[A-Za-z0-9]{36}\b/g;
|
|
5865
|
+
var JWT_PATTERN = /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g;
|
|
5866
|
+
var PEM_BLOCK_PATTERN = /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g;
|
|
5867
|
+
var BASIC_AUTH_URL_PATTERN = /(https?:\/\/)[^/\s:@]+:[^/\s@]+@/g;
|
|
5868
|
+
var GENERIC_SECRET_ASSIGNMENT_PATTERN = /\b((?:secret|password|passwd|api[_-]?key|access[_-]?key|client[_-]?secret|private[_-]?key)\s*[:=]\s*)[A-Za-z0-9+/_=-]{16,}\b/gi;
|
|
5869
|
+
function redactString(value, home) {
|
|
5870
|
+
let out = value.replace(GITHUB_TOKEN_PATTERN, "<redacted>").replace(CLASSIC_GITHUB_PAT_PATTERN, "$1<redacted>").replace(BEARER_TOKEN_PATTERN, "<redacted>").replace(AWS_ACCESS_KEY_PATTERN, "<redacted>").replace(SLACK_TOKEN_PATTERN, "<redacted>").replace(STRIPE_KEY_PATTERN, "<redacted>").replace(ANTHROPIC_KEY_PATTERN, "<redacted>").replace(OPENAI_KEY_PATTERN, "<redacted>").replace(NPM_TOKEN_PATTERN, "<redacted>").replace(JWT_PATTERN, "<redacted>").replace(PEM_BLOCK_PATTERN, "<redacted>").replace(BASIC_AUTH_URL_PATTERN, "$1<redacted>@").replace(GENERIC_SECRET_ASSIGNMENT_PATTERN, "$1<redacted>");
|
|
5871
|
+
if (home.length > 0 && out.startsWith(home)) {
|
|
5872
|
+
const rest = out.slice(home.length);
|
|
5873
|
+
if (rest === "" || rest.startsWith("/"))
|
|
5874
|
+
out = `~${rest}`;
|
|
5875
|
+
}
|
|
5876
|
+
return out;
|
|
5877
|
+
}
|
|
5878
|
+
function redact(value, home) {
|
|
5879
|
+
if (typeof value === "string")
|
|
5880
|
+
return redactString(value, home);
|
|
5881
|
+
if (Array.isArray(value))
|
|
5882
|
+
return value.map((v) => redact(v, home));
|
|
5883
|
+
if (value !== null && typeof value === "object") {
|
|
5884
|
+
const out = {};
|
|
5885
|
+
for (const [k, v] of Object.entries(value)) {
|
|
5886
|
+
out[k] = redact(v, home);
|
|
5887
|
+
}
|
|
5888
|
+
return out;
|
|
5889
|
+
}
|
|
5890
|
+
return value;
|
|
5891
|
+
}
|
|
5892
|
+
// ../../packages/aeg-core/src/log/store.ts
|
|
5893
|
+
function metaOf(obj) {
|
|
5894
|
+
if (obj === null || typeof obj !== "object")
|
|
5895
|
+
return null;
|
|
5896
|
+
const meta = obj.meta;
|
|
5897
|
+
if (meta === null || typeof meta !== "object")
|
|
5898
|
+
return null;
|
|
5899
|
+
return meta;
|
|
5900
|
+
}
|
|
5901
|
+
function recordIdentity(obj) {
|
|
5902
|
+
const meta = metaOf(obj);
|
|
5903
|
+
if (meta === null)
|
|
5904
|
+
return null;
|
|
5905
|
+
const eventId = meta.event_id;
|
|
5906
|
+
if (typeof eventId === "string" && eventId.length > 0)
|
|
5907
|
+
return eventId;
|
|
5908
|
+
const runId = meta.run_id;
|
|
5909
|
+
const seq = meta.seq;
|
|
5910
|
+
if (typeof runId === "string" && runId.length > 0 && typeof seq === "number" && Number.isInteger(seq)) {
|
|
5911
|
+
return `${runId}:${seq}`;
|
|
5912
|
+
}
|
|
5913
|
+
return null;
|
|
5914
|
+
}
|
|
5915
|
+
|
|
5916
|
+
// ../../packages/aeg-core/src/log/artifact.ts
|
|
5917
|
+
var TASK_LOG_ARTIFACT_MAX_BYTES = 8 * 1024 * 1024;
|
|
5649
5918
|
// ../../packages/aeg-core/src/dev-review-loop/journal-reconstruction.ts
|
|
5650
5919
|
var STOPPED_CONDITIONS = new Set(["confidence", "reappearance", "no_progress", "max_rounds"]);
|
|
5651
5920
|
// ../../packages/aeg-core/src/control-store/records.ts
|
|
@@ -5660,7 +5929,9 @@ var RunRecordSchema = z3.object({
|
|
|
5660
5929
|
runId: z3.string().min(1),
|
|
5661
5930
|
pid: z3.number().int().positive(),
|
|
5662
5931
|
host: z3.string().min(1),
|
|
5663
|
-
startedAt: isoTimestamp
|
|
5932
|
+
startedAt: isoTimestamp,
|
|
5933
|
+
childStartedAt: z3.string().min(1).nullable().optional(),
|
|
5934
|
+
childCommand: z3.string().min(1).nullable().optional()
|
|
5664
5935
|
}).strict();
|
|
5665
5936
|
var InputRecordSchema = z3.object({
|
|
5666
5937
|
version: z3.literal(1),
|
|
@@ -5693,6 +5964,88 @@ var TransitionRecordSchema = z3.object({
|
|
|
5693
5964
|
detail: z3.string().optional(),
|
|
5694
5965
|
at: isoTimestamp
|
|
5695
5966
|
}).strict();
|
|
5967
|
+
var ManifestRecordSchema = z3.object({
|
|
5968
|
+
version: z3.literal(1),
|
|
5969
|
+
kind: z3.literal("manifest"),
|
|
5970
|
+
task: taskId,
|
|
5971
|
+
round: epochNumber,
|
|
5972
|
+
repository: z3.string().min(1),
|
|
5973
|
+
pr: z3.number().int().positive(),
|
|
5974
|
+
branch: z3.string().min(1),
|
|
5975
|
+
baseSha: z3.string().min(1).nullable(),
|
|
5976
|
+
headSha: z3.string().min(1),
|
|
5977
|
+
briefHash: z3.string().min(1).nullable(),
|
|
5978
|
+
objectivesVersion: z3.string().min(1).nullable(),
|
|
5979
|
+
rulingOrdinal: epochNumber,
|
|
5980
|
+
policyDigest: z3.string().min(1),
|
|
5981
|
+
recordedAt: isoTimestamp
|
|
5982
|
+
}).strict();
|
|
5983
|
+
var roundHeadIdentity = z3.object({ round: z3.number().int().positive(), head: z3.string().min(1) }).strict();
|
|
5984
|
+
var LoopBudgetsSchema = z3.object({
|
|
5985
|
+
mechanicalRetries: z3.number().int().nonnegative(),
|
|
5986
|
+
reviewRounds: z3.number().int().nonnegative(),
|
|
5987
|
+
infrastructureRetries: z3.number().int().nonnegative()
|
|
5988
|
+
}).strict();
|
|
5989
|
+
var LoopStateRecordSchema = z3.object({
|
|
5990
|
+
version: z3.literal(1),
|
|
5991
|
+
kind: z3.literal("loop_state"),
|
|
5992
|
+
task: taskId,
|
|
5993
|
+
round: z3.number().int().positive(),
|
|
5994
|
+
phase: z3.string().min(1),
|
|
5995
|
+
pauseReason: z3.string().min(1).nullable(),
|
|
5996
|
+
budgets: LoopBudgetsSchema,
|
|
5997
|
+
heldResult: roundHeadIdentity.nullable(),
|
|
5998
|
+
deliveredFindings: roundHeadIdentity.nullable(),
|
|
5999
|
+
recordedAt: isoTimestamp
|
|
6000
|
+
}).strict();
|
|
6001
|
+
var EffectRecordSchema = z3.object({
|
|
6002
|
+
version: z3.literal(1),
|
|
6003
|
+
kind: z3.literal("effect"),
|
|
6004
|
+
task: taskId,
|
|
6005
|
+
key: z3.string().min(1),
|
|
6006
|
+
operation: z3.string().min(1),
|
|
6007
|
+
target: z3.string().min(1),
|
|
6008
|
+
inputVersion: z3.number().int().nonnegative(),
|
|
6009
|
+
payloadDigest: z3.string().min(1),
|
|
6010
|
+
status: z3.union([z3.literal("started"), z3.literal("verified"), z3.literal("uncertain")]),
|
|
6011
|
+
url: z3.string().optional(),
|
|
6012
|
+
recordedAt: isoTimestamp
|
|
6013
|
+
}).strict();
|
|
6014
|
+
var EscalationRecordSchema = z3.object({
|
|
6015
|
+
version: z3.literal(1),
|
|
6016
|
+
kind: z3.literal("escalation"),
|
|
6017
|
+
task: taskId,
|
|
6018
|
+
escalationId: z3.string().min(1),
|
|
6019
|
+
round: epochNumber,
|
|
6020
|
+
head: z3.string().min(1),
|
|
6021
|
+
branch: z3.string().min(1),
|
|
6022
|
+
pr: z3.number().int().positive().nullable(),
|
|
6023
|
+
runId: z3.string().min(1),
|
|
6024
|
+
pid: z3.number().int().positive(),
|
|
6025
|
+
host: z3.string().min(1),
|
|
6026
|
+
agent: z3.string().min(1).optional(),
|
|
6027
|
+
reason: z3.string().min(1),
|
|
6028
|
+
detail: z3.string().optional(),
|
|
6029
|
+
evidence: z3.string().optional(),
|
|
6030
|
+
attemptedRecovery: z3.string().min(1),
|
|
6031
|
+
requestedDecision: z3.string().min(1),
|
|
6032
|
+
recipient: z3.string().min(1),
|
|
6033
|
+
briefHash: z3.string().min(1).nullable(),
|
|
6034
|
+
objectivesVersion: z3.string().min(1).nullable(),
|
|
6035
|
+
rulingOrdinal: epochNumber,
|
|
6036
|
+
policyDigest: z3.string().min(1),
|
|
6037
|
+
recordedAt: isoTimestamp
|
|
6038
|
+
}).strict();
|
|
6039
|
+
var ResolutionRecordSchema = z3.object({
|
|
6040
|
+
version: z3.literal(1),
|
|
6041
|
+
kind: z3.literal("resolution"),
|
|
6042
|
+
task: taskId,
|
|
6043
|
+
escalationId: z3.string().min(1),
|
|
6044
|
+
decision: z3.union([z3.literal("resume"), z3.literal("cancel")]),
|
|
6045
|
+
authenticatedBy: z3.string().min(1),
|
|
6046
|
+
authenticatedFrom: z3.string().min(1),
|
|
6047
|
+
consumedAt: isoTimestamp
|
|
6048
|
+
}).strict();
|
|
5696
6049
|
// src/lib/config.ts
|
|
5697
6050
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
5698
6051
|
import { existsSync, mkdirSync, readFileSync as readFileSync2, realpathSync, writeFileSync } from "node:fs";
|
|
@@ -5873,6 +6226,13 @@ var VinayaConfigSchema = z4.object({
|
|
|
5873
6226
|
message: "must be at most 3600000 (1 hour)"
|
|
5874
6227
|
});
|
|
5875
6228
|
}
|
|
6229
|
+
}).optional(),
|
|
6230
|
+
logPublish: z4.object({
|
|
6231
|
+
issue: z4.number().int().positive().optional(),
|
|
6232
|
+
pr: z4.number().int().positive().optional(),
|
|
6233
|
+
maxChunksPerFlush: z4.number().int().positive().optional()
|
|
6234
|
+
}).refine((v) => !(v.issue !== undefined && v.pr !== undefined), {
|
|
6235
|
+
message: "logPublish: set at most one of issue/pr, not both"
|
|
5876
6236
|
}).optional()
|
|
5877
6237
|
});
|
|
5878
6238
|
var GLOBAL_VINAYA_HOME = join(homedir(), ".vinaya");
|
|
@@ -6049,8 +6409,8 @@ function loadConfig() {
|
|
|
6049
6409
|
var TOKENS_COLLECT_TRUST_PATH = join(GLOBAL_VINAYA_HOME, "tokens-collect-trust.json");
|
|
6050
6410
|
|
|
6051
6411
|
// src/lib/diff-evidence.ts
|
|
6052
|
-
import { execFileSync as
|
|
6053
|
-
import { join as
|
|
6412
|
+
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
6413
|
+
import { join as join5, relative, resolve as resolve2 } from "node:path";
|
|
6054
6414
|
|
|
6055
6415
|
// src/lib/brief-assembly.ts
|
|
6056
6416
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
@@ -6224,6 +6584,16 @@ var COMMANDS = [
|
|
|
6224
6584
|
],
|
|
6225
6585
|
status: "shipped"
|
|
6226
6586
|
},
|
|
6587
|
+
{
|
|
6588
|
+
name: "task-tools serve",
|
|
6589
|
+
description: "Run the task-operator MCP tool server over stdio — the command both runtime adapters register",
|
|
6590
|
+
details: [
|
|
6591
|
+
"Exposes the task-operator tool catalog (`packages/aeg-core/src/task-tools.ts`) to an agent runtime as one MCP server speaking newline-delimited JSON-RPC 2.0 (`initialize`/`tools/list`/`tools/call`). Claude registers it through the generated `.mcp.json`; Codex through its documented `~/.codex/config.toml` `[mcp_servers]` table — both point at this same command.",
|
|
6592
|
+
"stdout carries JSON-RPC and nothing else: any stray write from the CLI (a forge-read warning) is redirected to stderr, so the protocol stream is never corrupted.",
|
|
6593
|
+
"`task_status`/`task_escalation_read` read; `task_start` starts a run in attended mode only, requiring an authenticated caller from the invocation context (`VINAYA_MCP_CALLER`) and refusing without one — MCP is a transport, not authorization. `task_resume`/`task_cancel` require the same authenticated caller, plus a current Principal ruling read fresh from the run's own PR — never a caller-supplied approval; `task_resume` triggers the existing `dev-review-loop --resume` continuation exactly once per escalation, and `task_cancel` reports a truthful `confirmed`/`pending`/`uncertain` outcome, idempotently, across repeated calls. No unattended start until the worker-isolation boundary and a capability flag land."
|
|
6594
|
+
],
|
|
6595
|
+
status: "shipped"
|
|
6596
|
+
},
|
|
6227
6597
|
{
|
|
6228
6598
|
name: "pr create",
|
|
6229
6599
|
description: "Open a pull request after full brief-schema validation",
|
|
@@ -6368,6 +6738,30 @@ var COMMANDS = [
|
|
|
6368
6738
|
],
|
|
6369
6739
|
status: "shipped"
|
|
6370
6740
|
},
|
|
6741
|
+
{
|
|
6742
|
+
name: "log export-artifact",
|
|
6743
|
+
description: "Copy this run's own local outbox into a file, for the generated task-path workflow's own upload step",
|
|
6744
|
+
flags: [],
|
|
6745
|
+
details: [
|
|
6746
|
+
"Concatenates every `*.ndjson` file under `~/.vinaya/outbox/` into `<dest>`, verbatim — no filtering, no second redaction pass (lines are already redacted at `log()`'s own write boundary). Writes nothing when the outbox is empty, and exits 0 either way: no gate events this run is a legitimate outcome, never a failure.",
|
|
6747
|
+
"Runs inside the generated `vinaya-checks.yml` job, which holds no forge-write credential — this command never calls the forge. Both this step and the `actions/upload-artifact` step after it run `if: always()`, so a cancelled or failed job still exports whatever partial outbox it has."
|
|
6748
|
+
],
|
|
6749
|
+
status: "shipped"
|
|
6750
|
+
},
|
|
6751
|
+
{
|
|
6752
|
+
name: "log collect-artifact",
|
|
6753
|
+
description: "Validate a downloaded task-log artifact and publish the valid records through the existing flush path",
|
|
6754
|
+
flags: [
|
|
6755
|
+
{ flag: "--pr", description: "The pull request this artifact belongs to" },
|
|
6756
|
+
{ flag: "--repo", description: "Expected `owner/repo` — a provenance cross-check against each record" }
|
|
6757
|
+
],
|
|
6758
|
+
details: [
|
|
6759
|
+
"Runs inside the generated `vinaya-task-log-collector.yml` workflow — a `workflow_run`-triggered job on the default branch, holding the write credential the task-path job that produced the artifact never gets. `<path>` is already downloaded by that workflow, scoped to a specific, API-verified run id — a provenance guarantee this command never re-derives from the artifact bytes.",
|
|
6760
|
+
"Never executes, imports, or evaluates the artifact's content: every line is read as text and validated (schema, an 8 MiB whole-artifact size cap, redaction, and a repo cross-check) before anything is trusted. A rejected line becomes a named gap — printed, never a silent drop — and the artifact is never partially trusted past that check into executing anything.",
|
|
6761
|
+
"The valid, re-redacted survivors are appended into the same local outbox `vinaya log flush` would read for that PR's Issue, then published through the existing `flushOutbox` unmodified — reusing its chunking, its `<!-- aeg:log:… -->` marker, and its idempotent-retry read, rather than a second publisher. A retried collector run (a fresh runner, the same forge state) therefore dedupes for free: the marker already on the forge is acknowledged, never re-posted."
|
|
6762
|
+
],
|
|
6763
|
+
status: "shipped"
|
|
6764
|
+
},
|
|
6371
6765
|
{
|
|
6372
6766
|
name: "milestone create",
|
|
6373
6767
|
description: "Create a GitHub Milestone from a validated body",
|
|
@@ -7430,6 +7824,252 @@ function coreCheckRegistry() {
|
|
|
7430
7824
|
}
|
|
7431
7825
|
var CORE_CHECK_RING = Object.fromEntries(REGISTRY.map(([spec, ring]) => [spec.name, ring]));
|
|
7432
7826
|
|
|
7827
|
+
// src/lib/log-sink.ts
|
|
7828
|
+
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
7829
|
+
import { randomUUID } from "node:crypto";
|
|
7830
|
+
import {
|
|
7831
|
+
closeSync as closeSync2,
|
|
7832
|
+
constants as fsConstants2,
|
|
7833
|
+
existsSync as existsSync4,
|
|
7834
|
+
fstatSync as fstatSync2,
|
|
7835
|
+
mkdirSync as mkdirSync2,
|
|
7836
|
+
openSync as openSync2,
|
|
7837
|
+
readFileSync as readFileSync3,
|
|
7838
|
+
renameSync,
|
|
7839
|
+
writeSync
|
|
7840
|
+
} from "node:fs";
|
|
7841
|
+
import { hostname as osHostname, homedir as homedir2 } from "node:os";
|
|
7842
|
+
import { dirname as dirname3, join as join4 } from "node:path";
|
|
7843
|
+
var OUTBOX_MAX_BYTES = 8 * 1024 * 1024;
|
|
7844
|
+
function isEnoent(err) {
|
|
7845
|
+
return typeof err === "object" && err !== null && err.code === "ENOENT";
|
|
7846
|
+
}
|
|
7847
|
+
function resolveDoctrine(cwd, vinayaVersion) {
|
|
7848
|
+
let toplevel;
|
|
7849
|
+
try {
|
|
7850
|
+
toplevel = execFileSync5("git", ["-C", cwd, "rev-parse", "--show-toplevel"], {
|
|
7851
|
+
encoding: "utf8",
|
|
7852
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
7853
|
+
}).trim();
|
|
7854
|
+
} catch (err) {
|
|
7855
|
+
return isEnoent(err) ? "unknown" : vinayaVersion;
|
|
7856
|
+
}
|
|
7857
|
+
if (!existsSync4(join4(toplevel, "aeg-root", "roles")))
|
|
7858
|
+
return vinayaVersion;
|
|
7859
|
+
try {
|
|
7860
|
+
const sha = execFileSync5("git", ["-C", toplevel, "rev-parse", "HEAD:aeg-root"], {
|
|
7861
|
+
encoding: "utf8",
|
|
7862
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
7863
|
+
}).trim();
|
|
7864
|
+
return `aeg-root@${sha}`;
|
|
7865
|
+
} catch {
|
|
7866
|
+
return vinayaVersion;
|
|
7867
|
+
}
|
|
7868
|
+
}
|
|
7869
|
+
function readVinayaVersion() {
|
|
7870
|
+
try {
|
|
7871
|
+
const pkg = JSON.parse(readFileSync3(join4(packageRoot(import.meta.url), "package.json"), "utf8"));
|
|
7872
|
+
return pkg.version ?? "unknown";
|
|
7873
|
+
} catch {
|
|
7874
|
+
return "unknown";
|
|
7875
|
+
}
|
|
7876
|
+
}
|
|
7877
|
+
var SAFE_PATH_SEGMENT = /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/;
|
|
7878
|
+
function isSafeRepoSegment(segment) {
|
|
7879
|
+
return SAFE_PATH_SEGMENT.test(segment) && !segment.includes("..");
|
|
7880
|
+
}
|
|
7881
|
+
function outboxPathFor(deps, repo, issue) {
|
|
7882
|
+
const dirName = repo ? `${repo.owner}-${repo.repo}` : "unresolved";
|
|
7883
|
+
const fileName = `${issue ?? "none"}.ndjson`;
|
|
7884
|
+
return join4(deps.outboxRoot(), dirName, fileName);
|
|
7885
|
+
}
|
|
7886
|
+
function hostFromEnv(env) {
|
|
7887
|
+
if (env.GITHUB_ACTIONS)
|
|
7888
|
+
return "ci";
|
|
7889
|
+
if (env.VINAYA_HOST === "hook")
|
|
7890
|
+
return "hook";
|
|
7891
|
+
if (env.VINAYA_HOST === "loop")
|
|
7892
|
+
return "loop";
|
|
7893
|
+
return "cli";
|
|
7894
|
+
}
|
|
7895
|
+
function defaultDeps() {
|
|
7896
|
+
return {
|
|
7897
|
+
outboxRoot: () => join4(GLOBAL_VINAYA_HOME, "outbox"),
|
|
7898
|
+
home: () => homedir2(),
|
|
7899
|
+
hostname: () => osHostname(),
|
|
7900
|
+
cwd: () => process.cwd(),
|
|
7901
|
+
now: () => new Date,
|
|
7902
|
+
env: () => process.env,
|
|
7903
|
+
resolveRepo: () => resolveRepo(),
|
|
7904
|
+
vinayaVersion: () => readVinayaVersion(),
|
|
7905
|
+
stderr: (message) => {
|
|
7906
|
+
process.stderr.write(message);
|
|
7907
|
+
},
|
|
7908
|
+
inputVersions: () => {
|
|
7909
|
+
return;
|
|
7910
|
+
}
|
|
7911
|
+
};
|
|
7912
|
+
}
|
|
7913
|
+
var APPEND_OPEN_FLAGS = fsConstants2.O_WRONLY | fsConstants2.O_APPEND | fsConstants2.O_CREAT | fsConstants2.O_NOFOLLOW | fsConstants2.O_NONBLOCK;
|
|
7914
|
+
function guardedAppendOpen(path) {
|
|
7915
|
+
try {
|
|
7916
|
+
return openSync2(path, APPEND_OPEN_FLAGS, 384);
|
|
7917
|
+
} catch {
|
|
7918
|
+
return;
|
|
7919
|
+
}
|
|
7920
|
+
}
|
|
7921
|
+
function reportRotationOverflow(backupPath, warn) {
|
|
7922
|
+
let raw;
|
|
7923
|
+
try {
|
|
7924
|
+
raw = readFileSync3(backupPath, "utf8");
|
|
7925
|
+
} catch {
|
|
7926
|
+
return;
|
|
7927
|
+
}
|
|
7928
|
+
const lines = raw.split(`
|
|
7929
|
+
`).filter((l) => l.length > 0);
|
|
7930
|
+
if (lines.length === 0)
|
|
7931
|
+
return;
|
|
7932
|
+
const droppedIdentities = lines.map((line, i) => {
|
|
7933
|
+
try {
|
|
7934
|
+
return recordIdentity(JSON.parse(line)) ?? `unreadable:${i}`;
|
|
7935
|
+
} catch {
|
|
7936
|
+
return `unreadable:${i}`;
|
|
7937
|
+
}
|
|
7938
|
+
});
|
|
7939
|
+
const diagnostic = { reason: "capacity", dropped: droppedIdentities.length, droppedIdentities };
|
|
7940
|
+
const shown = diagnostic.droppedIdentities.slice(0, 20);
|
|
7941
|
+
const more = diagnostic.dropped > shown.length ? `, +${diagnostic.dropped - shown.length} more` : "";
|
|
7942
|
+
warn(`vinaya: log outbox rotation is overwriting ${backupPath} — ${diagnostic.dropped} record(s) permanently lost: ${shown.join(", ")}${more}
|
|
7943
|
+
`);
|
|
7944
|
+
}
|
|
7945
|
+
function appendLine(path, line, warn) {
|
|
7946
|
+
try {
|
|
7947
|
+
mkdirSync2(dirname3(path), { recursive: true, mode: 448 });
|
|
7948
|
+
let fd = guardedAppendOpen(path);
|
|
7949
|
+
if (fd === undefined) {
|
|
7950
|
+
warn(`vinaya: log outbox target could not be opened (symlink, FIFO, or unwritable) — refusing: ${path}
|
|
7951
|
+
`);
|
|
7952
|
+
return;
|
|
7953
|
+
}
|
|
7954
|
+
let closed = false;
|
|
7955
|
+
try {
|
|
7956
|
+
const stat = fstatSync2(fd);
|
|
7957
|
+
if (!stat.isFile()) {
|
|
7958
|
+
warn(`vinaya: log outbox target is not a regular file — refusing to write: ${path}
|
|
7959
|
+
`);
|
|
7960
|
+
return;
|
|
7961
|
+
}
|
|
7962
|
+
if (stat.size > OUTBOX_MAX_BYTES) {
|
|
7963
|
+
closeSync2(fd);
|
|
7964
|
+
closed = true;
|
|
7965
|
+
const backupPath = path.replace(/\.ndjson$/, ".1.ndjson");
|
|
7966
|
+
reportRotationOverflow(backupPath, warn);
|
|
7967
|
+
renameSync(path, backupPath);
|
|
7968
|
+
const rotated = guardedAppendOpen(path);
|
|
7969
|
+
if (rotated === undefined) {
|
|
7970
|
+
warn(`vinaya: log outbox target could not be reopened after rotation — refusing: ${path}
|
|
7971
|
+
`);
|
|
7972
|
+
return;
|
|
7973
|
+
}
|
|
7974
|
+
fd = rotated;
|
|
7975
|
+
closed = false;
|
|
7976
|
+
}
|
|
7977
|
+
writeSync(fd, line);
|
|
7978
|
+
} finally {
|
|
7979
|
+
if (!closed)
|
|
7980
|
+
closeSync2(fd);
|
|
7981
|
+
}
|
|
7982
|
+
} catch (err) {
|
|
7983
|
+
warn(`vinaya: log outbox write failed — ${err instanceof Error ? err.message : String(err)}
|
|
7984
|
+
`);
|
|
7985
|
+
}
|
|
7986
|
+
}
|
|
7987
|
+
function createLogSink(overrides = {}) {
|
|
7988
|
+
const deps = { ...defaultDeps(), ...overrides };
|
|
7989
|
+
const runId = deps.env().VINAYA_RUN_ID || randomUUID();
|
|
7990
|
+
const processId = randomUUID();
|
|
7991
|
+
let seq = 0;
|
|
7992
|
+
let warned = false;
|
|
7993
|
+
const warnOnce = (message) => {
|
|
7994
|
+
if (warned)
|
|
7995
|
+
return;
|
|
7996
|
+
warned = true;
|
|
7997
|
+
try {
|
|
7998
|
+
deps.stderr(message);
|
|
7999
|
+
} catch {}
|
|
8000
|
+
};
|
|
8001
|
+
let doctrineCache;
|
|
8002
|
+
const doctrine = () => {
|
|
8003
|
+
if (doctrineCache === undefined)
|
|
8004
|
+
doctrineCache = resolveDoctrine(deps.cwd(), deps.vinayaVersion());
|
|
8005
|
+
return doctrineCache;
|
|
8006
|
+
};
|
|
8007
|
+
let resolveRepoCache;
|
|
8008
|
+
const resolveRepoOnce = () => {
|
|
8009
|
+
if (resolveRepoCache === undefined)
|
|
8010
|
+
resolveRepoCache = deps.resolveRepo();
|
|
8011
|
+
return resolveRepoCache;
|
|
8012
|
+
};
|
|
8013
|
+
function log(e) {
|
|
8014
|
+
try {
|
|
8015
|
+
const env = deps.env();
|
|
8016
|
+
const host = hostFromEnv(env);
|
|
8017
|
+
const now = deps.now();
|
|
8018
|
+
const mySeq = seq++;
|
|
8019
|
+
resolveRepoOnce().then((resolved) => {
|
|
8020
|
+
const repo = resolved && isSafeRepoSegment(resolved.owner) && isSafeRepoSegment(resolved.repo) ? resolved : null;
|
|
8021
|
+
const header = buildHeader({
|
|
8022
|
+
now,
|
|
8023
|
+
runId,
|
|
8024
|
+
seq: mySeq,
|
|
8025
|
+
repo: repo ? `${repo.owner}/${repo.repo}` : null,
|
|
8026
|
+
vinaya: deps.vinayaVersion(),
|
|
8027
|
+
doctrine: doctrine(),
|
|
8028
|
+
host,
|
|
8029
|
+
hostname: deps.hostname(),
|
|
8030
|
+
env: {
|
|
8031
|
+
role: env.VINAYA_ROLE,
|
|
8032
|
+
task: env.VINAYA_TASK,
|
|
8033
|
+
round: env.VINAYA_ROUND,
|
|
8034
|
+
run: env.VINAYA_RUN,
|
|
8035
|
+
attempt: env.VINAYA_ATTEMPT,
|
|
8036
|
+
parent: env.VINAYA_PARENT_EVENT
|
|
8037
|
+
},
|
|
8038
|
+
eventId: randomUUID(),
|
|
8039
|
+
processId,
|
|
8040
|
+
inputVersions: deps.inputVersions()
|
|
8041
|
+
});
|
|
8042
|
+
const full = { ...e, ...header };
|
|
8043
|
+
const parsed = LogEventSchema.safeParse(full);
|
|
8044
|
+
if (!parsed.success) {
|
|
8045
|
+
warnOnce(`vinaya: log() refused an invalid payload — ${parsed.error.issues[0]?.message ?? "schema violation"}
|
|
8046
|
+
`);
|
|
8047
|
+
return;
|
|
8048
|
+
}
|
|
8049
|
+
const line = `${JSON.stringify(redact(parsed.data, deps.home()))}
|
|
8050
|
+
`;
|
|
8051
|
+
appendLine(outboxPathFor(deps, repo, header.subject.issue), line, warnOnce);
|
|
8052
|
+
}).catch((err) => {
|
|
8053
|
+
warnOnce(`vinaya: log() failed — ${err instanceof Error ? err.message : String(err)}
|
|
8054
|
+
`);
|
|
8055
|
+
});
|
|
8056
|
+
} catch (err) {
|
|
8057
|
+
warnOnce(`vinaya: log() failed — ${err instanceof Error ? err.message : String(err)}
|
|
8058
|
+
`);
|
|
8059
|
+
}
|
|
8060
|
+
}
|
|
8061
|
+
const warmup = () => {
|
|
8062
|
+
doctrine();
|
|
8063
|
+
const originalWarn = console.warn;
|
|
8064
|
+
console.warn = () => {};
|
|
8065
|
+
resolveRepoOnce().finally(() => {
|
|
8066
|
+
console.warn = originalWarn;
|
|
8067
|
+
});
|
|
8068
|
+
};
|
|
8069
|
+
return { log, runId, warmup };
|
|
8070
|
+
}
|
|
8071
|
+
var defaultSink = createLogSink();
|
|
8072
|
+
|
|
7433
8073
|
// src/checks/contract.ts
|
|
7434
8074
|
var CHECK_SCHEMA_VERSION = 1;
|
|
7435
8075
|
function emitCheckError(error) {
|
|
@@ -7438,7 +8078,7 @@ function emitCheckError(error) {
|
|
|
7438
8078
|
}
|
|
7439
8079
|
|
|
7440
8080
|
// src/checks/runner.ts
|
|
7441
|
-
var
|
|
8081
|
+
var activeChecks = new Map;
|
|
7442
8082
|
|
|
7443
8083
|
// src/lib/forge-write.ts
|
|
7444
8084
|
var INFORMATIONAL_DISPATCH_BLOCKER_CLASSES = new Set([
|
|
@@ -7477,7 +8117,7 @@ function parseChangedLineRanges(diffOutput) {
|
|
|
7477
8117
|
function fileDiffAgainst(ref, path) {
|
|
7478
8118
|
let out;
|
|
7479
8119
|
try {
|
|
7480
|
-
out =
|
|
8120
|
+
out = execFileSync6("git", ["diff", `${ref}...HEAD`, "--", path], {
|
|
7481
8121
|
encoding: "utf8",
|
|
7482
8122
|
stdio: ["ignore", "pipe", "pipe"]
|
|
7483
8123
|
}).trim();
|
|
@@ -7488,7 +8128,7 @@ function fileDiffAgainst(ref, path) {
|
|
|
7488
8128
|
}
|
|
7489
8129
|
function revParse(ref) {
|
|
7490
8130
|
try {
|
|
7491
|
-
return
|
|
8131
|
+
return execFileSync6("git", ["rev-parse", "--verify", ref], {
|
|
7492
8132
|
encoding: "utf8",
|
|
7493
8133
|
stdio: ["ignore", "pipe", "pipe"]
|
|
7494
8134
|
}).trim();
|
|
@@ -7498,7 +8138,7 @@ function revParse(ref) {
|
|
|
7498
8138
|
}
|
|
7499
8139
|
function repoRoot() {
|
|
7500
8140
|
try {
|
|
7501
|
-
return
|
|
8141
|
+
return execFileSync6("git", ["rev-parse", "--show-toplevel"], {
|
|
7502
8142
|
encoding: "utf8",
|
|
7503
8143
|
stdio: ["ignore", "pipe", "pipe"]
|
|
7504
8144
|
}).trim();
|
|
@@ -7509,7 +8149,7 @@ function repoRoot() {
|
|
|
7509
8149
|
function changedFiles(base) {
|
|
7510
8150
|
let out;
|
|
7511
8151
|
try {
|
|
7512
|
-
out =
|
|
8152
|
+
out = execFileSync6("git", ["diff", "--name-only", `${base}...HEAD`], {
|
|
7513
8153
|
encoding: "utf8",
|
|
7514
8154
|
stdio: ["ignore", "pipe", "pipe"]
|
|
7515
8155
|
}).trim();
|
|
@@ -7534,7 +8174,7 @@ function resolveDiff(base = process.env.BASE_SHA || "origin/main") {
|
|
|
7534
8174
|
const relPaths = changedFiles(ref);
|
|
7535
8175
|
if (relPaths === null)
|
|
7536
8176
|
continue;
|
|
7537
|
-
return { base: ref, root, files: relPaths.map((p) =>
|
|
8177
|
+
return { base: ref, root, files: relPaths.map((p) => join5(root, p)) };
|
|
7538
8178
|
}
|
|
7539
8179
|
return null;
|
|
7540
8180
|
}
|
|
@@ -7571,7 +8211,7 @@ var DOCTRINE_ROOT = loadConfig()?.proseGates?.doctrineRoot ?? "aeg-root";
|
|
|
7571
8211
|
var SHIPS_PREFIX2 = `${DOCTRINE_ROOT}/`;
|
|
7572
8212
|
function git2(args) {
|
|
7573
8213
|
try {
|
|
7574
|
-
return
|
|
8214
|
+
return execFileSync7("git", args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
|
|
7575
8215
|
} catch {
|
|
7576
8216
|
return "";
|
|
7577
8217
|
}
|
|
@@ -7584,7 +8224,7 @@ function collectWorkingTree(dir, out = []) {
|
|
|
7584
8224
|
return out;
|
|
7585
8225
|
}
|
|
7586
8226
|
for (const name of entries) {
|
|
7587
|
-
const full =
|
|
8227
|
+
const full = join6(dir, name);
|
|
7588
8228
|
let isDir;
|
|
7589
8229
|
try {
|
|
7590
8230
|
isDir = statSync(full).isDirectory();
|
|
@@ -7602,7 +8242,7 @@ function collectWorkingTree(dir, out = []) {
|
|
|
7602
8242
|
return out;
|
|
7603
8243
|
}
|
|
7604
8244
|
function readWorkingTree(paths) {
|
|
7605
|
-
return paths.map((p) => ({ path: p, content:
|
|
8245
|
+
return paths.map((p) => ({ path: p, content: readFileSync4(p, "utf8") }));
|
|
7606
8246
|
}
|
|
7607
8247
|
function collectAtRef(ref, dir) {
|
|
7608
8248
|
const listing = git2(["ls-tree", "-r", "--name-only", ref, "--", dir]);
|