@attalabs/vinaya 0.19.3 → 0.21.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 (153) hide show
  1. package/README.md +81 -0
  2. package/aeg-root/contracts/archivist-tranche-archivist.md +2 -2
  3. package/aeg-root/contracts/tranche-archivist-planner.md +8 -8
  4. package/aeg-root/enforcement.md +18 -9
  5. package/aeg-root/milestone-model.md +3 -1
  6. package/aeg-root/process.md +5 -5
  7. package/aeg-root/roles/architect.md +2 -2
  8. package/aeg-root/roles/archivist.md +10 -11
  9. package/aeg-root/roles/brief-author.md +1 -1
  10. package/aeg-root/roles/developer.md +4 -3
  11. package/aeg-root/roles/planner.md +2 -2
  12. package/aeg-root/roles/principal.md +2 -1
  13. package/aeg-root/roles/tranche-archivist.md +5 -18
  14. package/aeg-root/skills/aeg/SKILL.md +30 -1
  15. package/aeg-root/skills/aeg-roles/SKILL.md +1 -1
  16. package/aeg-root/skills/brief-authoring/SKILL.md +2 -2
  17. package/aeg-root/state-machine.md +8 -6
  18. package/aeg-root/task-model.md +1 -1
  19. package/aeg-root/templates/issue-rationale-template.md +4 -4
  20. package/aeg-root/templates/pr-report-template.md +4 -0
  21. package/aeg-root/tranche-model.md +1 -1
  22. package/dist/checks/bin/check-body-bare-digits.js +473 -32
  23. package/dist/checks/bin/check-branch-topology.js +792 -11
  24. package/dist/checks/bin/check-brief-shape.js +353 -11
  25. package/dist/checks/bin/check-changeset-coverage.js +4156 -0
  26. package/dist/checks/bin/check-closes-n.js +792 -11
  27. package/dist/checks/bin/check-coherence.js +831 -15
  28. package/dist/checks/bin/check-dead-branch-push.js +353 -11
  29. package/dist/checks/bin/check-dispatch-readiness.js +996 -28
  30. package/dist/checks/bin/check-doc-coverage-push.js +449 -22
  31. package/dist/checks/bin/check-doc-coverage.js +449 -22
  32. package/dist/checks/bin/check-doctrine-portability.js +392 -15
  33. package/dist/checks/bin/check-evidence-fresh.js +462 -20
  34. package/dist/checks/bin/check-first-push-dispatch.js +898 -26
  35. package/dist/checks/bin/check-issue-assignment.js +792 -11
  36. package/dist/checks/bin/check-main-branch-refusal.js +3973 -0
  37. package/dist/checks/bin/check-no-disk-state.js +353 -11
  38. package/dist/checks/bin/check-quoted-command.js +4405 -0
  39. package/dist/checks/bin/check-reader-resolvable-prose.js +466 -20
  40. package/dist/checks/bin/check-registry-gates.js +467 -16
  41. package/dist/checks/bin/check-retired-vocabulary.js +465 -19
  42. package/dist/checks/bin/check-review-gate.js +392 -15
  43. package/dist/checks/bin/check-single-plan-pr.js +353 -11
  44. package/dist/checks/bin/check-test-plan.js +353 -11
  45. package/dist/checks/bin/check-token-collection-wired.js +3975 -0
  46. package/dist/checks/bin/check-workspace-escape.js +353 -11
  47. package/dist/index.js +1921 -420
  48. package/package.json +1 -1
  49. package/studio-standalone/_node_modules/@attalabs/vinaya/studio-standalone/_node_modules/@attalabs/aeg-core/bin/verify-coherence.ts +1089 -0
  50. package/studio-standalone/apps/vinaya-studio/web/.next/BUILD_ID +1 -1
  51. package/studio-standalone/apps/vinaya-studio/web/.next/build-manifest.json +3 -3
  52. package/studio-standalone/apps/vinaya-studio/web/.next/prerender-manifest.json +3 -3
  53. package/studio-standalone/apps/vinaya-studio/web/.next/required-server-files.json +5 -0
  54. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.html +1 -1
  55. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.rsc +1 -1
  56. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  57. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  58. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  59. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  60. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  61. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page/server-reference-manifest.json +2 -2
  62. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page.js +2 -2
  63. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  64. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  65. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/api/coherence/route.js +1 -1
  66. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/api/coherence/route.js.nft.json +1 -1
  67. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page/server-reference-manifest.json +2 -2
  68. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page.js +2 -2
  69. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page.js.nft.json +1 -1
  70. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page_client-reference-manifest.js +1 -1
  71. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page/server-reference-manifest.json +2 -2
  72. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page.js +2 -2
  73. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page.js.nft.json +1 -1
  74. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page_client-reference-manifest.js +1 -1
  75. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page/server-reference-manifest.json +2 -2
  76. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page.js +3 -3
  77. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page.js.nft.json +1 -1
  78. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page_client-reference-manifest.js +1 -1
  79. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page/server-reference-manifest.json +2 -2
  80. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page.js +3 -3
  81. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page.js.nft.json +1 -1
  82. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page_client-reference-manifest.js +1 -1
  83. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page/server-reference-manifest.json +2 -2
  84. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page.js +3 -3
  85. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page.js.nft.json +1 -1
  86. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page_client-reference-manifest.js +1 -1
  87. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page/server-reference-manifest.json +2 -2
  88. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page.js +3 -3
  89. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page.js.nft.json +1 -1
  90. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page_client-reference-manifest.js +1 -1
  91. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page/server-reference-manifest.json +2 -2
  92. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page.js +3 -3
  93. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page.js.nft.json +1 -1
  94. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page_client-reference-manifest.js +1 -1
  95. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page/server-reference-manifest.json +2 -2
  96. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page.js +2 -2
  97. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page.js.nft.json +1 -1
  98. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page_client-reference-manifest.js +1 -1
  99. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/{[externals]__0pvgf28._.js → [externals]__1agj1ww._.js} +2 -2
  100. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/[root-of-the-server]__02a-3g8._.js +1 -1
  101. 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
  102. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0053k9k._.js +1 -1
  103. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0112h-k._.js +1 -1
  104. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__040smoa._.js +1 -1
  105. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0cxtq46._.js +25 -18
  106. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0o771t1._.js +1 -1
  107. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__03jepya._.js → [root-of-the-server]__0ozbaq0._.js} +1 -1
  108. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0puovz5._.js +1 -1
  109. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__0ykun-j._.js → [root-of-the-server]__0z6dav-._.js} +3 -3
  110. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__18kqy4q._.js +1 -1
  111. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__19jyp3m._.js +1 -1
  112. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1hs0dcu._.js +1 -1
  113. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1wc4-ip._.js +1 -1
  114. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1widio3._.js +1 -1
  115. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1yoa8tx._.js +3 -0
  116. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_03x_w6q._.js +1 -1
  117. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0gvm3og._.js +1 -1
  118. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0lwxg63._.js +1 -1
  119. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0wxycau._.js +1 -1
  120. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0x999pb._.js +1 -1
  121. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1-6rzip._.js +1 -1
  122. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1fqw88f._.js +2 -2
  123. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_0zys35s._.js → _1mqrlbl._.js} +2 -2
  124. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{_1c9b9j-._.js → _1mrtj0f._.js} +2 -2
  125. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1n0cnq-._.js +1 -1
  126. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{apps_vinaya-studio_web_src_app_studio_18kqbvs._.js → apps_vinaya-studio_web_src_app_studio_06it6s-._.js} +2 -2
  127. 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 -1
  128. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/node_modules_1vo08dj._.js +2 -2
  129. package/studio-standalone/apps/vinaya-studio/web/.next/server/middleware-build-manifest.js +3 -3
  130. package/studio-standalone/apps/vinaya-studio/web/.next/server/pages/500.html +1 -1
  131. package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.js +1 -1
  132. package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.json +3 -3
  133. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/0r4i_ks9z02bw.js +1 -0
  134. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{3noqvds-2bvrd.js → 1hfhxjy577l5d.js} +1 -1
  135. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/1k916ih3p4nsg.js +1 -0
  136. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{29-foak16tjfu.js → 1t2kft7bxzuxn.js} +1 -1
  137. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{2iysedx-n06xc.js → 1ybrihl5_aocy.js} +1 -1
  138. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{30ojnsx3p4lp4.js → 1yqs2zgvwa4p1.js} +1 -1
  139. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0msr2a1i-x-br.js → 25kbt5k-xb2a5.js} +1 -1
  140. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{3gehliafvmjo9.js → 2_k6j1o9q5nn4.js} +4 -4
  141. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/2hmannd4bjhzy.js +1 -0
  142. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/3mqu_uhluy19i.css +1 -0
  143. package/studio-standalone/apps/vinaya-studio/web/package.json +2 -2
  144. package/studio-standalone/apps/vinaya-studio/web/server.js +1 -1
  145. package/aeg-root/coordination.md +0 -292
  146. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1rku4gz._.js +0 -3
  147. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/25j-y57ng11hl.js +0 -1
  148. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/30lyvn0yzwdiz.js +0 -1
  149. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/35u8inxa732is.js +0 -1
  150. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/42wxpzjhw7oy4.css +0 -1
  151. /package/studio-standalone/apps/vinaya-studio/web/.next/static/{5Lv83SnT--7YJDjSbxona → crNCHQ9uAgKOYC6DKkZma}/_buildManifest.js +0 -0
  152. /package/studio-standalone/apps/vinaya-studio/web/.next/static/{5Lv83SnT--7YJDjSbxona → crNCHQ9uAgKOYC6DKkZma}/_clientMiddlewareManifest.js +0 -0
  153. /package/studio-standalone/apps/vinaya-studio/web/.next/static/{5Lv83SnT--7YJDjSbxona → crNCHQ9uAgKOYC6DKkZma}/_ssgManifest.js +0 -0
