@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.
Files changed (121) hide show
  1. package/README.md +8 -2
  2. package/aeg-root/contracts/planner-brief.md +1 -1
  3. package/aeg-root/enforcement.md +2 -2
  4. package/aeg-root/roles/developer.md +1 -0
  5. package/aeg-root/roles/planner.md +2 -2
  6. package/aeg-root/roles/reviewer.md +1 -1
  7. package/aeg-root/skills/aeg/SKILL.md +1 -1
  8. package/aeg-root/state-machine.md +1 -1
  9. package/aeg-root/templates/pr-report-template.md +2 -0
  10. package/aeg-root/tranche-model.md +1 -1
  11. package/dist/checks/bin/check-body-bare-digits.js +3545 -0
  12. package/dist/checks/bin/check-branch-topology.js +72 -6
  13. package/dist/checks/bin/check-brief-shape.js +72 -6
  14. package/dist/checks/bin/check-closes-n.js +72 -6
  15. package/dist/checks/bin/check-coherence.js +77 -7
  16. package/dist/checks/bin/check-dead-branch-push.js +72 -6
  17. package/dist/checks/bin/check-dispatch-readiness.js +77 -7
  18. package/dist/checks/bin/check-doc-coverage-push.js +77 -7
  19. package/dist/checks/bin/check-doc-coverage.js +80 -11
  20. package/dist/checks/bin/check-evidence-fresh.js +72 -6
  21. package/dist/checks/bin/check-first-push-dispatch.js +77 -7
  22. package/dist/checks/bin/check-issue-assignment.js +72 -6
  23. package/dist/checks/bin/check-no-disk-state.js +72 -6
  24. package/dist/checks/bin/check-reader-resolvable-prose.js +72 -6
  25. package/dist/checks/bin/check-registry-gates.js +72 -6
  26. package/dist/checks/bin/check-review-gate.js +77 -18
  27. package/dist/checks/bin/check-single-plan-pr.js +72 -6
  28. package/dist/checks/bin/check-test-plan.js +72 -6
  29. package/dist/index.js +591 -206
  30. package/package.json +1 -1
  31. package/studio-standalone/apps/vinaya-studio/web/.next/BUILD_ID +1 -1
  32. package/studio-standalone/apps/vinaya-studio/web/.next/build-manifest.json +3 -3
  33. package/studio-standalone/apps/vinaya-studio/web/.next/prerender-manifest.json +3 -3
  34. package/studio-standalone/apps/vinaya-studio/web/.next/required-server-files.json +1 -1
  35. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.html +1 -1
  36. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.rsc +1 -1
  37. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  38. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  39. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  40. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page/server-reference-manifest.json +2 -2
  41. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  42. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  43. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page/server-reference-manifest.json +2 -2
  44. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page.js.nft.json +1 -1
  45. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page_client-reference-manifest.js +1 -1
  46. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page/server-reference-manifest.json +2 -2
  47. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page.js +1 -1
  48. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page.js.nft.json +1 -1
  49. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page_client-reference-manifest.js +1 -1
  50. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page/server-reference-manifest.json +2 -2
  51. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page.js +1 -1
  52. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page.js.nft.json +1 -1
  53. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page_client-reference-manifest.js +1 -1
  54. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page/server-reference-manifest.json +2 -2
  55. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page.js.nft.json +1 -1
  56. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page_client-reference-manifest.js +1 -1
  57. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page/server-reference-manifest.json +2 -2
  58. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page.js +1 -1
  59. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page.js.nft.json +1 -1
  60. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page_client-reference-manifest.js +1 -1
  61. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page/server-reference-manifest.json +2 -2
  62. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page.js +1 -1
  63. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page.js.nft.json +1 -1
  64. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page_client-reference-manifest.js +1 -1
  65. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page/server-reference-manifest.json +2 -2
  66. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page.js +1 -1
  67. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page.js.nft.json +1 -1
  68. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page_client-reference-manifest.js +1 -1
  69. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page/server-reference-manifest.json +2 -2
  70. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page.js.nft.json +1 -1
  71. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page_client-reference-manifest.js +1 -1
  72. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/1q96_modules_@clerk_nextjs_dist_esm_app-router_client_keyless-creator-reader_0lom2js.js +1 -1
  73. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__029-1ch._.js +1 -1
  74. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0gw1_g2._.js +1 -1
  75. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0q56ohl._.js +1 -1
  76. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0rr_lq7._.js +1 -1
  77. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__19jyp3m._.js +1 -1
  78. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1_ojzp1._.js +1 -1
  79. 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
  80. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1d_8nm4._.js +1 -1
  81. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1dfzjrd._.js +1 -1
  82. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1zkwtx8._.js +1 -1
  83. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__210ehg9._.js +1 -1
  84. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0-n77dx._.js +1 -1
  85. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_00yjcv1._.js +1 -1
  86. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_01605g7._.js +1 -1
  87. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0o54suy._.js +1 -1
  88. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0rix02i._.js +1 -1
  89. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_1u3abhy._.js → _0x999pb._.js} +2 -2
  90. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_0ndy563._.js → _1-6rzip._.js} +2 -2
  91. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_18-d2be._.js +1 -1
  92. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_087xa25._.js → _1_talrs._.js} +2 -2
  93. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_11vnfnm._.js → _1ar5uqe._.js} +2 -2
  94. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_02drwa_._.js → _1c9b9j-._.js} +2 -2
  95. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1gw6vc9._.js +1 -1
  96. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/apps_vinaya-studio_web_src_app_studio_18kqbvs._.js +1 -1
  97. 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
  98. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/node_modules_1vo08dj._.js +2 -2
  99. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_animate_components_index_ts_186fje1._.js +1 -1
  100. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_basic_components_index_ts_0xk1vda._.js +1 -1
  101. package/studio-standalone/apps/vinaya-studio/web/.next/server/middleware-build-manifest.js +3 -3
  102. package/studio-standalone/apps/vinaya-studio/web/.next/server/pages/500.html +1 -1
  103. package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.js +1 -1
  104. package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.json +3 -3
  105. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1mexqnauhtbtp.js → 0_jnwbarv-cqk.js} +1 -1
  106. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0ek6qlqhokys0.js → 0l_vubs1ephe5.js} +1 -1
  107. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/0ojfbn3yvy-8_.js +1 -0
  108. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1jx5_q1g9l-cm.js → 0phqfqwbnt_ey.js} +1 -1
  109. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0qcu17x3h94a9.js → 17r0szvqeeyhx.js} +1 -1
  110. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0ve1-nz-mu_lr.js → 18x3rbqzeutpz.js} +1 -1
  111. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{22y4d5yrovcv-.js → 1bqpfvromtwn1.js} +1 -1
  112. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{39w6jbw3rleez.js → 24ojyzmt_fkg3.js} +1 -1
  113. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0tmcnl-z8yt2_.js → 30lyvn0yzwdiz.js} +1 -1
  114. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0fm4p9os2lsom.js → 3m0_gk59s-rbx.js} +1 -1
  115. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0ywkq74falx-x.js → 40x7f5hm7a5tk.js} +1 -1
  116. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0-08g_jjalnd9.js → 453zhecht_m1q.js} +1 -1
  117. package/studio-standalone/apps/vinaya-studio/web/server.js +1 -1
  118. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/1s9ixp5nhnevp.js +0 -1
  119. /package/studio-standalone/apps/vinaya-studio/web/.next/static/{R7xvB2iuNFp_jxENpL7xv → p5sWGp4ANwORiaX4Kk6U2}/_buildManifest.js +0 -0
  120. /package/studio-standalone/apps/vinaya-studio/web/.next/static/{R7xvB2iuNFp_jxENpL7xv → p5sWGp4ANwORiaX4Kk6U2}/_clientMiddlewareManifest.js +0 -0
  121. /package/studio-standalone/apps/vinaya-studio/web/.next/static/{R7xvB2iuNFp_jxENpL7xv → p5sWGp4ANwORiaX4Kk6U2}/_ssgManifest.js +0 -0
