@attalabs/vinaya 0.16.0 → 0.17.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 +8 -2
- package/aeg-root/contracts/planner-brief.md +1 -1
- package/aeg-root/enforcement.md +2 -2
- package/aeg-root/roles/developer.md +1 -0
- package/aeg-root/roles/planner.md +2 -2
- package/aeg-root/roles/reviewer.md +1 -1
- package/aeg-root/skills/aeg/SKILL.md +1 -1
- package/aeg-root/state-machine.md +1 -1
- package/aeg-root/templates/pr-report-template.md +2 -0
- package/aeg-root/tranche-model.md +1 -1
- package/dist/checks/bin/check-body-bare-digits.js +3545 -0
- package/dist/checks/bin/check-branch-topology.js +72 -6
- package/dist/checks/bin/check-brief-shape.js +72 -6
- package/dist/checks/bin/check-closes-n.js +72 -6
- package/dist/checks/bin/check-coherence.js +77 -7
- package/dist/checks/bin/check-dead-branch-push.js +72 -6
- package/dist/checks/bin/check-dispatch-readiness.js +77 -7
- package/dist/checks/bin/check-doc-coverage-push.js +77 -7
- package/dist/checks/bin/check-doc-coverage.js +80 -11
- package/dist/checks/bin/check-evidence-fresh.js +72 -6
- package/dist/checks/bin/check-first-push-dispatch.js +77 -7
- package/dist/checks/bin/check-issue-assignment.js +72 -6
- package/dist/checks/bin/check-no-disk-state.js +72 -6
- package/dist/checks/bin/check-reader-resolvable-prose.js +72 -6
- package/dist/checks/bin/check-registry-gates.js +72 -6
- package/dist/checks/bin/check-review-gate.js +77 -18
- package/dist/checks/bin/check-single-plan-pr.js +72 -6
- package/dist/checks/bin/check-test-plan.js +72 -6
- package/dist/index.js +591 -206
- 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/required-server-files.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/_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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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]__029-1ch._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0gw1_g2._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0q56ohl._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0rr_lq7._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__19jyp3m._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1_ojzp1._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__1qpl4m_._.js → [root-of-the-server]__1ccgndq._.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1d_8nm4._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1dfzjrd._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1zkwtx8._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__210ehg9._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0-n77dx._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_00yjcv1._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_01605g7._.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/_0rix02i._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_1u3abhy._.js → _0x999pb._.js} +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_0ndy563._.js → _1-6rzip._.js} +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_18-d2be._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_087xa25._.js → _1_talrs._.js} +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_11vnfnm._.js → _1ar5uqe._.js} +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_02drwa_._.js → _1c9b9j-._.js} +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1gw6vc9._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/apps_vinaya-studio_web_src_app_studio_18kqbvs._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/apps_vinaya-studio_web_src_app_studio_projects_[name]_tranches_[slug]_20yap_f._.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_basic_components_index_ts_0xk1vda._.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/{1mexqnauhtbtp.js → 0_jnwbarv-cqk.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0ek6qlqhokys0.js → 0l_vubs1ephe5.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/0ojfbn3yvy-8_.js +1 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1jx5_q1g9l-cm.js → 0phqfqwbnt_ey.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0qcu17x3h94a9.js → 17r0szvqeeyhx.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0ve1-nz-mu_lr.js → 18x3rbqzeutpz.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{22y4d5yrovcv-.js → 1bqpfvromtwn1.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{39w6jbw3rleez.js → 24ojyzmt_fkg3.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0tmcnl-z8yt2_.js → 30lyvn0yzwdiz.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0fm4p9os2lsom.js → 3m0_gk59s-rbx.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0ywkq74falx-x.js → 40x7f5hm7a5tk.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0-08g_jjalnd9.js → 453zhecht_m1q.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/server.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/1s9ixp5nhnevp.js +0 -1
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{R7xvB2iuNFp_jxENpL7xv → p5sWGp4ANwORiaX4Kk6U2}/_buildManifest.js +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{R7xvB2iuNFp_jxENpL7xv → p5sWGp4ANwORiaX4Kk6U2}/_clientMiddlewareManifest.js +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{R7xvB2iuNFp_jxENpL7xv → p5sWGp4ANwORiaX4Kk6U2}/_ssgManifest.js +0 -0
|
@@ -6,7 +6,27 @@ import { promisify as promisify4 } from "node:util";
|
|
|
6
6
|
// ../../packages/aeg-forge-state/src/strip-code.ts
|
|
7
7
|
function maskCode(body) {
|
|
8
8
|
const fill = (line) => " ".repeat(line.length);
|
|
9
|
-
|
|
9
|
+
const blocksMasked = maskIndentedCode(maskFencedCode(body, fill), fill);
|
|
10
|
+
return blocksMasked.split(`
|
|
11
|
+
`).map((line) => replaceInlineSpans(line, (span) => " ".repeat(span.length))).join(`
|
|
12
|
+
`);
|
|
13
|
+
}
|
|
14
|
+
var DETAILS_OPEN = /<details\b[^>]*>/gi;
|
|
15
|
+
var DETAILS_CLOSE = /<\/details\s*>/gi;
|
|
16
|
+
function maskDetailsBlocks(body) {
|
|
17
|
+
const fill = (line) => " ".repeat(line.length);
|
|
18
|
+
const lines = body.split(`
|
|
19
|
+
`);
|
|
20
|
+
let depth = 0;
|
|
21
|
+
const out = lines.map((line) => {
|
|
22
|
+
const opens = line.match(DETAILS_OPEN)?.length ?? 0;
|
|
23
|
+
const closes = line.match(DETAILS_CLOSE)?.length ?? 0;
|
|
24
|
+
const maskThisLine = depth > 0 || opens > 0;
|
|
25
|
+
depth = Math.max(0, depth + opens - closes);
|
|
26
|
+
return maskThisLine ? fill(line) : line;
|
|
27
|
+
});
|
|
28
|
+
return out.join(`
|
|
29
|
+
`);
|
|
10
30
|
}
|
|
11
31
|
function stripCode(body, options = {}) {
|
|
12
32
|
const normalised = body.replace(/\r\n?/g, `
|
|
@@ -15,7 +35,50 @@ function stripCode(body, options = {}) {
|
|
|
15
35
|
const blocksStripped = maskIndentedCode(maskFencedCode(normalised, blank), blank);
|
|
16
36
|
if (options.inlineSpans === "keep")
|
|
17
37
|
return blocksStripped;
|
|
18
|
-
return blocksStripped.
|
|
38
|
+
return blocksStripped.split(`
|
|
39
|
+
`).map((line) => replaceInlineSpans(line, () => "")).join(`
|
|
40
|
+
`);
|
|
41
|
+
}
|
|
42
|
+
function replaceInlineSpans(line, replace) {
|
|
43
|
+
let result = "";
|
|
44
|
+
let i = 0;
|
|
45
|
+
const runLengthAt = (at) => {
|
|
46
|
+
let j = at;
|
|
47
|
+
while (j < line.length && line[j] === "`")
|
|
48
|
+
j++;
|
|
49
|
+
return j - at;
|
|
50
|
+
};
|
|
51
|
+
while (i < line.length) {
|
|
52
|
+
if (line[i] !== "`") {
|
|
53
|
+
result += line[i];
|
|
54
|
+
i++;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const openLen = runLengthAt(i);
|
|
58
|
+
const openEnd = i + openLen;
|
|
59
|
+
let j = openEnd;
|
|
60
|
+
let closeEnd = -1;
|
|
61
|
+
while (j < line.length) {
|
|
62
|
+
if (line[j] !== "`") {
|
|
63
|
+
j++;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const runLen = runLengthAt(j);
|
|
67
|
+
if (runLen === openLen) {
|
|
68
|
+
closeEnd = j + runLen;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
j += runLen;
|
|
72
|
+
}
|
|
73
|
+
if (closeEnd === -1) {
|
|
74
|
+
result += line.slice(i, openEnd);
|
|
75
|
+
i = openEnd;
|
|
76
|
+
} else {
|
|
77
|
+
result += replace(line.slice(i, closeEnd));
|
|
78
|
+
i = closeEnd;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
19
82
|
}
|
|
20
83
|
var FENCE_OPEN = /^ {0,3}(`{3,}|~{3,})([^\r\n]*)\r?$/;
|
|
21
84
|
var FENCE_CLOSE = /^ {0,3}(`+|~+)[ \t]*\r?$/;
|
|
@@ -1754,9 +1817,10 @@ function evaluateC5(changed, docOwnersContent, prBody, fileExists, waiverActive,
|
|
|
1754
1817
|
return out;
|
|
1755
1818
|
}
|
|
1756
1819
|
// ../../packages/aeg-core/src/pr-tier.ts
|
|
1820
|
+
var TIER_FIELD = /(\*\*)?\s*Tier\s*(\*\*)?\s*:\s*(\*\*)?\s*([013])\b/i;
|
|
1757
1821
|
function readTierFromPrBody(prBody) {
|
|
1758
1822
|
const searchIn = anchoredRegion(prBody, "TIER") ?? prBody;
|
|
1759
|
-
const m = searchIn.match(
|
|
1823
|
+
const m = searchIn.match(TIER_FIELD);
|
|
1760
1824
|
if (!m)
|
|
1761
1825
|
return null;
|
|
1762
1826
|
const t = Number(m[4]);
|
|
@@ -2398,9 +2462,6 @@ function extractSecurityReviewVerdict(comments) {
|
|
|
2398
2462
|
return extractVerdict(comments, /^[ \t]*(?:\*{1,3}|_{1,3})?VERDICT:\s*(PASS|FAIL)(?![A-Za-z0-9])/im, "security-review");
|
|
2399
2463
|
}
|
|
2400
2464
|
// ../../packages/aeg-core/src/review-gate.ts
|
|
2401
|
-
function isReviewGateExemptBranch(branch) {
|
|
2402
|
-
return branch.startsWith("plan/");
|
|
2403
|
-
}
|
|
2404
2465
|
function isBoundToHead(extraction, headSha) {
|
|
2405
2466
|
if (!extraction.headSha)
|
|
2406
2467
|
return false;
|
|
@@ -2455,6 +2516,11 @@ function checkReviewGate(input) {
|
|
|
2455
2516
|
waived: false
|
|
2456
2517
|
};
|
|
2457
2518
|
}
|
|
2519
|
+
var CHANGESET_RELEASE_BRANCH = "changeset-release/main";
|
|
2520
|
+
var DEFAULT_RELEASE_ACTOR = "github-actions[bot]";
|
|
2521
|
+
function isChangesetsReleasePr(branch, author, expectedAuthor) {
|
|
2522
|
+
return branch === CHANGESET_RELEASE_BRANCH && author === expectedAuthor;
|
|
2523
|
+
}
|
|
2458
2524
|
// ../../packages/aeg-core/src/markdown-table.ts
|
|
2459
2525
|
function splitRow(line) {
|
|
2460
2526
|
const trimmed = line.trim().replace(/^\|/, "").replace(/\|$/, "");
|
|
@@ -3171,6 +3237,7 @@ var VinayaConfigSchema = z2.object({
|
|
|
3171
3237
|
briefSchema: BriefSchemaSchema.optional(),
|
|
3172
3238
|
managed: ManagedManifestSchema.optional(),
|
|
3173
3239
|
principals: z2.array(z2.string()).min(1).optional(),
|
|
3240
|
+
releaseActor: z2.string().min(1).optional(),
|
|
3174
3241
|
ci: z2.object({ setup: z2.string().min(1) }).optional(),
|
|
3175
3242
|
blastRadius: z2.object({ extraDomains: z2.array(z2.string()).optional() }).optional()
|
|
3176
3243
|
});
|
|
@@ -3180,6 +3247,9 @@ var LOCAL_CONFIG_FILENAME = "vinaya.config.json";
|
|
|
3180
3247
|
function resolvePrincipalAllowlist(config) {
|
|
3181
3248
|
return config?.principals ?? PRINCIPAL_ALLOWLIST;
|
|
3182
3249
|
}
|
|
3250
|
+
function resolveReleaseActor(config) {
|
|
3251
|
+
return config?.releaseActor ?? DEFAULT_RELEASE_ACTOR;
|
|
3252
|
+
}
|
|
3183
3253
|
function trustAnchorRepo() {
|
|
3184
3254
|
const wellFormed = (slug) => /^[^/\s]+\/[^/\s]+$/.test(slug) ? slug : null;
|
|
3185
3255
|
const fromRunner = process.env.GITHUB_REPOSITORY?.trim();
|
|
@@ -3222,7 +3292,7 @@ function isMissingFileError(err) {
|
|
|
3222
3292
|
return /\b404\b|not found/i.test(haystack);
|
|
3223
3293
|
}
|
|
3224
3294
|
function loadTrustAnchorConfig(fetcher = ghFetchTrustAnchorConfig) {
|
|
3225
|
-
const warn = (why) => process.stdout.write(`⚠ could not read \`principals\` from the default branch (${why}) — falling back to vinaya's built-in
|
|
3295
|
+
const warn = (why) => process.stdout.write(`⚠ could not read the trust-anchor config (\`principals\`/\`releaseActor\`) from the default branch (${why}) — falling back to vinaya's built-in defaults.
|
|
3226
3296
|
`);
|
|
3227
3297
|
let base64;
|
|
3228
3298
|
try {
|
|
@@ -6,7 +6,27 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
6
6
|
// ../../packages/aeg-forge-state/src/strip-code.ts
|
|
7
7
|
function maskCode(body) {
|
|
8
8
|
const fill = (line) => " ".repeat(line.length);
|
|
9
|
-
|
|
9
|
+
const blocksMasked = maskIndentedCode(maskFencedCode(body, fill), fill);
|
|
10
|
+
return blocksMasked.split(`
|
|
11
|
+
`).map((line) => replaceInlineSpans(line, (span) => " ".repeat(span.length))).join(`
|
|
12
|
+
`);
|
|
13
|
+
}
|
|
14
|
+
var DETAILS_OPEN = /<details\b[^>]*>/gi;
|
|
15
|
+
var DETAILS_CLOSE = /<\/details\s*>/gi;
|
|
16
|
+
function maskDetailsBlocks(body) {
|
|
17
|
+
const fill = (line) => " ".repeat(line.length);
|
|
18
|
+
const lines = body.split(`
|
|
19
|
+
`);
|
|
20
|
+
let depth = 0;
|
|
21
|
+
const out = lines.map((line) => {
|
|
22
|
+
const opens = line.match(DETAILS_OPEN)?.length ?? 0;
|
|
23
|
+
const closes = line.match(DETAILS_CLOSE)?.length ?? 0;
|
|
24
|
+
const maskThisLine = depth > 0 || opens > 0;
|
|
25
|
+
depth = Math.max(0, depth + opens - closes);
|
|
26
|
+
return maskThisLine ? fill(line) : line;
|
|
27
|
+
});
|
|
28
|
+
return out.join(`
|
|
29
|
+
`);
|
|
10
30
|
}
|
|
11
31
|
function stripCode(body, options = {}) {
|
|
12
32
|
const normalised = body.replace(/\r\n?/g, `
|
|
@@ -15,7 +35,50 @@ function stripCode(body, options = {}) {
|
|
|
15
35
|
const blocksStripped = maskIndentedCode(maskFencedCode(normalised, blank), blank);
|
|
16
36
|
if (options.inlineSpans === "keep")
|
|
17
37
|
return blocksStripped;
|
|
18
|
-
return blocksStripped.
|
|
38
|
+
return blocksStripped.split(`
|
|
39
|
+
`).map((line) => replaceInlineSpans(line, () => "")).join(`
|
|
40
|
+
`);
|
|
41
|
+
}
|
|
42
|
+
function replaceInlineSpans(line, replace) {
|
|
43
|
+
let result = "";
|
|
44
|
+
let i = 0;
|
|
45
|
+
const runLengthAt = (at) => {
|
|
46
|
+
let j = at;
|
|
47
|
+
while (j < line.length && line[j] === "`")
|
|
48
|
+
j++;
|
|
49
|
+
return j - at;
|
|
50
|
+
};
|
|
51
|
+
while (i < line.length) {
|
|
52
|
+
if (line[i] !== "`") {
|
|
53
|
+
result += line[i];
|
|
54
|
+
i++;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const openLen = runLengthAt(i);
|
|
58
|
+
const openEnd = i + openLen;
|
|
59
|
+
let j = openEnd;
|
|
60
|
+
let closeEnd = -1;
|
|
61
|
+
while (j < line.length) {
|
|
62
|
+
if (line[j] !== "`") {
|
|
63
|
+
j++;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const runLen = runLengthAt(j);
|
|
67
|
+
if (runLen === openLen) {
|
|
68
|
+
closeEnd = j + runLen;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
j += runLen;
|
|
72
|
+
}
|
|
73
|
+
if (closeEnd === -1) {
|
|
74
|
+
result += line.slice(i, openEnd);
|
|
75
|
+
i = openEnd;
|
|
76
|
+
} else {
|
|
77
|
+
result += replace(line.slice(i, closeEnd));
|
|
78
|
+
i = closeEnd;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
19
82
|
}
|
|
20
83
|
var FENCE_OPEN = /^ {0,3}(`{3,}|~{3,})([^\r\n]*)\r?$/;
|
|
21
84
|
var FENCE_CLOSE = /^ {0,3}(`+|~+)[ \t]*\r?$/;
|
|
@@ -1754,9 +1817,10 @@ function evaluateC5(changed, docOwnersContent, prBody, fileExists, waiverActive,
|
|
|
1754
1817
|
return out;
|
|
1755
1818
|
}
|
|
1756
1819
|
// ../../packages/aeg-core/src/pr-tier.ts
|
|
1820
|
+
var TIER_FIELD = /(\*\*)?\s*Tier\s*(\*\*)?\s*:\s*(\*\*)?\s*([013])\b/i;
|
|
1757
1821
|
function readTierFromPrBody(prBody) {
|
|
1758
1822
|
const searchIn = anchoredRegion(prBody, "TIER") ?? prBody;
|
|
1759
|
-
const m = searchIn.match(
|
|
1823
|
+
const m = searchIn.match(TIER_FIELD);
|
|
1760
1824
|
if (!m)
|
|
1761
1825
|
return null;
|
|
1762
1826
|
const t = Number(m[4]);
|
|
@@ -2398,9 +2462,6 @@ function extractSecurityReviewVerdict(comments) {
|
|
|
2398
2462
|
return extractVerdict(comments, /^[ \t]*(?:\*{1,3}|_{1,3})?VERDICT:\s*(PASS|FAIL)(?![A-Za-z0-9])/im, "security-review");
|
|
2399
2463
|
}
|
|
2400
2464
|
// ../../packages/aeg-core/src/review-gate.ts
|
|
2401
|
-
function isReviewGateExemptBranch(branch) {
|
|
2402
|
-
return branch.startsWith("plan/");
|
|
2403
|
-
}
|
|
2404
2465
|
function isBoundToHead(extraction, headSha) {
|
|
2405
2466
|
if (!extraction.headSha)
|
|
2406
2467
|
return false;
|
|
@@ -2455,6 +2516,11 @@ function checkReviewGate(input) {
|
|
|
2455
2516
|
waived: false
|
|
2456
2517
|
};
|
|
2457
2518
|
}
|
|
2519
|
+
var CHANGESET_RELEASE_BRANCH = "changeset-release/main";
|
|
2520
|
+
var DEFAULT_RELEASE_ACTOR = "github-actions[bot]";
|
|
2521
|
+
function isChangesetsReleasePr(branch, author, expectedAuthor) {
|
|
2522
|
+
return branch === CHANGESET_RELEASE_BRANCH && author === expectedAuthor;
|
|
2523
|
+
}
|
|
2458
2524
|
// ../../packages/aeg-core/src/markdown-table.ts
|
|
2459
2525
|
function splitRow(line) {
|
|
2460
2526
|
const trimmed = line.trim().replace(/^\|/, "").replace(/\|$/, "");
|
|
@@ -3172,6 +3238,7 @@ var VinayaConfigSchema = z.object({
|
|
|
3172
3238
|
briefSchema: BriefSchemaSchema.optional(),
|
|
3173
3239
|
managed: ManagedManifestSchema.optional(),
|
|
3174
3240
|
principals: z.array(z.string()).min(1).optional(),
|
|
3241
|
+
releaseActor: z.string().min(1).optional(),
|
|
3175
3242
|
ci: z.object({ setup: z.string().min(1) }).optional(),
|
|
3176
3243
|
blastRadius: z.object({ extraDomains: z.array(z.string()).optional() }).optional()
|
|
3177
3244
|
});
|
|
@@ -3181,6 +3248,9 @@ var LOCAL_CONFIG_FILENAME = "vinaya.config.json";
|
|
|
3181
3248
|
function resolvePrincipalAllowlist(config) {
|
|
3182
3249
|
return config?.principals ?? PRINCIPAL_ALLOWLIST;
|
|
3183
3250
|
}
|
|
3251
|
+
function resolveReleaseActor(config) {
|
|
3252
|
+
return config?.releaseActor ?? DEFAULT_RELEASE_ACTOR;
|
|
3253
|
+
}
|
|
3184
3254
|
function trustAnchorRepo() {
|
|
3185
3255
|
const wellFormed = (slug) => /^[^/\s]+\/[^/\s]+$/.test(slug) ? slug : null;
|
|
3186
3256
|
const fromRunner = process.env.GITHUB_REPOSITORY?.trim();
|
|
@@ -3223,7 +3293,7 @@ function isMissingFileError(err) {
|
|
|
3223
3293
|
return /\b404\b|not found/i.test(haystack);
|
|
3224
3294
|
}
|
|
3225
3295
|
function loadTrustAnchorConfig(fetcher = ghFetchTrustAnchorConfig) {
|
|
3226
|
-
const warn = (why) => process.stdout.write(`⚠ could not read \`principals\` from the default branch (${why}) — falling back to vinaya's built-in
|
|
3296
|
+
const warn = (why) => process.stdout.write(`⚠ could not read the trust-anchor config (\`principals\`/\`releaseActor\`) from the default branch (${why}) — falling back to vinaya's built-in defaults.
|
|
3227
3297
|
`);
|
|
3228
3298
|
let base64;
|
|
3229
3299
|
try {
|
|
@@ -1,13 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// @bun
|
|
3
2
|
|
|
4
3
|
// src/checks/bin/check-doc-coverage.ts
|
|
5
|
-
import { execFileSync as execFileSync4 } from "child_process";
|
|
6
|
-
import { existsSync, readFileSync } from "fs";
|
|
4
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
5
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
7
6
|
// ../../packages/aeg-forge-state/src/strip-code.ts
|
|
8
7
|
function maskCode(body) {
|
|
9
8
|
const fill = (line) => " ".repeat(line.length);
|
|
10
|
-
|
|
9
|
+
const blocksMasked = maskIndentedCode(maskFencedCode(body, fill), fill);
|
|
10
|
+
return blocksMasked.split(`
|
|
11
|
+
`).map((line) => replaceInlineSpans(line, (span) => " ".repeat(span.length))).join(`
|
|
12
|
+
`);
|
|
13
|
+
}
|
|
14
|
+
var DETAILS_OPEN = /<details\b[^>]*>/gi;
|
|
15
|
+
var DETAILS_CLOSE = /<\/details\s*>/gi;
|
|
16
|
+
function maskDetailsBlocks(body) {
|
|
17
|
+
const fill = (line) => " ".repeat(line.length);
|
|
18
|
+
const lines = body.split(`
|
|
19
|
+
`);
|
|
20
|
+
let depth = 0;
|
|
21
|
+
const out = lines.map((line) => {
|
|
22
|
+
const opens = line.match(DETAILS_OPEN)?.length ?? 0;
|
|
23
|
+
const closes = line.match(DETAILS_CLOSE)?.length ?? 0;
|
|
24
|
+
const maskThisLine = depth > 0 || opens > 0;
|
|
25
|
+
depth = Math.max(0, depth + opens - closes);
|
|
26
|
+
return maskThisLine ? fill(line) : line;
|
|
27
|
+
});
|
|
28
|
+
return out.join(`
|
|
29
|
+
`);
|
|
11
30
|
}
|
|
12
31
|
function stripCode(body, options = {}) {
|
|
13
32
|
const normalised = body.replace(/\r\n?/g, `
|
|
@@ -16,7 +35,50 @@ function stripCode(body, options = {}) {
|
|
|
16
35
|
const blocksStripped = maskIndentedCode(maskFencedCode(normalised, blank), blank);
|
|
17
36
|
if (options.inlineSpans === "keep")
|
|
18
37
|
return blocksStripped;
|
|
19
|
-
return blocksStripped.
|
|
38
|
+
return blocksStripped.split(`
|
|
39
|
+
`).map((line) => replaceInlineSpans(line, () => "")).join(`
|
|
40
|
+
`);
|
|
41
|
+
}
|
|
42
|
+
function replaceInlineSpans(line, replace) {
|
|
43
|
+
let result = "";
|
|
44
|
+
let i = 0;
|
|
45
|
+
const runLengthAt = (at) => {
|
|
46
|
+
let j = at;
|
|
47
|
+
while (j < line.length && line[j] === "`")
|
|
48
|
+
j++;
|
|
49
|
+
return j - at;
|
|
50
|
+
};
|
|
51
|
+
while (i < line.length) {
|
|
52
|
+
if (line[i] !== "`") {
|
|
53
|
+
result += line[i];
|
|
54
|
+
i++;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const openLen = runLengthAt(i);
|
|
58
|
+
const openEnd = i + openLen;
|
|
59
|
+
let j = openEnd;
|
|
60
|
+
let closeEnd = -1;
|
|
61
|
+
while (j < line.length) {
|
|
62
|
+
if (line[j] !== "`") {
|
|
63
|
+
j++;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const runLen = runLengthAt(j);
|
|
67
|
+
if (runLen === openLen) {
|
|
68
|
+
closeEnd = j + runLen;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
j += runLen;
|
|
72
|
+
}
|
|
73
|
+
if (closeEnd === -1) {
|
|
74
|
+
result += line.slice(i, openEnd);
|
|
75
|
+
i = openEnd;
|
|
76
|
+
} else {
|
|
77
|
+
result += replace(line.slice(i, closeEnd));
|
|
78
|
+
i = closeEnd;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
20
82
|
}
|
|
21
83
|
var FENCE_OPEN = /^ {0,3}(`{3,}|~{3,})([^\r\n]*)\r?$/;
|
|
22
84
|
var FENCE_CLOSE = /^ {0,3}(`+|~+)[ \t]*\r?$/;
|
|
@@ -1755,9 +1817,10 @@ function evaluateC5(changed, docOwnersContent, prBody, fileExists, waiverActive,
|
|
|
1755
1817
|
return out;
|
|
1756
1818
|
}
|
|
1757
1819
|
// ../../packages/aeg-core/src/pr-tier.ts
|
|
1820
|
+
var TIER_FIELD = /(\*\*)?\s*Tier\s*(\*\*)?\s*:\s*(\*\*)?\s*([013])\b/i;
|
|
1758
1821
|
function readTierFromPrBody(prBody) {
|
|
1759
1822
|
const searchIn = anchoredRegion(prBody, "TIER") ?? prBody;
|
|
1760
|
-
const m = searchIn.match(
|
|
1823
|
+
const m = searchIn.match(TIER_FIELD);
|
|
1761
1824
|
if (!m)
|
|
1762
1825
|
return null;
|
|
1763
1826
|
const t = Number(m[4]);
|
|
@@ -2399,9 +2462,6 @@ function extractSecurityReviewVerdict(comments) {
|
|
|
2399
2462
|
return extractVerdict(comments, /^[ \t]*(?:\*{1,3}|_{1,3})?VERDICT:\s*(PASS|FAIL)(?![A-Za-z0-9])/im, "security-review");
|
|
2400
2463
|
}
|
|
2401
2464
|
// ../../packages/aeg-core/src/review-gate.ts
|
|
2402
|
-
function isReviewGateExemptBranch(branch) {
|
|
2403
|
-
return branch.startsWith("plan/");
|
|
2404
|
-
}
|
|
2405
2465
|
function isBoundToHead(extraction, headSha) {
|
|
2406
2466
|
if (!extraction.headSha)
|
|
2407
2467
|
return false;
|
|
@@ -2456,6 +2516,11 @@ function checkReviewGate(input) {
|
|
|
2456
2516
|
waived: false
|
|
2457
2517
|
};
|
|
2458
2518
|
}
|
|
2519
|
+
var CHANGESET_RELEASE_BRANCH = "changeset-release/main";
|
|
2520
|
+
var DEFAULT_RELEASE_ACTOR = "github-actions[bot]";
|
|
2521
|
+
function isChangesetsReleasePr(branch, author, expectedAuthor) {
|
|
2522
|
+
return branch === CHANGESET_RELEASE_BRANCH && author === expectedAuthor;
|
|
2523
|
+
}
|
|
2459
2524
|
// ../../packages/aeg-core/src/markdown-table.ts
|
|
2460
2525
|
function splitRow(line) {
|
|
2461
2526
|
const trimmed = line.trim().replace(/^\|/, "").replace(/\|$/, "");
|
|
@@ -3173,6 +3238,7 @@ var VinayaConfigSchema = z.object({
|
|
|
3173
3238
|
briefSchema: BriefSchemaSchema.optional(),
|
|
3174
3239
|
managed: ManagedManifestSchema.optional(),
|
|
3175
3240
|
principals: z.array(z.string()).min(1).optional(),
|
|
3241
|
+
releaseActor: z.string().min(1).optional(),
|
|
3176
3242
|
ci: z.object({ setup: z.string().min(1) }).optional(),
|
|
3177
3243
|
blastRadius: z.object({ extraDomains: z.array(z.string()).optional() }).optional()
|
|
3178
3244
|
});
|
|
@@ -3182,6 +3248,9 @@ var LOCAL_CONFIG_FILENAME = "vinaya.config.json";
|
|
|
3182
3248
|
function resolvePrincipalAllowlist(config) {
|
|
3183
3249
|
return config?.principals ?? PRINCIPAL_ALLOWLIST;
|
|
3184
3250
|
}
|
|
3251
|
+
function resolveReleaseActor(config) {
|
|
3252
|
+
return config?.releaseActor ?? DEFAULT_RELEASE_ACTOR;
|
|
3253
|
+
}
|
|
3185
3254
|
function trustAnchorRepo() {
|
|
3186
3255
|
const wellFormed = (slug) => /^[^/\s]+\/[^/\s]+$/.test(slug) ? slug : null;
|
|
3187
3256
|
const fromRunner = process.env.GITHUB_REPOSITORY?.trim();
|
|
@@ -3224,7 +3293,7 @@ function isMissingFileError(err) {
|
|
|
3224
3293
|
return /\b404\b|not found/i.test(haystack);
|
|
3225
3294
|
}
|
|
3226
3295
|
function loadTrustAnchorConfig(fetcher = ghFetchTrustAnchorConfig) {
|
|
3227
|
-
const warn = (why) => process.stdout.write(`⚠ could not read \`principals\` from the default branch (${why}) — falling back to vinaya's built-in
|
|
3296
|
+
const warn = (why) => process.stdout.write(`⚠ could not read the trust-anchor config (\`principals\`/\`releaseActor\`) from the default branch (${why}) — falling back to vinaya's built-in defaults.
|
|
3228
3297
|
`);
|
|
3229
3298
|
let base64;
|
|
3230
3299
|
try {
|
|
@@ -3334,7 +3403,7 @@ function main() {
|
|
|
3334
3403
|
check: CHECK_NAME,
|
|
3335
3404
|
severity: "error",
|
|
3336
3405
|
message,
|
|
3337
|
-
agent_recovery_prompt: "Read the doc pointer named in the finding above, apply the change your code edit implies, and commit both " + "files in this PR. If the doc genuinely does not need updating, ask a principal to apply the `vinaya/waiver:docs` " + "label rather than editing around this finding
|
|
3406
|
+
agent_recovery_prompt: "Read the doc pointer named in the finding above, apply the change your code edit implies, and commit both " + "files in this PR. If the doc genuinely does not need updating, ask a principal to apply the `vinaya/waiver:docs` " + "label rather than editing around this finding — you cannot self-serve that waiver."
|
|
3338
3407
|
});
|
|
3339
3408
|
}
|
|
3340
3409
|
process.exit(1);
|
|
@@ -5,7 +5,27 @@ import { execFileSync as execFileSync2 } from "node:child_process";
|
|
|
5
5
|
// ../../packages/aeg-forge-state/src/strip-code.ts
|
|
6
6
|
function maskCode(body) {
|
|
7
7
|
const fill = (line) => " ".repeat(line.length);
|
|
8
|
-
|
|
8
|
+
const blocksMasked = maskIndentedCode(maskFencedCode(body, fill), fill);
|
|
9
|
+
return blocksMasked.split(`
|
|
10
|
+
`).map((line) => replaceInlineSpans(line, (span) => " ".repeat(span.length))).join(`
|
|
11
|
+
`);
|
|
12
|
+
}
|
|
13
|
+
var DETAILS_OPEN = /<details\b[^>]*>/gi;
|
|
14
|
+
var DETAILS_CLOSE = /<\/details\s*>/gi;
|
|
15
|
+
function maskDetailsBlocks(body) {
|
|
16
|
+
const fill = (line) => " ".repeat(line.length);
|
|
17
|
+
const lines = body.split(`
|
|
18
|
+
`);
|
|
19
|
+
let depth = 0;
|
|
20
|
+
const out = lines.map((line) => {
|
|
21
|
+
const opens = line.match(DETAILS_OPEN)?.length ?? 0;
|
|
22
|
+
const closes = line.match(DETAILS_CLOSE)?.length ?? 0;
|
|
23
|
+
const maskThisLine = depth > 0 || opens > 0;
|
|
24
|
+
depth = Math.max(0, depth + opens - closes);
|
|
25
|
+
return maskThisLine ? fill(line) : line;
|
|
26
|
+
});
|
|
27
|
+
return out.join(`
|
|
28
|
+
`);
|
|
9
29
|
}
|
|
10
30
|
function stripCode(body, options = {}) {
|
|
11
31
|
const normalised = body.replace(/\r\n?/g, `
|
|
@@ -14,7 +34,50 @@ function stripCode(body, options = {}) {
|
|
|
14
34
|
const blocksStripped = maskIndentedCode(maskFencedCode(normalised, blank), blank);
|
|
15
35
|
if (options.inlineSpans === "keep")
|
|
16
36
|
return blocksStripped;
|
|
17
|
-
return blocksStripped.
|
|
37
|
+
return blocksStripped.split(`
|
|
38
|
+
`).map((line) => replaceInlineSpans(line, () => "")).join(`
|
|
39
|
+
`);
|
|
40
|
+
}
|
|
41
|
+
function replaceInlineSpans(line, replace) {
|
|
42
|
+
let result = "";
|
|
43
|
+
let i = 0;
|
|
44
|
+
const runLengthAt = (at) => {
|
|
45
|
+
let j = at;
|
|
46
|
+
while (j < line.length && line[j] === "`")
|
|
47
|
+
j++;
|
|
48
|
+
return j - at;
|
|
49
|
+
};
|
|
50
|
+
while (i < line.length) {
|
|
51
|
+
if (line[i] !== "`") {
|
|
52
|
+
result += line[i];
|
|
53
|
+
i++;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const openLen = runLengthAt(i);
|
|
57
|
+
const openEnd = i + openLen;
|
|
58
|
+
let j = openEnd;
|
|
59
|
+
let closeEnd = -1;
|
|
60
|
+
while (j < line.length) {
|
|
61
|
+
if (line[j] !== "`") {
|
|
62
|
+
j++;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const runLen = runLengthAt(j);
|
|
66
|
+
if (runLen === openLen) {
|
|
67
|
+
closeEnd = j + runLen;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
j += runLen;
|
|
71
|
+
}
|
|
72
|
+
if (closeEnd === -1) {
|
|
73
|
+
result += line.slice(i, openEnd);
|
|
74
|
+
i = openEnd;
|
|
75
|
+
} else {
|
|
76
|
+
result += replace(line.slice(i, closeEnd));
|
|
77
|
+
i = closeEnd;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
18
81
|
}
|
|
19
82
|
var FENCE_OPEN = /^ {0,3}(`{3,}|~{3,})([^\r\n]*)\r?$/;
|
|
20
83
|
var FENCE_CLOSE = /^ {0,3}(`+|~+)[ \t]*\r?$/;
|
|
@@ -1753,9 +1816,10 @@ function evaluateC5(changed, docOwnersContent, prBody, fileExists, waiverActive,
|
|
|
1753
1816
|
return out;
|
|
1754
1817
|
}
|
|
1755
1818
|
// ../../packages/aeg-core/src/pr-tier.ts
|
|
1819
|
+
var TIER_FIELD = /(\*\*)?\s*Tier\s*(\*\*)?\s*:\s*(\*\*)?\s*([013])\b/i;
|
|
1756
1820
|
function readTierFromPrBody(prBody) {
|
|
1757
1821
|
const searchIn = anchoredRegion(prBody, "TIER") ?? prBody;
|
|
1758
|
-
const m = searchIn.match(
|
|
1822
|
+
const m = searchIn.match(TIER_FIELD);
|
|
1759
1823
|
if (!m)
|
|
1760
1824
|
return null;
|
|
1761
1825
|
const t = Number(m[4]);
|
|
@@ -2397,9 +2461,6 @@ function extractSecurityReviewVerdict(comments) {
|
|
|
2397
2461
|
return extractVerdict(comments, /^[ \t]*(?:\*{1,3}|_{1,3})?VERDICT:\s*(PASS|FAIL)(?![A-Za-z0-9])/im, "security-review");
|
|
2398
2462
|
}
|
|
2399
2463
|
// ../../packages/aeg-core/src/review-gate.ts
|
|
2400
|
-
function isReviewGateExemptBranch(branch) {
|
|
2401
|
-
return branch.startsWith("plan/");
|
|
2402
|
-
}
|
|
2403
2464
|
function isBoundToHead(extraction, headSha) {
|
|
2404
2465
|
if (!extraction.headSha)
|
|
2405
2466
|
return false;
|
|
@@ -2454,6 +2515,11 @@ function checkReviewGate(input) {
|
|
|
2454
2515
|
waived: false
|
|
2455
2516
|
};
|
|
2456
2517
|
}
|
|
2518
|
+
var CHANGESET_RELEASE_BRANCH = "changeset-release/main";
|
|
2519
|
+
var DEFAULT_RELEASE_ACTOR = "github-actions[bot]";
|
|
2520
|
+
function isChangesetsReleasePr(branch, author, expectedAuthor) {
|
|
2521
|
+
return branch === CHANGESET_RELEASE_BRANCH && author === expectedAuthor;
|
|
2522
|
+
}
|
|
2457
2523
|
// ../../packages/aeg-core/src/markdown-table.ts
|
|
2458
2524
|
function splitRow(line) {
|
|
2459
2525
|
const trimmed = line.trim().replace(/^\|/, "").replace(/\|$/, "");
|
|
@@ -5,7 +5,27 @@ import { execFileSync as execFileSync3 } from "node:child_process";
|
|
|
5
5
|
// ../../packages/aeg-forge-state/src/strip-code.ts
|
|
6
6
|
function maskCode(body) {
|
|
7
7
|
const fill = (line) => " ".repeat(line.length);
|
|
8
|
-
|
|
8
|
+
const blocksMasked = maskIndentedCode(maskFencedCode(body, fill), fill);
|
|
9
|
+
return blocksMasked.split(`
|
|
10
|
+
`).map((line) => replaceInlineSpans(line, (span) => " ".repeat(span.length))).join(`
|
|
11
|
+
`);
|
|
12
|
+
}
|
|
13
|
+
var DETAILS_OPEN = /<details\b[^>]*>/gi;
|
|
14
|
+
var DETAILS_CLOSE = /<\/details\s*>/gi;
|
|
15
|
+
function maskDetailsBlocks(body) {
|
|
16
|
+
const fill = (line) => " ".repeat(line.length);
|
|
17
|
+
const lines = body.split(`
|
|
18
|
+
`);
|
|
19
|
+
let depth = 0;
|
|
20
|
+
const out = lines.map((line) => {
|
|
21
|
+
const opens = line.match(DETAILS_OPEN)?.length ?? 0;
|
|
22
|
+
const closes = line.match(DETAILS_CLOSE)?.length ?? 0;
|
|
23
|
+
const maskThisLine = depth > 0 || opens > 0;
|
|
24
|
+
depth = Math.max(0, depth + opens - closes);
|
|
25
|
+
return maskThisLine ? fill(line) : line;
|
|
26
|
+
});
|
|
27
|
+
return out.join(`
|
|
28
|
+
`);
|
|
9
29
|
}
|
|
10
30
|
function stripCode(body, options = {}) {
|
|
11
31
|
const normalised = body.replace(/\r\n?/g, `
|
|
@@ -14,7 +34,50 @@ function stripCode(body, options = {}) {
|
|
|
14
34
|
const blocksStripped = maskIndentedCode(maskFencedCode(normalised, blank), blank);
|
|
15
35
|
if (options.inlineSpans === "keep")
|
|
16
36
|
return blocksStripped;
|
|
17
|
-
return blocksStripped.
|
|
37
|
+
return blocksStripped.split(`
|
|
38
|
+
`).map((line) => replaceInlineSpans(line, () => "")).join(`
|
|
39
|
+
`);
|
|
40
|
+
}
|
|
41
|
+
function replaceInlineSpans(line, replace) {
|
|
42
|
+
let result = "";
|
|
43
|
+
let i = 0;
|
|
44
|
+
const runLengthAt = (at) => {
|
|
45
|
+
let j = at;
|
|
46
|
+
while (j < line.length && line[j] === "`")
|
|
47
|
+
j++;
|
|
48
|
+
return j - at;
|
|
49
|
+
};
|
|
50
|
+
while (i < line.length) {
|
|
51
|
+
if (line[i] !== "`") {
|
|
52
|
+
result += line[i];
|
|
53
|
+
i++;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const openLen = runLengthAt(i);
|
|
57
|
+
const openEnd = i + openLen;
|
|
58
|
+
let j = openEnd;
|
|
59
|
+
let closeEnd = -1;
|
|
60
|
+
while (j < line.length) {
|
|
61
|
+
if (line[j] !== "`") {
|
|
62
|
+
j++;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const runLen = runLengthAt(j);
|
|
66
|
+
if (runLen === openLen) {
|
|
67
|
+
closeEnd = j + runLen;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
j += runLen;
|
|
71
|
+
}
|
|
72
|
+
if (closeEnd === -1) {
|
|
73
|
+
result += line.slice(i, openEnd);
|
|
74
|
+
i = openEnd;
|
|
75
|
+
} else {
|
|
76
|
+
result += replace(line.slice(i, closeEnd));
|
|
77
|
+
i = closeEnd;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
18
81
|
}
|
|
19
82
|
var FENCE_OPEN = /^ {0,3}(`{3,}|~{3,})([^\r\n]*)\r?$/;
|
|
20
83
|
var FENCE_CLOSE = /^ {0,3}(`+|~+)[ \t]*\r?$/;
|
|
@@ -1753,9 +1816,10 @@ function evaluateC5(changed, docOwnersContent, prBody, fileExists, waiverActive,
|
|
|
1753
1816
|
return out;
|
|
1754
1817
|
}
|
|
1755
1818
|
// ../../packages/aeg-core/src/pr-tier.ts
|
|
1819
|
+
var TIER_FIELD = /(\*\*)?\s*Tier\s*(\*\*)?\s*:\s*(\*\*)?\s*([013])\b/i;
|
|
1756
1820
|
function readTierFromPrBody(prBody) {
|
|
1757
1821
|
const searchIn = anchoredRegion(prBody, "TIER") ?? prBody;
|
|
1758
|
-
const m = searchIn.match(
|
|
1822
|
+
const m = searchIn.match(TIER_FIELD);
|
|
1759
1823
|
if (!m)
|
|
1760
1824
|
return null;
|
|
1761
1825
|
const t = Number(m[4]);
|
|
@@ -2397,9 +2461,6 @@ function extractSecurityReviewVerdict(comments) {
|
|
|
2397
2461
|
return extractVerdict(comments, /^[ \t]*(?:\*{1,3}|_{1,3})?VERDICT:\s*(PASS|FAIL)(?![A-Za-z0-9])/im, "security-review");
|
|
2398
2462
|
}
|
|
2399
2463
|
// ../../packages/aeg-core/src/review-gate.ts
|
|
2400
|
-
function isReviewGateExemptBranch(branch) {
|
|
2401
|
-
return branch.startsWith("plan/");
|
|
2402
|
-
}
|
|
2403
2464
|
function isBoundToHead(extraction, headSha) {
|
|
2404
2465
|
if (!extraction.headSha)
|
|
2405
2466
|
return false;
|
|
@@ -2454,6 +2515,11 @@ function checkReviewGate(input) {
|
|
|
2454
2515
|
waived: false
|
|
2455
2516
|
};
|
|
2456
2517
|
}
|
|
2518
|
+
var CHANGESET_RELEASE_BRANCH = "changeset-release/main";
|
|
2519
|
+
var DEFAULT_RELEASE_ACTOR = "github-actions[bot]";
|
|
2520
|
+
function isChangesetsReleasePr(branch, author, expectedAuthor) {
|
|
2521
|
+
return branch === CHANGESET_RELEASE_BRANCH && author === expectedAuthor;
|
|
2522
|
+
}
|
|
2457
2523
|
// ../../packages/aeg-core/src/markdown-table.ts
|
|
2458
2524
|
function splitRow(line) {
|
|
2459
2525
|
const trimmed = line.trim().replace(/^\|/, "").replace(/\|$/, "");
|
|
@@ -3170,6 +3236,7 @@ var VinayaConfigSchema = z2.object({
|
|
|
3170
3236
|
briefSchema: BriefSchemaSchema.optional(),
|
|
3171
3237
|
managed: ManagedManifestSchema.optional(),
|
|
3172
3238
|
principals: z2.array(z2.string()).min(1).optional(),
|
|
3239
|
+
releaseActor: z2.string().min(1).optional(),
|
|
3173
3240
|
ci: z2.object({ setup: z2.string().min(1) }).optional(),
|
|
3174
3241
|
blastRadius: z2.object({ extraDomains: z2.array(z2.string()).optional() }).optional()
|
|
3175
3242
|
});
|
|
@@ -3179,6 +3246,9 @@ var LOCAL_CONFIG_FILENAME = "vinaya.config.json";
|
|
|
3179
3246
|
function resolvePrincipalAllowlist(config) {
|
|
3180
3247
|
return config?.principals ?? PRINCIPAL_ALLOWLIST;
|
|
3181
3248
|
}
|
|
3249
|
+
function resolveReleaseActor(config) {
|
|
3250
|
+
return config?.releaseActor ?? DEFAULT_RELEASE_ACTOR;
|
|
3251
|
+
}
|
|
3182
3252
|
function trustAnchorRepo() {
|
|
3183
3253
|
const wellFormed = (slug) => /^[^/\s]+\/[^/\s]+$/.test(slug) ? slug : null;
|
|
3184
3254
|
const fromRunner = process.env.GITHUB_REPOSITORY?.trim();
|
|
@@ -3221,7 +3291,7 @@ function isMissingFileError(err) {
|
|
|
3221
3291
|
return /\b404\b|not found/i.test(haystack);
|
|
3222
3292
|
}
|
|
3223
3293
|
function loadTrustAnchorConfig(fetcher = ghFetchTrustAnchorConfig) {
|
|
3224
|
-
const warn = (why) => process.stdout.write(`⚠ could not read \`principals\` from the default branch (${why}) — falling back to vinaya's built-in
|
|
3294
|
+
const warn = (why) => process.stdout.write(`⚠ could not read the trust-anchor config (\`principals\`/\`releaseActor\`) from the default branch (${why}) — falling back to vinaya's built-in defaults.
|
|
3225
3295
|
`);
|
|
3226
3296
|
let base64;
|
|
3227
3297
|
try {
|