@@ -6,17 +6,17 @@ import { existsSync as existsSync3, readdirSync, readFileSync, statSync } from "
6
6
  import matter2 from "gray-matter";
7
7
  // ../../packages/aeg-core/src/gate-audience.ts
8
8
  var GATE_AUDIENCE = {
9
- "check-branch-topology": { shippedAs: "branch-topology" },
10
- "check-first-push-dispatch": { shippedAs: "first-push-dispatch" },
11
- "check-no-disk-state": { shippedAs: "no-disk-state" },
12
- "verify-brief": { shippedAs: "brief-shape" },
13
- "verify-coherence": { shippedAs: "coherence" },
14
- "verify-dispatch": { shippedAs: "dispatch-readiness" },
15
- "verify-docs": { shippedAs: ["doc-coverage", "doc-coverage-push"] },
16
- "verify-registry": { shippedAs: "registry-gates" },
17
- "verify-review-gate": { shippedAs: "review-gate" },
18
- "verify-single-plan-pr": { shippedAs: "single-plan-pr" },
19
- "verify-test-plan": { shippedAs: "test-plan" },
9
+ "check-branch-topology": { shippedAs: "branch-topology", ring: 0 },
10
+ "check-first-push-dispatch": { shippedAs: "first-push-dispatch", ring: 0 },
11
+ "check-no-disk-state": { shippedAs: "no-disk-state", ring: 0 },
12
+ "verify-brief": { shippedAs: "brief-shape", ring: 0 },
13
+ "verify-coherence": { shippedAs: "coherence", ring: 0 },
14
+ "verify-dispatch": { shippedAs: "dispatch-readiness", ring: 0 },
15
+ "verify-docs": { shippedAs: ["doc-coverage", "doc-coverage-push"], ring: 0 },
16
+ "verify-registry": { shippedAs: "registry-gates", ring: 0 },
17
+ "verify-review-gate": { shippedAs: "review-gate", ring: 1 },
18
+ "verify-single-plan-pr": { shippedAs: "single-plan-pr", ring: 0 },
19
+ "verify-test-plan": { shippedAs: "test-plan", ring: 1 },
20
20
  "check-direct-main-push": {
21
21
  internal: "Reaches adopters through `vinaya audit --only=direct-push`, not the check registry: it is a ring-2 sweep over merge history keyed on `GITHUB_SHA`, run by the generated archivist job on push to the default branch. It has no diff to key on, so there is nothing for `vinaya check` to run it against."
22
22
  },
@@ -191,6 +191,12 @@ var NEXT_HEADER = /\*\*[A-Z][^*]*\*\*/;
191
191
  var FIELD_LABEL = /^(Depends-on|Conflicts-with)\s*:\s*(.*)$/i;
192
192
  var ID_TOKEN = /^(?:[\w.-]+\s+)?#?\d+[a-z]?$/i;
193
193
  var SLUG_QUALIFIED_ID = /^([\w.-]+)\s+(#?\d+[a-z]?)$/i;
194
+ function splitSlugQualifiedEdge(edge) {
195
+ const m = edge.trim().match(SLUG_QUALIFIED_ID);
196
+ if (!m)
197
+ return null;
198
+ return { slug: m[1], bareId: m[2] };
199
+ }
194
200
  function isEmptyMarker(s) {
195
201
  const t = s.trim();
196
202
  return t === "" || t === "—" || t === "-" || t === "–";
@@ -328,6 +334,13 @@ var LABELS = [
328
334
  form: "literal",
329
335
  carries: "Execution is halted pending an external unblock; wins over every other derived status."
330
336
  },
337
+ {
338
+ key: "backlog",
339
+ id: "vinaya/backlog",
340
+ category: "state",
341
+ form: "literal",
342
+ carries: "The Issue is deliberately unplanned — belongs to no tranche and is excluded from dispatch, until a Planner promotes it."
343
+ },
331
344
  {
332
345
  key: "tier-0",
333
346
  id: "vinaya/tier:0",
@@ -1780,6 +1793,151 @@ var DERIVED_STATUSES = [
1780
1793
  "incoherent"
1781
1794
  ];
1782
1795
  var DERIVABLE_STATUSES = DERIVED_STATUSES.filter((s) => s !== "backlog");
1796
+ // ../../packages/aeg-core/src/report-tokens.ts
1797
+ var DASH_LOOKALIKES = {
1798
+ "-": "‑",
1799
+ "–": "‒",
1800
+ "—": "―"
1801
+ };
1802
+ var DASH_CHARS = new Set(Object.keys(DASH_LOOKALIKES));
1803
+ // ../../packages/aeg-core/src/claude-code-transcript.ts
1804
+ function summarizeTranscript(jsonl) {
1805
+ const seen = new Set;
1806
+ const components = {
1807
+ inputTokens: 0,
1808
+ outputTokens: 0,
1809
+ cacheCreationInputTokens: 0,
1810
+ cacheReadInputTokens: 0
1811
+ };
1812
+ let model = null;
1813
+ let messageCount = 0;
1814
+ for (const rawLine of jsonl.split(/\r?\n/)) {
1815
+ const line = rawLine.trim();
1816
+ if (!line)
1817
+ continue;
1818
+ let entry2;
1819
+ try {
1820
+ entry2 = JSON.parse(line);
1821
+ } catch {
1822
+ continue;
1823
+ }
1824
+ if (!entry2 || typeof entry2 !== "object")
1825
+ continue;
1826
+ const obj = entry2;
1827
+ if (obj.type !== "assistant")
1828
+ continue;
1829
+ const message = obj.message;
1830
+ const id = message?.id;
1831
+ const usage = message?.usage;
1832
+ if (typeof id !== "string" || !id || !usage || seen.has(id))
1833
+ continue;
1834
+ seen.add(id);
1835
+ messageCount++;
1836
+ components.inputTokens += numberOr(usage.input_tokens, 0);
1837
+ components.outputTokens += numberOr(usage.output_tokens, 0);
1838
+ components.cacheCreationInputTokens += numberOr(usage.cache_creation_input_tokens, 0);
1839
+ components.cacheReadInputTokens += numberOr(usage.cache_read_input_tokens, 0);
1840
+ const messageModel = message?.model;
1841
+ if (typeof messageModel === "string" && messageModel)
1842
+ model = messageModel;
1843
+ }
1844
+ return { components, model, messageCount };
1845
+ }
1846
+ function numberOr(value, fallback) {
1847
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
1848
+ }
1849
+ function sanitizeKey(value) {
1850
+ return value.replace(/[^A-Za-z0-9]+/g, "-");
1851
+ }
1852
+ function transcriptPointerPath(projectDir, tmpDir) {
1853
+ return `${tmpDir}/claude-transcript-${sanitizeKey(projectDir)}.txt`;
1854
+ }
1855
+ function resolvePointer(explicitTranscriptPath, deps) {
1856
+ if (explicitTranscriptPath)
1857
+ return { path: explicitTranscriptPath, corroborated: true };
1858
+ const projectDir = deps.env.CLAUDE_PROJECT_DIR ?? deps.cwd;
1859
+ const tmpDir = deps.env.TMPDIR ?? "/tmp";
1860
+ const pointerPath = transcriptPointerPath(projectDir, tmpDir);
1861
+ const currentSessionId = deps.env.CLAUDE_CODE_SESSION_ID;
1862
+ if (!deps.exists(pointerPath)) {
1863
+ return {
1864
+ pointerExisted: false,
1865
+ corroborated: false,
1866
+ error: `No transcript pointer at ${pointerPath} and no --transcript given. ` + "Either this repo installs no track-transcript.sh Stop hook (lacking one is not a defect — " + "name the transcript directly instead), or no session has completed a turn yet."
1867
+ };
1868
+ }
1869
+ let contents;
1870
+ try {
1871
+ contents = deps.readFile(pointerPath).replace(/\r?\n+$/, "");
1872
+ } catch (err) {
1873
+ return {
1874
+ pointerExisted: true,
1875
+ oursByLocation: true,
1876
+ error: `Transcript pointer at ${pointerPath} could not be read: ${err.message}. ` + "Remove that file to clear this — the Stop hook rewrites it on the next turn."
1877
+ };
1878
+ }
1879
+ const [pointerSessionId, transcriptPath] = contents.split("\t");
1880
+ if (!transcriptPath) {
1881
+ return {
1882
+ pointerExisted: true,
1883
+ oursByLocation: true,
1884
+ error: `Transcript pointer file ${pointerPath} is malformed: "${contents.slice(0, 120)}${contents.length > 120 ? "…" : ""}". ` + "Remove that file to clear this — the Stop hook rewrites it on the next turn."
1885
+ };
1886
+ }
1887
+ if (currentSessionId && pointerSessionId && currentSessionId !== pointerSessionId) {
1888
+ return {
1889
+ pointerExisted: true,
1890
+ corroborated: false,
1891
+ error: `Transcript pointer at ${pointerPath} is stale: written for session ${pointerSessionId}, ` + `but this session is ${currentSessionId}. Name your own transcript with --transcript instead of ` + "reporting another session's figures as yours."
1892
+ };
1893
+ }
1894
+ return { path: transcriptPath, corroborated: Boolean(currentSessionId && pointerSessionId) };
1895
+ }
1896
+ function resolveMeteringCapability(deps, explicitTranscriptPath) {
1897
+ const resolved = resolvePointer(explicitTranscriptPath, deps);
1898
+ if ("error" in resolved) {
1899
+ const ours = resolved.pointerExisted && (resolved.corroborated || resolved.oursByLocation);
1900
+ if (ours)
1901
+ return { capable: false, reason: "pointer-unusable", detail: resolved.error };
1902
+ return {
1903
+ capable: false,
1904
+ reason: "no-transcript-resolved",
1905
+ detail: resolved.pointerExisted ? `A transcript pointer exists but belongs to another session, so this session has no wiring of its own to use. (Underlying condition, for diagnosis only: ${resolved.error})` : resolved.error
1906
+ };
1907
+ }
1908
+ const downstream = (r, detail) => resolved.corroborated ? { reason: r, detail } : {
1909
+ reason: "no-transcript-resolved",
1910
+ detail: `A transcript pointer was found but could not be shown to belong to this session, so it is not treated as this session's wiring. (Underlying condition, for diagnosis only: ${detail})`
1911
+ };
1912
+ if (!deps.exists(resolved.path)) {
1913
+ return {
1914
+ capable: false,
1915
+ ...downstream("transcript-unreadable", `Resolved transcript path ${resolved.path} is not readable as a regular file owned by this user.`)
1916
+ };
1917
+ }
1918
+ let jsonl;
1919
+ try {
1920
+ jsonl = deps.readFile(resolved.path);
1921
+ } catch (err) {
1922
+ return {
1923
+ capable: false,
1924
+ ...downstream("transcript-unreadable", `Transcript at ${resolved.path} could not be read: ${err.message}`)
1925
+ };
1926
+ }
1927
+ const summary = summarizeTranscript(jsonl);
1928
+ if (summary.messageCount === 0) {
1929
+ return {
1930
+ capable: false,
1931
+ ...downstream("transcript-empty", `Transcript at ${resolved.path} yielded zero assistant messages with usage data — ` + "it's empty, unparseable, or not yet flushed to disk.")
1932
+ };
1933
+ }
1934
+ return { capable: true, transcriptPath: resolved.path, summary };
1935
+ }
1936
+ function isTokenCollectionWiringBroken(capability) {
1937
+ if (capability.capable)
1938
+ return false;
1939
+ return capability.reason !== "no-transcript-resolved";
1940
+ }
1783
1941
  // ../../packages/aeg-core/src/file-classify.ts
1784
1942
  function isCodeFile(p) {
1785
1943
  if (p.endsWith(".md"))
@@ -1986,7 +2144,59 @@ function overrideActive(opts) {
1986
2144
  return false;
1987
2145
  }
1988
2146
  // ../../packages/aeg-core/src/premise-check.ts
2147
+ import { createHash } from "node:crypto";
1989
2148
  var ASSERTION_KINDS = new Set(["contains", "absent", "sha256"]);
2149
+ function isPremiseHeader(line) {
2150
+ const stripped = line.replace(/[*#]/g, "").trim();
2151
+ return /^premise\s*:?$/i.test(stripped);
2152
+ }
2153
+ var PREMISE_LINE = /^[-*]\s*(\S+)\s+(contains|absent|sha256)\s*:\s*(.+)$/i;
2154
+ function parsePremiseBlock(prBody) {
2155
+ const searchIn = anchoredRegion(prBody, "PREMISE") ?? prBody;
2156
+ const lines = searchIn.split(/\r?\n/);
2157
+ const assertions = [];
2158
+ let inBlock = false;
2159
+ for (const raw of lines) {
2160
+ const line = raw.trim();
2161
+ if (!inBlock) {
2162
+ if (isPremiseHeader(line))
2163
+ inBlock = true;
2164
+ continue;
2165
+ }
2166
+ if (line === "")
2167
+ break;
2168
+ const m = line.match(PREMISE_LINE);
2169
+ if (!m)
2170
+ break;
2171
+ const [, path, kindRaw, value] = m;
2172
+ const kind = kindRaw.toLowerCase();
2173
+ if (!ASSERTION_KINDS.has(kind))
2174
+ continue;
2175
+ assertions.push({ kind, path, value: value.trim() });
2176
+ }
2177
+ return assertions;
2178
+ }
2179
+ function checkPremises(assertions, fileReader) {
2180
+ const failures = [];
2181
+ for (const a of assertions) {
2182
+ const content = fileReader(a.path);
2183
+ if (content === null) {
2184
+ failures.push(`premise-check: ${a.path} does not exist on disk (premise asserted \`${a.kind}: ${a.value}\`) — the surface moved since this brief was authored; re-dig before proceeding.`);
2185
+ continue;
2186
+ }
2187
+ if (a.kind === "contains" && !content.includes(a.value)) {
2188
+ failures.push(`premise-check: ${a.path} no longer contains "${a.value}" — the premise this brief pinned has moved; re-dig before proceeding.`);
2189
+ } else if (a.kind === "absent" && content.includes(a.value)) {
2190
+ failures.push(`premise-check: ${a.path} now contains "${a.value}", but the brief pinned it absent — the premise has moved; re-dig before proceeding.`);
2191
+ } else if (a.kind === "sha256") {
2192
+ const actual = createHash("sha256").update(content).digest("hex");
2193
+ if (actual !== a.value.toLowerCase()) {
2194
+ failures.push(`premise-check: ${a.path} sha256 mismatch (brief pinned ${a.value}, file is now ${actual}) — the file changed since this brief was authored; re-dig before proceeding.`);
2195
+ }
2196
+ }
2197
+ }
2198
+ return { pass: failures.length === 0, failures };
2199
+ }
1990
2200
 
1991
2201
  // ../../packages/aeg-core/src/test-plan-section.ts
1992
2202
  var HEADING_FORM_RE = /^#{1,4}[ \t]*(?:\d+[a-z]?\.[ \t]*)?\*{0,2}Test Plan\*{0,2}[ \t]*$/im;
@@ -2790,6 +3000,7 @@ function checkG1(rows, existsFn) {
2790
3000
  }
2791
3001
  return { check: "G1", status: findings.length > 0 ? "fail" : "pass", findings };
2792
3002
  }
3003
+ var SCAFFOLD_PLACEHOLDER = "[undocumented — fill in why]";
2793
3004
  function checkG2(rows, candidateFiles) {
2794
3005
  const implementations = new Set(rows.map((r) => r.implementation).filter((p) => p !== ""));
2795
3006
  const findings = [];
@@ -2801,6 +3012,16 @@ function checkG2(rows, candidateFiles) {
2801
3012
  });
2802
3013
  }
2803
3014
  }
3015
+ for (const row of rows) {
3016
+ const carriesPlaceholder = [row.summary, row.description, row.spec].some((cell) => cell === SCAFFOLD_PLACEHOLDER);
3017
+ if (carriesPlaceholder) {
3018
+ findings.push({
3019
+ row: row.action,
3020
+ path: row.implementation,
3021
+ reason: `${row.ring} row "${row.action}" still carries the scaffold placeholder marker — the why is owed`
3022
+ });
3023
+ }
3024
+ }
2804
3025
  return { check: "G2", status: findings.length > 0 ? "info" : "pass", findings };
2805
3026
  }
2806
3027
  function checkG3(ring0Rows, crossingFiles) {
@@ -3148,6 +3369,100 @@ function parseGlossaryTerms(glossaryContent) {
3148
3369
  }
3149
3370
  return terms;
3150
3371
  }
3372
+ // ../../packages/aeg-core/src/quoted-command.ts
3373
+ var QUOTED_COMMAND_SHIPS_PREFIX = "aeg-root/";
3374
+ var QUOTED_COMMAND_SWEPT_CLASSES = new Set(["ships", "reader-facing"]);
3375
+ var START_PATTERN = /<!--\s*AEG:QUOTES-FILE:START:(\S+?)\s*-->/g;
3376
+ var END_PATTERN = /<!--\s*AEG:QUOTES-FILE:END\s*-->/;
3377
+ function isValidCitedFilePath(path) {
3378
+ if (path.length === 0)
3379
+ return false;
3380
+ if (path.startsWith("/") || path.startsWith("\\"))
3381
+ return false;
3382
+ if (/^[A-Za-z]:[\\/]/.test(path))
3383
+ return false;
3384
+ return !path.split(/[\\/]+/).includes("..");
3385
+ }
3386
+ function quotedCommandLineAt(content, index) {
3387
+ let line = 1;
3388
+ for (let i = 0;i < index; i++) {
3389
+ if (content.charCodeAt(i) === 10)
3390
+ line++;
3391
+ }
3392
+ return line;
3393
+ }
3394
+ function extractQuotedText(raw) {
3395
+ const trimmed = raw.trim();
3396
+ const fenced = /^(?:`{3,}|~{3,})[^\n]*\n([\s\S]*?)\n?(?:`{3,}|~{3,})$/.exec(trimmed);
3397
+ if (fenced)
3398
+ return (fenced[1] ?? "").trim();
3399
+ const inline = /^`([^`]+)`$/.exec(trimmed);
3400
+ if (inline)
3401
+ return (inline[1] ?? "").trim();
3402
+ return trimmed;
3403
+ }
3404
+ function findQuotesInFile(path, content) {
3405
+ const masked = maskCode(content);
3406
+ const quotes = [];
3407
+ START_PATTERN.lastIndex = 0;
3408
+ let start = START_PATTERN.exec(masked);
3409
+ while (start !== null) {
3410
+ const citedFile = start[1];
3411
+ const innerStart = start.index + start[0].length;
3412
+ const end = END_PATTERN.exec(masked.slice(innerStart));
3413
+ if (end === null) {
3414
+ START_PATTERN.lastIndex = innerStart;
3415
+ start = START_PATTERN.exec(masked);
3416
+ continue;
3417
+ }
3418
+ const innerEnd = innerStart + end.index;
3419
+ if (isValidCitedFilePath(citedFile)) {
3420
+ const quotedText = extractQuotedText(content.slice(innerStart, innerEnd));
3421
+ if (quotedText.length > 0) {
3422
+ quotes.push({ file: path, line: quotedCommandLineAt(content, innerStart), quotedText, citedFile });
3423
+ }
3424
+ }
3425
+ START_PATTERN.lastIndex = innerEnd + end[0].length;
3426
+ start = START_PATTERN.exec(masked);
3427
+ }
3428
+ return quotes;
3429
+ }
3430
+ function findCitedQuotes(files, readerFacingPrefix, readerFacingSuffix, shipsPrefix = QUOTED_COMMAND_SHIPS_PREFIX) {
3431
+ const quotes = [];
3432
+ for (const file of files) {
3433
+ const cls = classifyProseFile(file.path, readerFacingPrefix, readerFacingSuffix, shipsPrefix);
3434
+ if (!cls || !QUOTED_COMMAND_SWEPT_CLASSES.has(cls))
3435
+ continue;
3436
+ quotes.push(...findQuotesInFile(file.path, file.content));
3437
+ }
3438
+ return quotes;
3439
+ }
3440
+ function evaluateCitedQuotes(citedQuotes, citedFileContents) {
3441
+ const findings = [];
3442
+ for (const quote of citedQuotes) {
3443
+ const content = citedFileContents.get(quote.citedFile);
3444
+ if (content === undefined) {
3445
+ findings.push({
3446
+ file: quote.file,
3447
+ line: quote.line,
3448
+ citedFile: quote.citedFile,
3449
+ quotedText: quote.quotedText,
3450
+ message: `${quote.file}:${quote.line} quotes "${quote.quotedText}" as citing \`${quote.citedFile}\`, but that file could not be read`
3451
+ });
3452
+ continue;
3453
+ }
3454
+ if (!content.includes(quote.quotedText)) {
3455
+ findings.push({
3456
+ file: quote.file,
3457
+ line: quote.line,
3458
+ citedFile: quote.citedFile,
3459
+ quotedText: quote.quotedText,
3460
+ message: `${quote.file}:${quote.line} quotes "${quote.quotedText}" as citing \`${quote.citedFile}\`, but \`${quote.citedFile}\` no longer contains that text verbatim`
3461
+ });
3462
+ }
3463
+ }
3464
+ return findings;
3465
+ }
3151
3466
  // ../../packages/aeg-core/src/retired-vocabulary.ts