@@ -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
- return maskIndentedCode(maskFencedCode(body, fill), fill).replace(/(`+)[^\n]*?\1/g, (m) => " ".repeat(m.length));
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.replace(/(`+)[^\n]*?\1/g, "");
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(/(\*\*)?\s*Tier\s*(\*\*)?\s*:\s*(\*\*)?\s*([013])\b/i);
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 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
- return maskIndentedCode(maskFencedCode(body, fill), fill).replace(/(`+)[^\n]*?\1/g, (m) => " ".repeat(m.length));
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.replace(/(`+)[^\n]*?\1/g, "");
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(/(\*\*)?\s*Tier\s*(\*\*)?\s*:\s*(\*\*)?\s*([013])\b/i);
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(/\|$/, "");
@@ -7,7 +7,27 @@ import { fileURLToPath } from "node:url";
7
7
  // ../../packages/aeg-forge-state/src/strip-code.ts
8
8
  function maskCode(body) {
9
9
  const fill = (line) => " ".repeat(line.length);
10
- return maskIndentedCode(maskFencedCode(body, fill), fill).replace(/(`+)[^\n]*?\1/g, (m) => " ".repeat(m.length));
10
+ const blocksMasked = maskIndentedCode(maskFencedCode(body, fill), fill);
11
+ return blocksMasked.split(`
12
+ `).map((line) => replaceInlineSpans(line, (span) => " ".repeat(span.length))).join(`
13
+ `);
14
+ }
15
+ var DETAILS_OPEN = /<details\b[^>]*>/gi;
16
+ var DETAILS_CLOSE = /<\/details\s*>/gi;
17
+ function maskDetailsBlocks(body) {
18
+ const fill = (line) => " ".repeat(line.length);
19
+ const lines = body.split(`
20
+ `);
21
+ let depth = 0;
22
+ const out = lines.map((line) => {
23
+ const opens = line.match(DETAILS_OPEN)?.length ?? 0;
24
+ const closes = line.match(DETAILS_CLOSE)?.length ?? 0;
25
+ const maskThisLine = depth > 0 || opens > 0;
26
+ depth = Math.max(0, depth + opens - closes);
27
+ return maskThisLine ? fill(line) : line;
28
+ });
29
+ return out.join(`
30
+ `);
11
31
  }
12
32
  function stripCode(body, options = {}) {
13
33
  const normalised = body.replace(/\r\n?/g, `
@@ -16,7 +36,50 @@ function stripCode(body, options = {}) {
16
36
  const blocksStripped = maskIndentedCode(maskFencedCode(normalised, blank), blank);
17
37
  if (options.inlineSpans === "keep")
18
38
  return blocksStripped;
19
- return blocksStripped.replace(/(`+)[^\n]*?\1/g, "");
39
+ return blocksStripped.split(`
40
+ `).map((line) => replaceInlineSpans(line, () => "")).join(`
41
+ `);
42
+ }
43
+ function replaceInlineSpans(line, replace) {
44
+ let result = "";
45
+ let i = 0;
46
+ const runLengthAt = (at) => {
47
+ let j = at;
48
+ while (j < line.length && line[j] === "`")
49
+ j++;
50
+ return j - at;
51
+ };
52
+ while (i < line.length) {
53
+ if (line[i] !== "`") {
54
+ result += line[i];
55
+ i++;
56
+ continue;
57
+ }
58
+ const openLen = runLengthAt(i);
59
+ const openEnd = i + openLen;
60
+ let j = openEnd;
61
+ let closeEnd = -1;
62
+ while (j < line.length) {
63
+ if (line[j] !== "`") {
64
+ j++;
65
+ continue;
66
+ }
67
+ const runLen = runLengthAt(j);
68
+ if (runLen === openLen) {
69
+ closeEnd = j + runLen;
70
+ break;
71
+ }
72
+ j += runLen;
73
+ }
74
+ if (closeEnd === -1) {
75
+ result += line.slice(i, openEnd);
76
+ i = openEnd;
77
+ } else {
78
+ result += replace(line.slice(i, closeEnd));
79
+ i = closeEnd;
80
+ }
81
+ }
82
+ return result;
20
83
  }
21
84
  var FENCE_OPEN = /^ {0,3}(`{3,}|~{3,})([^\r\n]*)\r?$/;
22
85
  var FENCE_CLOSE = /^ {0,3}(`+|~+)[ \t]*\r?$/;
@@ -1755,9 +1818,10 @@ function evaluateC5(changed, docOwnersContent, prBody, fileExists, waiverActive,
1755
1818
  return out;
1756
1819
  }
1757
1820
  // ../../packages/aeg-core/src/pr-tier.ts
1821
+ var TIER_FIELD = /(\*\*)?\s*Tier\s*(\*\*)?\s*:\s*(\*\*)?\s*([013])\b/i;
1758
1822
  function readTierFromPrBody(prBody) {
1759
1823
  const searchIn = anchoredRegion(prBody, "TIER") ?? prBody;
1760
- const m = searchIn.match(/(\*\*)?\s*Tier\s*(\*\*)?\s*:\s*(\*\*)?\s*([013])\b/i);
1824
+ const m = searchIn.match(TIER_FIELD);
1761
1825
  if (!m)
1762
1826
  return null;
1763
1827
  const t = Number(m[4]);
@@ -2399,9 +2463,6 @@ function extractSecurityReviewVerdict(comments) {
2399
2463
  return extractVerdict(comments, /^[ \t]*(?:\*{1,3}|_{1,3})?VERDICT:\s*(PASS|FAIL)(?![A-Za-z0-9])/im, "security-review");
2400
2464
  }
2401
2465
  // ../../packages/aeg-core/src/review-gate.ts
2402
- function isReviewGateExemptBranch(branch) {
2403
- return branch.startsWith("plan/");
2404
- }
2405
2466
  function isBoundToHead(extraction, headSha) {
2406
2467
  if (!extraction.headSha)
2407
2468
  return false;
@@ -2456,6 +2517,11 @@ function checkReviewGate(input) {
2456
2517
  waived: false
2457
2518
  };
2458
2519
  }
2520
+ var CHANGESET_RELEASE_BRANCH = "changeset-release/main";
2521
+ var DEFAULT_RELEASE_ACTOR = "github-actions[bot]";
2522
+ function isChangesetsReleasePr(branch, author, expectedAuthor) {
2523
+ return branch === CHANGESET_RELEASE_BRANCH && author === expectedAuthor;
2524
+ }
2459
2525
  // ../../packages/aeg-core/src/markdown-table.ts
2460
2526
  function splitRow(line) {
2461
2527
  const trimmed = line.trim().replace(/^\|/, "").replace(/\|$/, "");
@@ -7,7 +7,27 @@ import matter2 from "gray-matter";
7
7
  // ../../packages/aeg-forge-state/src/strip-code.ts
8
8
  function maskCode(body) {
9
9
  const fill = (line) => " ".repeat(line.length);
10
- return maskIndentedCode(maskFencedCode(body, fill), fill).replace(/(`+)[^\n]*?\1/g, (m) => " ".repeat(m.length));
10
+ const blocksMasked = maskIndentedCode(maskFencedCode(body, fill), fill);
11
+ return blocksMasked.split(`
12
+ `).map((line) => replaceInlineSpans(line, (span) => " ".repeat(span.length))).join(`
13
+ `);
14
+ }
15
+ var DETAILS_OPEN = /<details\b[^>]*>/gi;
16
+ var DETAILS_CLOSE = /<\/details\s*>/gi;
17
+ function maskDetailsBlocks(body) {
18
+ const fill = (line) => " ".repeat(line.length);
19
+ const lines = body.split(`
20
+ `);
21
+ let depth = 0;
22
+ const out = lines.map((line) => {
23
+ const opens = line.match(DETAILS_OPEN)?.length ?? 0;
24
+ const closes = line.match(DETAILS_CLOSE)?.length ?? 0;
25
+ const maskThisLine = depth > 0 || opens > 0;
26
+ depth = Math.max(0, depth + opens - closes);
27
+ return maskThisLine ? fill(line) : line;
28
+ });
29
+ return out.join(`
30
+ `);
11
31
  }
12
32
  function stripCode(body, options = {}) {
13
33
  const normalised = body.replace(/\r\n?/g, `
@@ -16,7 +36,50 @@ function stripCode(body, options = {}) {
16
36
  const blocksStripped = maskIndentedCode(maskFencedCode(normalised, blank), blank);
17
37
  if (options.inlineSpans === "keep")
18
38
  return blocksStripped;
19
- return blocksStripped.replace(/(`+)[^\n]*?\1/g, "");
39
+ return blocksStripped.split(`
40
+ `).map((line) => replaceInlineSpans(line, () => "")).join(`
41
+ `);
42
+ }
43
+ function replaceInlineSpans(line, replace) {
44
+ let result = "";
45
+ let i = 0;
46
+ const runLengthAt = (at) => {
47
+ let j = at;
48
+ while (j < line.length && line[j] === "`")
49
+ j++;
50
+ return j - at;
51
+ };
52
+ while (i < line.length) {
53
+ if (line[i] !== "`") {
54
+ result += line[i];
55
+ i++;
56
+ continue;
57
+ }
58
+ const openLen = runLengthAt(i);
59
+ const openEnd = i + openLen;
60
+ let j = openEnd;
61
+ let closeEnd = -1;
62
+ while (j < line.length) {
63
+ if (line[j] !== "`") {
64
+ j++;
65
+ continue;
66
+ }
67
+ const runLen = runLengthAt(j);
68
+ if (runLen === openLen) {
69
+ closeEnd = j + runLen;
70
+ break;
71
+ }
72
+ j += runLen;
73
+ }
74
+ if (closeEnd === -1) {
75
+ result += line.slice(i, openEnd);
76
+ i = openEnd;
77
+ } else {
78
+ result += replace(line.slice(i, closeEnd));
79
+ i = closeEnd;
80
+ }
81
+ }
82
+ return result;
20
83
  }
21
84
  var FENCE_OPEN = /^ {0,3}(`{3,}|~{3,})([^\r\n]*)\r?$/;
22
85
  var FENCE_CLOSE = /^ {0,3}(`+|~+)[ \t]*\r?$/;
@@ -1755,9 +1818,10 @@ function evaluateC5(changed, docOwnersContent, prBody, fileExists, waiverActive,
1755
1818
  return out;
1756
1819
  }
1757
1820
  // ../../packages/aeg-core/src/pr-tier.ts
1821
+ var TIER_FIELD = /(\*\*)?\s*Tier\s*(\*\*)?\s*:\s*(\*\*)?\s*([013])\b/i;
1758
1822
  function readTierFromPrBody(prBody) {
1759
1823
  const searchIn = anchoredRegion(prBody, "TIER") ?? prBody;
1760
- const m = searchIn.match(/(\*\*)?\s*Tier\s*(\*\*)?\s*:\s*(\*\*)?\s*([013])\b/i);
1824
+ const m = searchIn.match(TIER_FIELD);
1761
1825
  if (!m)
1762
1826
  return null;
1763
1827
  const t = Number(m[4]);
@@ -2399,9 +2463,6 @@ function extractSecurityReviewVerdict(comments) {
2399
2463
  return extractVerdict(comments, /^[ \t]*(?:\*{1,3}|_{1,3})?VERDICT:\s*(PASS|FAIL)(?![A-Za-z0-9])/im, "security-review");
2400
2464
  }
2401
2465
  // ../../packages/aeg-core/src/review-gate.ts
2402
- function isReviewGateExemptBranch(branch) {
2403
- return branch.startsWith("plan/");
2404
- }
2405
2466
  function isBoundToHead(extraction, headSha) {
2406
2467
  if (!extraction.headSha)
2407
2468
  return false;
@@ -2456,6 +2517,11 @@ function checkReviewGate(input) {
2456
2517
  waived: false
2457
2518
  };
2458
2519
  }
2520
+ var CHANGESET_RELEASE_BRANCH = "changeset-release/main";
2521
+ var DEFAULT_RELEASE_ACTOR = "github-actions[bot]";
2522
+ function isChangesetsReleasePr(branch, author, expectedAuthor) {
2523
+ return branch === CHANGESET_RELEASE_BRANCH && author === expectedAuthor;
2524
+ }
2459
2525
  // ../../packages/aeg-core/src/markdown-table.ts
2460
2526
  function splitRow(line) {
2461
2527
  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
- return maskIndentedCode(maskFencedCode(body, fill), fill).replace(/(`+)[^\n]*?\1/g, (m) => " ".repeat(m.length));
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.replace(/(`+)[^\n]*?\1/g, "");
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(/(\*\*)?\s*Tier\s*(\*\*)?\s*:\s*(\*\*)?\s*([013])\b/i);
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(/\|$/, "");
@@ -3156,6 +3222,7 @@ var VinayaConfigSchema = z.object({
3156
3222
  briefSchema: BriefSchemaSchema.optional(),
3157
3223
  managed: ManagedManifestSchema.optional(),
3158
3224
  principals: z.array(z.string()).min(1).optional(),
3225
+ releaseActor: z.string().min(1).optional(),
3159
3226
  ci: z.object({ setup: z.string().min(1) }).optional(),
3160
3227
  blastRadius: z.object({ extraDomains: z.array(z.string()).optional() }).optional()
3161
3228
  });
@@ -3165,6 +3232,9 @@ var LOCAL_CONFIG_FILENAME = "vinaya.config.json";
3165
3232
  function resolvePrincipalAllowlist(config) {
3166
3233
  return config?.principals ?? PRINCIPAL_ALLOWLIST;
3167
3234
  }
3235
+ function resolveReleaseActor(config) {
3236
+ return config?.releaseActor ?? DEFAULT_RELEASE_ACTOR;
3237
+ }
3168
3238
  function trustAnchorRepo() {
3169
3239
  const wellFormed = (slug) => /^[^/\s]+\/[^/\s]+$/.test(slug) ? slug : null;
3170
3240
  const fromRunner = process.env.GITHUB_REPOSITORY?.trim();
@@ -3207,7 +3277,7 @@ function isMissingFileError(err) {
3207
3277
  return /\b404\b|not found/i.test(haystack);
3208
3278
  }
3209
3279
  function loadTrustAnchorConfig(fetcher = ghFetchTrustAnchorConfig) {
3210
- const warn = (why) => process.stdout.write(`⚠ could not read \`principals\` from the default branch (${why}) — falling back to vinaya's built-in principal allowlist.
3280
+ 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.
3211
3281
  `);
3212
3282
  let base64;
3213
3283
  try {
@@ -3234,13 +3304,6 @@ function loadTrustAnchorConfig(fetcher = ghFetchTrustAnchorConfig) {
3234
3304
 
3235
3305
  // src/checks/bin/check-review-gate.ts
3236
3306
  var CHECK_NAME = "review-gate";
3237
- function git(args) {
3238
- try {
3239
- return execFileSync3("git", args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
3240
- } catch {
3241
- return "";
3242
- }
3243
- }
3244
3307
  function fetchPr(prNumber) {
3245
3308
  try {
3246
3309
  const out = execFileSync3("gh", ["pr", "view", String(prNumber), "--json", "number,comments,labels,headRefOid"], {
@@ -3267,10 +3330,6 @@ function fetchWaiverLabelActor(prNumber, label2) {
3267
3330
  }
3268
3331
  }
3269
3332
  function main() {
3270
- const branch = process.env.BRANCH || git(["rev-parse", "--abbrev-ref", "HEAD"]);
3271
- if (isReviewGateExemptBranch(branch)) {
3272
- process.exit(0);
3273
- }
3274
3333
  const prNumberStr = process.env.PR_NUMBER;
3275
3334
  if (!prNumberStr) {
3276
3335
  process.exit(0);