3152
3467
  var RETIRED_PATTERNS = [
3153
3468
  String.raw`\bD-[0-9]{3}\b`,
@@ -3261,6 +3576,10 @@ function checkDispatchReadiness(input) {
3261
3576
  blockers.push(`dispatch-gate rationale: Issue #${input.issue.number} for ${taskLabel} fails the rationale gate (checkIssueRationale) — the Planner must complete the eight-field rationale before this task is dispatchable.`);
3262
3577
  }
3263
3578
  for (const dep of input.dependsOn) {
3579
+ if (dep.resolved === false) {
3580
+ blockers.push(`dispatch-gate depends-on: ${taskLabel} depends on "${dep.id}", which is UNRESOLVABLE — the resolver could not find a matching tranche/task/Issue for this edge (not a claim about merge status). Not dispatchable until the edge is corrected.`);
3581
+ continue;
3582
+ }
3264
3583
  if (!dep.merged && !isHandClosedByRecognizedPrincipal(dep, principalAllowlist)) {
3265
3584
  const issueStr = dep.issue !== null ? ` (#${dep.issue})` : "";
3266
3585
  blockers.push(`dispatch-gate depends-on: ${taskLabel} depends on ${dep.id}${issueStr}, whose PR is not merged yet — not dispatchable, it serializes behind it.`);
@@ -3320,6 +3639,29 @@ function isNewDiskStateFile(path, status) {
3320
3639
  return false;
3321
3640
  return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
3322
3641
  }
3642
+ // ../../packages/aeg-core/src/main-branch-refusal.ts
3643
+ function checkMainBranchRefusal(facts) {
3644
+ const { currentSymbolicBranch, defaultBranch } = facts;
3645
+ if (currentSymbolicBranch === null)
3646
+ return null;
3647
+ if (defaultBranch === null) {
3648
+ return {
3649
+ reason: "default-branch-undetermined",
3650
+ severity: "warning",
3651
+ currentBranch: currentSymbolicBranch,
3652
+ defaultBranch: null
3653
+ };
3654
+ }
3655
+ if (currentSymbolicBranch === defaultBranch) {
3656
+ return {
3657
+ reason: "on-default-branch",
3658
+ severity: "error",
3659
+ currentBranch: currentSymbolicBranch,
3660
+ defaultBranch
3661
+ };
3662
+ }
3663
+ return null;
3664
+ }
3323
3665
  // ../../packages/aeg-core/src/branch-topology-gate.ts
3324
3666
  function taskBranchTopologyFields(branch) {
3325
3667
  if (!/^task\/.*\/.*$/.test(branch))
@@ -3609,8 +3951,8 @@ var BIN_EXT = BIN_DIR === DIST_BIN_DIR ? ".js" : ".ts";
3609
3951
  function bin(name) {
3610
3952
  return join2(BIN_DIR, `${name}${BIN_EXT}`);
3611
3953
  }
3612
- function coreCheckRegistry() {
3613
- return [
3954
+ var REGISTRY = [
3955
+ [
3614
3956
  {
3615
3957
  name: "brief-shape",
3616
3958
  run: bin("check-brief-shape"),
@@ -3621,6 +3963,9 @@ function coreCheckRegistry() {
3621
3963
  BRANCH: { optional: true }
3622
3964
  }
3623
3965
  },
3966
+ 0
3967
+ ],
3968
+ [
3624
3969
  {
3625
3970
  name: "doc-coverage",
3626
3971
  run: bin("check-doc-coverage"),
@@ -3636,6 +3981,9 @@ function coreCheckRegistry() {
3636
3981
  GH_TOKEN: { optional: true }
3637
3982
  }
3638
3983
  },
3984
+ 0
3985
+ ],
3986
+ [
3639
3987
  {
3640
3988
  name: "coherence",
3641
3989
  run: bin("check-coherence"),
@@ -3648,6 +3996,9 @@ function coreCheckRegistry() {
3648
3996
  GH_TOKEN: { optional: true }
3649
3997
  }
3650
3998
  },
3999
+ 0
4000
+ ],
4001
+ [
3651
4002
  {
3652
4003
  name: "dispatch-readiness",
3653
4004
  run: bin("check-dispatch-readiness"),
@@ -3657,9 +4008,13 @@ function coreCheckRegistry() {
3657
4008
  AEG_REPO: { optional: true },
3658
4009
  BRANCH: { optional: true },
3659
4010
  GITHUB_TOKEN: { optional: true },
3660
- GH_TOKEN: { optional: true }
4011
+ GH_TOKEN: { optional: true },
4012
+ PREMISE_FILE: { optional: true }
3661
4013
  }
3662
4014
  },
4015
+ 0
4016
+ ],
4017
+ [
3663
4018
  {
3664
4019
  name: "closes-n",
3665
4020
  run: bin("check-closes-n"),
@@ -3674,6 +4029,9 @@ function coreCheckRegistry() {
3674
4029
  GH_TOKEN: { optional: true }
3675
4030
  }
3676
4031
  },
4032
+ 1
4033
+ ],
4034
+ [
3677
4035
  {
3678
4036
  name: "single-plan-pr",
3679
4037
  run: bin("check-single-plan-pr"),
@@ -3686,6 +4044,9 @@ function coreCheckRegistry() {
3686
4044
  GH_TOKEN: { optional: true }
3687
4045
  }
3688
4046
  },
4047
+ 0
4048
+ ],
4049
+ [
3689
4050
  {
3690
4051
  name: "test-plan",
3691
4052
  run: bin("check-test-plan"),
@@ -3697,6 +4058,9 @@ function coreCheckRegistry() {
3697
4058
  BRANCH: { optional: true }
3698
4059
  }
3699
4060
  },
4061
+ 1
4062
+ ],
4063
+ [
3700
4064
  {
3701
4065
  name: "body-bare-digits",
3702
4066
  run: bin("check-body-bare-digits"),
@@ -3712,6 +4076,9 @@ function coreCheckRegistry() {
3712
4076
  GH_TOKEN: { optional: true }
3713
4077
  }
3714
4078
  },
4079
+ 1
4080
+ ],
4081
+ [
3715
4082
  {
3716
4083
  name: "no-disk-state",
3717
4084
  run: bin("check-no-disk-state"),
@@ -3719,6 +4086,9 @@ function coreCheckRegistry() {
3719
4086
  timeoutMs: 15000,
3720
4087
  env: { BASE_SHA: { optional: true } }
3721
4088
  },
4089
+ 0
4090
+ ],
4091
+ [
3722
4092
  {
3723
4093
  name: "registry-gates",
3724
4094
  run: bin("check-registry-gates"),
@@ -3730,6 +4100,9 @@ function coreCheckRegistry() {
3730
4100
  GH_TOKEN: { optional: true }
3731
4101
  }
3732
4102
  },
4103
+ 0
4104
+ ],
4105
+ [
3733
4106
  {
3734
4107
  name: "review-gate",
3735
4108
  run: bin("check-review-gate"),
@@ -3743,6 +4116,9 @@ function coreCheckRegistry() {
3743
4116
  GH_TOKEN: { optional: true }
3744
4117
  }
3745
4118
  },
4119
+ 1
4120
+ ],
4121
+ [
3746
4122
  {
3747
4123
  name: "branch-topology",
3748
4124
  run: bin("check-branch-topology"),
@@ -3755,6 +4131,9 @@ function coreCheckRegistry() {
3755
4131
  GH_TOKEN: { optional: true }
3756
4132
  }
3757
4133
  },
4134
+ 0
4135
+ ],
4136
+ [
3758
4137
  {
3759
4138
  name: "dead-branch-push",
3760
4139
  run: bin("check-dead-branch-push"),
@@ -3766,6 +4145,9 @@ function coreCheckRegistry() {
3766
4145
  GH_TOKEN: { optional: true }
3767
4146
  }
3768
4147
  },
4148
+ 0
4149
+ ],
4150
+ [
3769
4151
  {
3770
4152
  name: "first-push-dispatch",
3771
4153
  run: bin("check-first-push-dispatch"),
@@ -3778,6 +4160,9 @@ function coreCheckRegistry() {
3778
4160
  GH_TOKEN: { optional: true }
3779
4161
  }
3780
4162
  },
4163
+ 0
4164
+ ],
4165
+ [
3781
4166
  {
3782
4167
  name: "doc-coverage-push",
3783
4168
  run: bin("check-doc-coverage-push"),
@@ -3795,6 +4180,9 @@ function coreCheckRegistry() {
3795
4180
  GH_TOKEN: { optional: true }
3796
4181
  }
3797
4182
  },
4183
+ 0
4184
+ ],
4185
+ [
3798
4186
  {
3799
4187
  name: "issue-assignment",
3800
4188
  run: bin("check-issue-assignment"),
@@ -3807,6 +4195,9 @@ function coreCheckRegistry() {
3807
4195
  GH_TOKEN: { optional: true }
3808
4196
  }
3809
4197
  },
4198
+ 0
4199
+ ],
4200
+ [
3810
4201
  {
3811
4202
  name: "evidence-fresh",
3812
4203
  run: bin("check-evidence-fresh"),
@@ -3821,6 +4212,9 @@ function coreCheckRegistry() {
3821
4212
  GH_TOKEN: { optional: true }
3822
4213
  }
3823
4214
  },
4215
+ 1
4216
+ ],
4217
+ [
3824
4218
  {
3825
4219
  name: "reader-resolvable-prose",
3826
4220
  run: bin("check-reader-resolvable-prose"),
@@ -3828,6 +4222,9 @@ function coreCheckRegistry() {
3828
4222
  timeoutMs: 30000,
3829
4223
  env: {}
3830
4224
  },
4225
+ 0
4226
+ ],
4227
+ [
3831
4228
  {
3832
4229
  name: "retired-vocabulary",
3833
4230
  run: bin("check-retired-vocabulary"),
@@ -3835,6 +4232,9 @@ function coreCheckRegistry() {
3835
4232
  timeoutMs: 30000,
3836
4233
  env: {}
3837
4234
  },
4235
+ 0
4236
+ ],
4237
+ [
3838
4238
  {
3839
4239
  name: "doctrine-portability",
3840
4240
  run: bin("check-doctrine-portability"),
@@ -3842,15 +4242,66 @@ function coreCheckRegistry() {
3842
4242
  timeoutMs: 30000,
3843
4243
  env: { BASE_SHA: { optional: true } }
3844
4244
  },
4245
+ 0
4246
+ ],
4247
+ [
3845
4248
  {
3846
4249
  name: "workspace-escape",
3847
4250
  run: bin("check-workspace-escape"),
3848
4251
  scope: "full",
3849
4252
  timeoutMs: 30000,
3850
4253
  env: {}
3851
- }
3852
- ];
4254
+ },
4255
+ 0
4256
+ ],
4257
+ [
4258
+ {
4259
+ name: "changeset-coverage",
4260
+ run: bin("check-changeset-coverage"),
4261
+ scope: "diff",
4262
+ timeoutMs: 15000,
4263
+ env: {}
4264
+ },
4265
+ 0
4266
+ ],
4267
+ [
4268
+ {
4269
+ name: "quoted-command",
4270
+ run: bin("check-quoted-command"),
4271
+ scope: "diff",
4272
+ timeoutMs: 15000,
4273
+ env: {}
4274
+ },
4275
+ 0
4276
+ ],
4277
+ [
4278
+ {
4279
+ name: "main-branch-refusal",
4280
+ run: bin("check-main-branch-refusal"),
4281
+ scope: "full",
4282
+ timeoutMs: 15000,
4283
+ env: {}
4284
+ },
4285
+ 0
4286
+ ],
4287
+ [
4288
+ {
4289
+ name: "token-collection-wired",
4290
+ run: bin("check-token-collection-wired"),
4291
+ scope: "full",
4292
+ timeoutMs: 15000,
4293
+ env: {
4294
+ CLAUDE_PROJECT_DIR: { optional: true },
4295
+ CLAUDE_CODE_SESSION_ID: { optional: true }
4296
+ }
4297
+ },
4298
+ 0
4299
+ ]
4300
+ ];
4301
+ function coreCheckRegistry() {
4302
+ return REGISTRY.map(([spec]) => spec);
3853
4303
  }
4304
+ var CORE_CHECK_RING = Object.fromEntries(REGISTRY.map(([spec, ring]) => [spec.name, ring]));
3854
4305
 
3855
4306
  // src/checks/bin/check-registry-gates.ts
3856
4307
  var CHECK_NAME = "registry-gates";