@attalabs/vinaya 0.21.0 → 0.23.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 (211) hide show
  1. package/README.md +15 -4
  2. package/aeg-root/contracts/archivist-tranche-archivist.md +2 -2
  3. package/aeg-root/contracts/brief-developer.md +1 -0
  4. package/aeg-root/contracts/developer-reviewer.md +3 -3
  5. package/aeg-root/contracts/reviewer-archivist.md +3 -3
  6. package/aeg-root/enforcement.md +28 -21
  7. package/aeg-root/process.md +8 -4
  8. package/aeg-root/roles/archivist.md +2 -2
  9. package/aeg-root/roles/brief-author.md +9 -3
  10. package/aeg-root/roles/developer.md +63 -31
  11. package/aeg-root/roles/planner.md +2 -2
  12. package/aeg-root/roles/principal.md +14 -0
  13. package/aeg-root/roles/reviewer.md +32 -15
  14. package/aeg-root/roles/security.md +15 -5
  15. package/aeg-root/skills/aeg/SKILL.md +9 -5
  16. package/aeg-root/skills/aeg-roles/SKILL.md +2 -2
  17. package/aeg-root/skills/brief-authoring/SKILL.md +39 -27
  18. package/aeg-root/state-machine.md +9 -11
  19. package/aeg-root/templates/brief-template.md +6 -6
  20. package/aeg-root/templates/pr-report-template.md +12 -7
  21. package/aeg-root/tranche-model.md +9 -5
  22. package/dist/checks/bin/check-body-bare-digits.js +667 -148
  23. package/dist/checks/bin/check-branch-topology.js +714 -149
  24. package/dist/checks/bin/check-brief-shape.js +704 -147
  25. package/dist/checks/bin/check-changeset-coverage.js +1046 -166
  26. package/dist/checks/bin/check-closes-n.js +714 -149
  27. package/dist/checks/bin/check-coherence.js +729 -156
  28. package/dist/checks/bin/check-dead-branch-push.js +663 -144
  29. package/dist/checks/bin/check-dispatch-readiness.js +728 -155
  30. package/dist/checks/bin/check-doc-coverage-push.js +838 -261
  31. package/dist/checks/bin/check-doc-coverage.js +838 -261
  32. package/dist/checks/bin/check-doctrine-no-procedures.js +4794 -0
  33. package/dist/checks/bin/check-doctrine-portability.js +799 -155
  34. package/dist/checks/bin/check-evidence-fresh.js +1132 -206
  35. package/dist/checks/bin/check-exec-bits.js +4931 -0
  36. package/dist/checks/bin/check-first-push-dispatch.js +716 -151
  37. package/dist/checks/bin/check-issue-assignment.js +714 -149
  38. package/dist/checks/bin/check-main-branch-refusal.js +663 -144
  39. package/dist/checks/bin/check-no-disk-state.js +663 -144
  40. package/dist/checks/bin/check-pr-report-density.js +4461 -0
  41. package/dist/checks/bin/check-quoted-command.js +741 -166
  42. package/dist/checks/bin/check-reader-resolvable-prose.js +768 -173
  43. package/dist/checks/bin/check-registry-gates.js +726 -154
  44. package/dist/checks/bin/check-retired-vocabulary.js +760 -165
  45. package/dist/checks/bin/check-review-gate.js +783 -148
  46. package/dist/checks/bin/check-single-plan-pr.js +663 -144
  47. package/dist/checks/bin/check-test-plan.js +664 -145
  48. package/dist/checks/bin/check-token-collection-wired.js +665 -146
  49. package/dist/checks/bin/check-token-report.js +4509 -0
  50. package/dist/checks/bin/check-workspace-escape.js +1129 -183
  51. package/dist/index.js +8458 -5403
  52. package/package.json +1 -1
  53. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/actions.ts +173 -0
  54. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/anchored-region.ts +113 -0
  55. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/archive-task.ts +206 -0
  56. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/baseline-capture.ts +65 -0
  57. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/blast-radius-domains.ts +192 -0
  58. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/branch-topology-gate.ts +85 -0
  59. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/brief-validation.ts +511 -0
  60. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/claude-code-transcript.ts +460 -0
  61. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/coherence-checks.ts +787 -0
  62. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/dead-branch-push-audit.ts +55 -0
  63. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/dead-branch-push-guard.ts +77 -0
  64. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/derive-section7.ts +66 -0
  65. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/derive-tranche.ts +94 -0
  66. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/diagram-model.ts +372 -0
  67. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/direct-main-push.ts +39 -0
  68. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/dispatch-gate.ts +224 -0
  69. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/doc-owners.ts +314 -0
  70. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/build-doc-nav.ts +38 -0
  71. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/docs-coherence.ts +136 -0
  72. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/index.ts +29 -0
  73. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/legacy-anchors.ts +48 -0
  74. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/nav-helpers.ts +17 -0
  75. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/node-route.ts +134 -0
  76. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/parse-doc.ts +43 -0
  77. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/published-prose.ts +306 -0
  78. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/surfaced-manifest.ts +89 -0
  79. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/docs/types.ts +33 -0
  80. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/doctrine-portability.ts +170 -0
  81. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/doctrine-source.ts +23 -0
  82. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/ensure-label.ts +28 -0
  83. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/file-classify.ts +51 -0
  84. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/first-push-dispatch-gate.ts +80 -0
  85. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/gate-audience.ts +168 -0
  86. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/index.ts +301 -0
  87. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/issue-assignment.ts +102 -0
  88. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/issue-validation.ts +746 -0
  89. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/leftover-detection.ts +68 -0
  90. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/local-anchor-coverage.ts +245 -0
  91. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/main-branch-refusal.ts +64 -0
  92. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/manifest-validity.ts +81 -0
  93. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/markdown-table.ts +76 -0
  94. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/metering-io-guard.ts +119 -0
  95. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/milestone-validation.ts +240 -0
  96. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/no-disk-state.ts +50 -0
  97. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/parse-ledger.ts +77 -0
  98. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/parse-registry.ts +105 -0
  99. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/parse-token-report.ts +165 -0
  100. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/parse-tranche.ts +183 -0
  101. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/pr-tier.ts +81 -0
  102. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/premise-check.ts +125 -0
  103. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/quoted-command.ts +275 -0
  104. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/reader-resolvable-prose.ts +320 -0
  105. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/registry-checks.ts +255 -0
  106. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/registry-parse.ts +164 -0
  107. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/registry-scaffold.ts +216 -0
  108. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/report-tokens.ts +261 -0
  109. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/retired-vocabulary.ts +163 -0
  110. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/review-gate.ts +269 -0
  111. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/single-plan-pr.ts +73 -0
  112. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/state-machine-model.ts +269 -0
  113. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/state-source.ts +14 -0
  114. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/status-block.ts +8 -0
  115. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/sum-ledger.ts +26 -0
  116. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/symbol-collisions.ts +78 -0
  117. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/test-plan-gate.ts +104 -0
  118. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/test-plan-section.ts +65 -0
  119. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/types.ts +174 -0
  120. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/verdict-extraction.ts +140 -0
  121. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/vocabulary-citation.ts +114 -0
  122. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/waiver-label.ts +52 -0
  123. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/workspace-escape.ts +172 -0
  124. package/studio-standalone/apps/vinaya-studio/web/.next/BUILD_ID +1 -1
  125. package/studio-standalone/apps/vinaya-studio/web/.next/build-manifest.json +3 -3
  126. package/studio-standalone/apps/vinaya-studio/web/.next/prerender-manifest.json +3 -3
  127. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.html +1 -1
  128. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.rsc +1 -1
  129. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  130. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  131. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  132. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  133. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  134. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page/server-reference-manifest.json +2 -2
  135. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  136. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  137. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/api/coherence/route.js.nft.json +1 -1
  138. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page/server-reference-manifest.json +2 -2
  139. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page.js.nft.json +1 -1
  140. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page_client-reference-manifest.js +1 -1
  141. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page/server-reference-manifest.json +2 -2
  142. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page.js.nft.json +1 -1
  143. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page_client-reference-manifest.js +1 -1
  144. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page/server-reference-manifest.json +2 -2
  145. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page.js.nft.json +1 -1
  146. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page_client-reference-manifest.js +1 -1
  147. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page/server-reference-manifest.json +2 -2
  148. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page.js.nft.json +1 -1
  149. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page_client-reference-manifest.js +1 -1
  150. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page/server-reference-manifest.json +2 -2
  151. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page.js.nft.json +1 -1
  152. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page_client-reference-manifest.js +1 -1
  153. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page/server-reference-manifest.json +2 -2
  154. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page.js.nft.json +1 -1
  155. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page_client-reference-manifest.js +1 -1
  156. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page/server-reference-manifest.json +2 -2
  157. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page.js.nft.json +1 -1
  158. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page_client-reference-manifest.js +1 -1
  159. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page/server-reference-manifest.json +2 -2
  160. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page.js.nft.json +1 -1
  161. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page_client-reference-manifest.js +1 -1
  162. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/[root-of-the-server]__02a-3g8._.js +1 -1
  163. 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
  164. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0053k9k._.js +1 -1
  165. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0112h-k._.js +1 -1
  166. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__02c71kv._.js +1 -1
  167. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0o771t1._.js +1 -1
  168. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0puovz5._.js +1 -1
  169. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1hs0dcu._.js +1 -1
  170. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__0ozbaq0._.js → [root-of-the-server]__1mcitst._.js} +1 -1
  171. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1wc4-ip._.js +1 -1
  172. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_03x_w6q._.js +1 -1
  173. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0gvm3og._.js +1 -1
  174. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0lwxg63._.js +1 -1
  175. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0o54suy._.js +1 -1
  176. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1-6rzip._.js +1 -1
  177. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1fqw88f._.js +1 -1
  178. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1mrtj0f._.js +1 -1
  179. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1n0cnq-._.js +1 -1
  180. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/apps_vinaya-studio_web_src_app_studio_06it6s-._.js +1 -1
  181. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/node_modules_1vo08dj._.js +2 -2
  182. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_animate_components_index_ts_186fje1._.js +1 -1
  183. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_brutal_components_index_ts_0n_lcc4._.js +1 -1
  184. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_retro_components_index_ts_0wvpm_z._.js +1 -1
  185. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_retro_components_index_ts_1_cfi48._.js +1 -1
  186. package/studio-standalone/apps/vinaya-studio/web/.next/server/middleware-build-manifest.js +3 -3
  187. package/studio-standalone/apps/vinaya-studio/web/.next/server/pages/500.html +1 -1
  188. package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.js +1 -1
  189. package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.json +3 -3
  190. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/00pi8vhg8w6gi.js +1 -0
  191. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0r4i_ks9z02bw.js → 03q0q9n6-xah8.js} +1 -1
  192. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{2_k6j1o9q5nn4.js → 0jer_drkl1e4r.js} +4 -4
  193. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/0vc2u252q5q6o.js +1 -0
  194. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1k916ih3p4nsg.js → 13g16cu00g570.js} +1 -1
  195. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{2hmannd4bjhzy.js → 1sfxfunirkcr6.js} +1 -1
  196. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1t2kft7bxzuxn.js → 206ajg8f1a-_h.js} +1 -1
  197. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1hfhxjy577l5d.js → 20x-t0a0v129z.js} +1 -1
  198. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{25kbt5k-xb2a5.js → 279qq4twinc97.js} +1 -1
  199. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{112g08xpx3kro.js → 2ka8dg687auhj.js} +1 -1
  200. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/2ou_81ahqw31e.js +1 -0
  201. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0up5x3jg-cwov.js → 2rn89uwtf2lwc.js} +1 -1
  202. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{3mqu_uhluy19i.css → 3qc67qhcvbg0o.css} +1 -1
  203. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1yqs2zgvwa4p1.js → 3zugx9esh2x51.js} +1 -1
  204. package/studio-standalone/apps/vinaya-studio/web/package.json +2 -2
  205. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/0_jnwbarv-cqk.js +0 -1
  206. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/1ybrihl5_aocy.js +0 -1
  207. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/3r5efmleneaco.js +0 -1
  208. /package/studio-standalone/_node_modules/@attalabs/vinaya/studio-standalone/_node_modules/@attalabs/{aeg-core → vinaya/studio-standalone/_node_modules/@attalabs/aeg-core}/bin/verify-coherence.ts +0 -0
  209. /package/studio-standalone/apps/vinaya-studio/web/.next/static/{crNCHQ9uAgKOYC6DKkZma → 5xy_GA7G5KRuE3HDumIiw}/_buildManifest.js +0 -0
  210. /package/studio-standalone/apps/vinaya-studio/web/.next/static/{crNCHQ9uAgKOYC6DKkZma → 5xy_GA7G5KRuE3HDumIiw}/_clientMiddlewareManifest.js +0 -0
  211. /package/studio-standalone/apps/vinaya-studio/web/.next/static/{crNCHQ9uAgKOYC6DKkZma → 5xy_GA7G5KRuE3HDumIiw}/_ssgManifest.js +0 -0
@@ -149,7 +149,7 @@ The Reviewer role has two specializations — code review (`roles/reviewer.md`)
149
149
  - **Write:** PR review verdicts and review comments only (a Class 2 object) — **nothing to disk**. The verdict is the structured block in the role doc (`APPROVE | REQUEST CHANGES` for code, with a `SPEC CONFORMANCE` line; `PASS | FAIL` for security). A REQUEST CHANGES sets the PR's review decision, which is the derived `changes-requested` status — the Reviewer writes no status field. **Plus a one-line token report** in the same verdict comment — numeric cells `—` when the role is **operator-metered** — the host exposes no usage figure to the agent — which is the reviewing role's usual case and the one sanctioned reason for a blank token cell (`tranche-model.md` §12). The per-task Archivist reads this report and appends the ledger row (`tranches/<name>.tokens.md`) at close-out (§13 append-only artifacts; `tranche-model.md` §12).
150
150
  - **Cannot:** edit code, specs, skills, PM docs; mutate labels; or merge. The Reviewer reports; the Developer remediates; the Principal merges.
151
151
  - **Independence:** fresh context (a separate invocation), never reviewing work it authored. This is the whole point.
152
- - **Escalation:** a finding that exceeds review authority is marked `[ESCALATE] severity:strategy|product` and routed to the Planner or Principal.
152
+ - **Escalation:** a concern that exceeds review authority is posted via `--escalate authority | strategy | product` — its own review outcome, never a finding — and routed to the Planner (`strategy`) or Principal (`authority`/`product`).
153
153
 
154
154
  Because the Reviewer never mutates a canonical artifact, it has no column. Its position is Phase 10 (`process.md`): code-reviewer pass → security pass → Principal code review → Brief Author spec review → **Phase 11 Verification (`roles/developer.md` § Verification)** → merge.
155
155
 
@@ -233,7 +233,7 @@ When a Developer reaches a decision not covered by the brief, it escalates throu
233
233
 
234
234
  **`severity: product`** — requires a Principal decision. Rare; reserved for Type 1 decisions discovered during execution. Adds `vinaya/needs:principal-input`. If the Principal is present, they decide and reply; if not, the item stays labeled `vinaya/needs:principal-input` and the Developer terminates, resuming via a follow-up dispatch after the window.
235
235
 
236
- While blocked, the task carries a `vinaya/blocked` label (the one status with no native forge fact). The Reviewer uses the same severity vocabulary for `[ESCALATE]` findings.
236
+ While blocked, the task carries a `vinaya/blocked` label (the one status with no native forge fact). The Reviewer's own `--escalate authority | strategy | product` outcome uses this same class vocabulary.
237
237
 
238
238
  ### Type 1 decisions during execution
239
239
 
@@ -305,11 +305,11 @@ The lowest-commitment way to run AEG: read-only over a team's existing process.
305
305
  - **Typecheck, tests** — standard CI gates; always blocking.
306
306
  - **Issue template / no forbidden fields** — a required Issue template + a CI check reject planning metadata (priority/estimates/points) on task Issues, keeping them execution-only.
307
307
  - **Brief validation** — the Archivist's `brief-validation` job runs `packages/aeg-core/bin/verify-brief.ts` against the PR body and checks presence of every required brief section (Tier, `For:` model attribution, `Project:` — both read from the PR body's header block, before the first `##` heading, the same region the post-merge Archivist's provenance assembly reads — tagged Test Plan, surface map, doc-update list, worktree Step 0, stop conditions, autonomy clause, `Closes #N`); flags malformed briefs (`vinaya/needs:brief-correction`) and fails CI. **The trigger is the body, not the branch (`fix/brief-gate-nontask`):** the gate runs when the branch is `task/<tranche>/<n>` **or** the body is brief-shaped (`isBriefShaped` — ≥2 of surface map / doc-update list / stop conditions / autonomy clause, matched on `stripCode`'d text so a brief *quoted inside a fence* stays exempt). Bodies that are neither still bypass — that exemption is for an ordinary non-AEG PR (a one-line dependency bump) which carries no brief and must not be forced to grow one. The old branch-only bypass was the wrong proxy for it: a standalone `fix/*` brief **is** a brief, and it skipped every section check — confirmed live on `fix/studio-tranche-href`, which shipped with no §7 documentation-update list because `checkDocUpdateList`, the checker that exists for exactly that, never ran. `Closes #N` remains **task-branch-only** (`BriefSectionsOptions.requireClosesN`): a standalone fix brief has no task Issue to close, and a `plan/*` PR is *forbidden* to carry one by the plan-PR guard below — requiring it there would make the two gates jointly unsatisfiable. The same validator also runs at **authoring time** as the `brief-shape` check — `PR_BODY="$(cat brief.md)" vinaya check brief-shape` (on this repo's toolchain, also `bun packages/aeg-core/bin/verify-brief.ts --body-file <brief.md>`) — before a PR or even a branch exists, so a Brief Author gates a brief before dispatch rather than after the Developer has done the work (`skills/brief-authoring/SKILL.md` protocol step 4); with no `BRANCH`, the branch is read from the brief's own Step 0 `git worktree add … -b` line. **Includes the plan-PR Closes guard**: a `plan/*` branch whose PR body carries `Closes #N` fails CI before the non-task bypass even runs — a plan PR creates Issues, it does not resolve one (`roles/planner.md`); this closed a confirmed pattern of plan PRs prematurely closing task Issues on merge. **Real**, now the `Brief Validation` step (9/9) of the AEG gate suite job in `.github/workflows/forge-lifecycle.yml`. Presence-only — it cannot judge whether a Test Plan item is truly scriptable or whether a declared `unit-tests-only` is justified by the surface map; those remain Reviewer + Verification judgment. Same enforcement substrate as above.
308
- - **Per-task Archivist close-out** — `.github/workflows/archivist.yml::post-merge` (`packages/aeg-core/bin/archive-task.ts`) runs on every push to `main`, resolves the merge commit's PR via `gh api repos/{owner}/{repo}/commits/{sha}/pulls`, and — for task-branch PRs only — assembles and posts the Archivist provenance block (`roles/archivist.md` item 8) and explicitly closes the task's Issue, confirming the closed state before exiting. Idempotent **per PR**, not per Issue (an Issue can legitimately accrue multiple merged PRs over its life; idempotency never spans PRs): skips silently if the PR already carries a provenance comment. Skips silently on non-task branches (`plan/*`, `fix/*`, …). Fails loud (non-zero exit) on any `gh`/permission error — never a silent no-op. Real, installed with `contents: read`, `issues: write`, `pull-requests: write` permissions. Does not automate the Tranche Archivist or items 2–7 of per-task close-out (docs coherence, `docs-index.md`, token ledger) — those remain dispatched-Archivist judgment work.
308
+ - **Per-task Archivist close-out** — `.github/workflows/vinaya-archivist.yml::post-merge` (`packages/aeg-core/bin/archive-task.ts`) runs on every push to `main`, resolves the merge commit's PR via `gh api repos/{owner}/{repo}/commits/{sha}/pulls`, and — for task-branch PRs only — assembles and posts the Archivist provenance block (`roles/archivist.md` item 8) and explicitly closes the task's Issue, confirming the closed state before exiting. Idempotent **per PR**, not per Issue (an Issue can legitimately accrue multiple merged PRs over its life; idempotency never spans PRs): skips silently if the PR already carries a provenance comment. Skips silently on non-task branches (`plan/*`, `fix/*`, …). Fails loud (non-zero exit) on any `gh`/permission error — never a silent no-op. Real, installed with `contents: read`, `issues: write`, `pull-requests: write` permissions. Does not automate the Tranche Archivist or items 2–7 of per-task close-out (docs coherence, `docs-index.md`, token ledger) — those remain dispatched-Archivist judgment work.
309
309
  - **Manifest integrity** — `verify-docs --full` and the coherence oracle validate the doc-owners manifest: pointer existence (M1), glob syntax (M2 advisory), and duplicate globs (M3). There is no decision-number sequencing: the log it validated is gone.
310
310
  - **Closes #N gate** — task-branch PRs must declare `Closes #<its-issue>` in the PR body; absence fails CI. Non-task branches bypass this forward direction automatically. Real, installed at `.github/workflows/forge-lifecycle.yml::closes-n-gate`. Same enforcement substrate as above. **Forge-native-tranche fix (`fix/closes-n-forge-native`):** the gate's scoped `loadTrancheFiles(null, onlySlug)` call discovers which tranches exist by listing `aeg-root/tranches/*.md` filenames — a tranche with zero topology file never entered that enumeration, so the forge derivation was never invoked for it despite the tranche already being fully Milestone-capable, and the gate failed every such PR with a misleading "no topology file found." Fixed by falling back to a direct forge derivation (the Milestone-existence check plus the file-and-forge composition, today `indexTrancheMilestonesAsync` + `mergeFileTopology`) when the requested `onlySlug` isn't found via files, gated on an actual open Milestone existing so an unrecognized branch slug still fails honestly — the scoped-path counterpart to `verify-dispatch.ts`'s `otherActiveTrancheSlugs` fix. **Reverse direction (`fix/closes-n-reverse`):** a `Closes #N` that resolves to a real AEG task Issue (title matches the `[<tranche-slug>] <task-id>...` convention and carries a `vinaya/tranche:<slug>` label) now requires the branch to actually be named `task/<tranche-slug>/<task-id>`, regardless of what the branch itself is called — closing the blind spot that let a mis-named branch implement a real task Issue with zero forge-visible status. One batched forge query (`fetchTaskIssueRefs`) resolves each referenced Issue's task identity before `checkClosesN` runs. **Code-span hardening (`fix/closes-gate-hardening`):** both the pre-merge gate (`checkClosesN` in `brief-validation.ts`) and the coherence-side parse (`extractClosesReferences` in `coherence-checks.ts`) now `stripCode` the body before matching the closing keyword, as GitHub's own auto-close parser ignores `Closes #N` inside a code span or fenced block. Inline spans of **any backtick-run length** are covered (`` `x` ``, `` ``x`` ``, …) via CommonMark's `(`+)…\1` matched-run rule — the double-backtick form was a false-green in the first cut (peeled as two empty spans). Fenced blocks are matched by a line scanner that pairs a fence with its own closer by **character and run length**: `~~~` tilde fences, info strings (```` ```js ````), and runs longer than three (```` `````` ````) all strip correctly, and an unclosed fence runs to end of body as GitHub renders it — the earlier `` /```[\s\S]*?```/g `` regex missed all three. The keyword set matches GitHub's own: `close`/`closes`/`closed`, `fix`/`fixes`/`fixed`, `resolve`/`resolves`/`resolved`. Before this, a body whose only `Closes #N` was backticked passed the gate **green** yet merged **without** closing its Issue, then read red on every open PR via A3 `auto-close-misfire`; "verify-docs green" now implies "GitHub will auto-close" for fenced + inline-code forms. 4-space **indented** code blocks are stripped too, conservatively: a ≥4-column-indented run counts as code only when it follows a blank line *and* is not inside a list — since within a list item that indentation is the item's own content indent, which GitHub *does* auto-close (blanking it would be a false-red, the brief's over-strip stop condition). The strip runs on the **whole body, before any region is sliced out of it** — never on a slice. Every rule in it is block-structural (a fence pairs with its own closer; an indented run is code only after a blank line and outside list context), so a fragment strips differently from the same text in place: stripping the sliced `AEG:CLOSES` region blanked an anchor indented inside a list item — list content GitHub *does* auto-close — and the Archivist's `extractIssue` returned no Issue, stranding it on merge exactly as before. Markers are HTML comments and survive the strip, so selecting the region from stripped text loses nothing and subsumes the decoy protection: a decoy anchor inside code never survives to be sliced. The same grammar governs `maskCode`, the index-preserving variant `anchoredRegion` runs to find the `AEG:*` markers themselves — it is **upstream** of every `stripCode` call, so while it stayed on the naive fence/inline regexes a decoy `AEG:CLOSES` anchor inside a tilde fence, a ≥4-backtick fence, a double-backtick span, or an indented block won the region outright and the gate resolved a **wrong** Issue number (worse than the strandings above: the post-merge Archivist's `extractIssue` would explicitly close an unrelated Issue). Both now delegate to one pair of scanners, differing only in what they emit per code line — nothing for `stripCode`, same-length filler for `maskCode` — so a divergence is a compile-level impossibility rather than a convention. This hardens all five anchored fields (`CLOSES`, `PROJECT`, `TIER`, `PREMISE`, `TEST-PLAN`) at once, not just the closing reference. `stripCode` normalises `\r\n`/`\r` to `\n` before any of these scanners run: the fence scanners anchor per line, and JS's `.`/`$` never match `\r`, so a CRLF body opened no fence at all and let a fenced `Closes #N` walk free — the same false-green along a new axis, and it hit exactly the web-UI-authored bodies this CI backstop exists for (HTML normalises textarea newlines to CRLF on submit). The closing-keyword separator is **bounded** (`\s{0,8}:?\s{0,8}`, identical in both parsers): two adjacent unbounded `\s*` groups backtrack quadratically on `closes` + long whitespace + no `#` — ~2.0 s at GitHub's 65,536-char body cap, run twice on the fail path — where the bound is 0.1 ms. **Known residual:** a genuine indented code block *nested inside a list* is therefore left unstripped — the deliberately safe direction of that trade. A `Closes #N` surviving only inside code fails with an actionable message pointing at a bare reference in the `AEG:CLOSES` anchor. `stripCode` is the one shared stripper, exported from `anchored-region.ts` (no duplicated regex).
311
311
  - *(The practitioner-facing map of every enforcement mechanism — prevention, detection, audit — lives in `aeg-root/enforcement.md`; this section remains the normative gate registry.)*
312
- - **Tool-layer forge gates** — the earliest enforcement point: a PreToolUse hook (`.claude/hooks/check-forge-gates.sh`, wired in `.claude/settings.json`) denies raw `gh pr create`/`gh pr edit --body*`/`gh issue create`/`gh issue edit --body*` (and `gh api` creation POSTs), directing agents to the validated wrappers `packages/aeg-core/bin/open-pr.ts` (runs verify-brief + verify-docs `--pr` + the Closes #N gate locally, calls `gh` only on green) and `bin/open-issue.ts` (a task Issue with a `vinaya/tranche:*` label must carry the full eight-field Planner rationale — `checkIssueRationale`, planner-brief contract, **and pass three content checks on what those fields say, `checkBlastRadiusScope` (the declared surface may not reach a shared collision domain — live-derived `packages/*` workspace members, built-in cross-cutting defaults, plus any `vinaya.config.json` `blastRadius.extraDomains` entries — that no declared project owns, absent a second **registered** project or a `blast-radius-ack:` line), `checkNoBriefContent` (no brief-shaped section in the Issue), `checkRationaleNamesDocs` (the rationale names a concrete doc/skill path, or the `no-doc-surface` sentinel). `checkConflictCompleteness` warns on an undeclared collision-domain overlap and never blocks**). Prevention, not detection: a malformed PR/Issue body is refused at the agent's own tool call and never reaches the forge; the CI gates below re-run the identical aeg-core checks purely as a backstop for non-hook writers. Also enforced at the same layer: title grammar (`checkForgeTitle`, both wrappers), the single-plan-PR guard (`checkSinglePlanPr` — a diff touching a tranche's topology file is refused when another OPEN PR already touches that same tranche's topology file), `gh api` PATCH/curl write-method denies, and a `.husky/pre-push` gate refusing `task/<tranche>/<id>` pushes whose id has no topology row (mechanical). Operational rule: restart running agent sessions after merging hook/settings changes — hooks load at session start. Same mechanism as skill-check enforcement and the T9 merge gate.
312
+ - **Tool-layer forge gates (ring 0)** — the earliest enforcement point: a tool-interception hook, wired into the agent's own host so it runs before any raw forge-mutating call reaches GitHub, denies raw `gh pr create`/`gh pr edit --body*`/`gh issue create`/`gh issue edit --body*` (and `gh api` creation POSTs), directing agents to the validated wrappers `packages/aeg-core/bin/open-pr.ts` (runs verify-brief + verify-docs `--pr` + the Closes #N gate locally, calls `gh` only on green) and `bin/open-issue.ts` (a task Issue with a `vinaya/tranche:*` label must carry the full eight-field Planner rationale — `checkIssueRationale`, planner-brief contract, **and pass three content checks on what those fields say, `checkBlastRadiusScope` (the declared surface may not reach a shared collision domain — live-derived `packages/*` workspace members, built-in cross-cutting defaults, plus any `vinaya.config.json` `blastRadius.extraDomains` entries — that no declared project owns, absent a second **registered** project or a `blast-radius-ack:` line), `checkNoBriefContent` (no brief-shaped section in the Issue), `checkRationaleNamesDocs` (the rationale names a concrete doc/skill path, or the `no-doc-surface` sentinel). `checkConflictCompleteness` warns on an undeclared collision-domain overlap and never blocks**). Prevention, not detection: a malformed PR/Issue body is refused at the agent's own tool call and never reaches the forge; the CI gates below re-run the identical aeg-core checks purely as a backstop for non-hook writers. Also enforced at the same layer: title grammar (`checkForgeTitle`, both wrappers), the single-plan-PR guard (`checkSinglePlanPr` — a diff touching a tranche's topology file is refused when another OPEN PR already touches that same tranche's topology file), `gh api` PATCH/curl write-method denies, and a `.husky/pre-push` gate refusing `task/<tranche>/<id>` pushes whose id has no topology row (mechanical). On this repo's shipped reference host, this hook type is a `PreToolUse` hook (`.claude/hooks/check-forge-gates.sh`, wired in `.claude/settings.json`) — one instance of the pattern, not the concept itself; see `tranche-model.md` §12 for how this doctrine names its one concrete example. Operational rule: restart running agent sessions after merging hook/settings changes — hooks load at session start. Same mechanism as skill-check enforcement and the T9 merge gate.
313
313
  - **Single-plan-PR CI backstop** — `checkSinglePlanPr` (`packages/aeg-core/src/single-plan-pr.ts`) was extracted from `open-pr.ts` (previously private to that wrapper) so the identical predicate could also run forge-side: `.github/workflows/forge-lifecycle.yml::single-plan-pr-gate` re-fetches this PR's touched files plus every other open PR's touched files and fails CI on the same violation the ring-0 hook refuses locally. Closes the gap where a PR opened directly via the GitHub web UI bypasses `open-pr.ts` entirely. No-ops (never fires) for an ordinary task-branch PR, since its diff never touches a tranche topology file. **Dormant in this repo entirely, as of the forge-native cutover:** a plan is now a Milestone plus labeled Issues, and `aeg-root/tranches/` holds no active topology file for a diff to collide over. The guard is kept, not deleted, because it is correct and live for any repo that does keep plans as files — but nothing here can trip it, and a gate that cannot fire should say so rather than read as active protection. One implementation, two enforcement points — no second copy of the predicate.
314
314
  - **Coherence oracle (A1/A2/A3/T1/T2/T3/D1/M1/M3)** — `packages/aeg-core/bin/verify-coherence.ts` runs against every PR and genuinely blocks CI — the CLI's own exit code, non-zero on any `fail`-status check, is what the `coherence-gate` job exits with. Failures in A1 (closed-without-merge), A2 (archived-without-provenance), A3 (auto-close-misfire), T1 (phantom-issue-ref), T2 (orphan-task — **plan PRs only, see below**), T3 (tbd-in-active-tranche), D1 (dispatched-on-unmet-deps), M1 (manifest-dangling), and M3 (manifest-duplicate-glob) fail CI. L1–L5 and M2 are advisory (info-only) — every `checkL*` returns `status: info`, so a premature-archive, lifecycle-hygiene, Milestone-attachment-drift, or open-Milestone-all-closed finding is surfaced for a human to investigate but never fails CI. On A1 failures the relevant Issues receive the `vinaya/incoherent` label (Section 14). Real, installed at `.github/workflows/forge-lifecycle.yml::coherence-gate`. Same enforcement substrate as above. **The job's repo-state inputs (topology files, tranche list) are read from a freshly-fetched `origin/main` — not the checkout's `refs/pull/N/merge`, which GitHub materializes lazily and can lag behind main (5+ false-red cycles, 2026-07-03/04). A plan PR's own topology diff still reads from its head ref.**
315
315
  - **Planner→Brief rationale completeness (R1)** — the same coherence oracle's **R1** check re-runs `checkIssueRationale` **and `checkProjectsRegistered`** (`packages/aeg-core`) against every open task Issue's body, batched per active tranche alongside T2. A non-grandfathered Issue missing any of the eight `contracts/planner-brief.md` rationale fields — or whose `Project:` field names a project with no row in the project registry — fails CI. Paired with the ring-0 creation gate (`bin/open-issue.ts`, same tool-layer-forge-gates row above) — R1 is the continuous half, the hook is the point-of-creation half; one grammar, two enforcement points (`aeg-root/enforcement.md`). Pre- Issues are grandfathered by explicit Issue number (`R1_GRANDFATHERED_ISSUES`), reported `info`, never blocking — see Section 15b. **Real.** Moves this seam's rationale-completeness half from Trusted (below) to Enforced; the "role doc matches contract prose" half of contract conformance remains Trusted.
@@ -613,13 +613,11 @@ Sibling to `verify-docs.ts`/`verify-coherence.ts`, same thin-CLI-shim discipline
613
613
 
614
614
  **The default-mode composite ships as the `dispatch-readiness` check** (`vinaya check dispatch-readiness`, branch-scoped) — see `enforcement.md`'s dispatch row for its known parity gap (prior-tranche-archival always reports empty). The `--premise`/`--simulate`/`--check-baseline` modes below have no shipped `vinaya` equivalent yet.
615
615
 
616
- **Usage (this repo's toolchain):**
617
- ```
618
- bun packages/aeg-core/bin/verify-dispatch.ts <tranche> <n>
619
- bun packages/aeg-core/bin/verify-dispatch.ts <tranche> <n> --premise <body-file>
620
- bun packages/aeg-core/bin/verify-dispatch.ts <tranche> <n> --simulate <body-file>
621
- bun packages/aeg-core/bin/verify-dispatch.ts <tranche> <n> --check-baseline <file>
622
- ```
616
+ **Usage (this repo's toolchain)** — four independent invocation forms, not a sequence:
617
+ - Default mode: `bun packages/aeg-core/bin/verify-dispatch.ts <tranche> <n>`
618
+ - Premise re-assertion: `bun packages/aeg-core/bin/verify-dispatch.ts <tranche> <n> --premise <body-file>`
619
+ - Simulate mode: `bun packages/aeg-core/bin/verify-dispatch.ts <tranche> <n> --simulate <body-file>`
620
+ - Baseline compare: `bun packages/aeg-core/bin/verify-dispatch.ts <tranche> <n> --check-baseline <file>`
623
621
 
624
622
  **Default mode composes three checks:**
625
623
 
@@ -9,7 +9,7 @@ The brief itself carries no anchor comments: it rides into the PR body as the *r
9
9
 
10
10
  ---
11
11
 
12
- **For:** [model + environment, e.g. "Sonnet (coding-agent CLI on a dev machine, dispatched locally, unattended)"]
12
+ **For:** [model + environment, e.g. "your-model (coding-agent CLI on a dev machine, dispatched locally, unattended)"]
13
13
  **Reason:** [why this capability level fits this task — real reasoning against the task, not "because it's good"]
14
14
  **Owner:** [who owns the task — the Principal, by default]
15
15
  **Goal:** [one sentence: what ships]
@@ -22,7 +22,7 @@ You are the AEG Developer. Read `aeg-root/roles/developer.md` first[, then the h
22
22
 
23
23
  - **Tranche:** [`tranche-slug`], task [n], Issue #[N]. Branch `task/[tranche-slug]/[n]`. `Depends-on: [—|ids]`, `Conflicts-with: [—|ids]`. Confirm `READY TO DISPATCH` at your own Step 0.
24
24
  - **Read Issue #[N] in full** for the complete rationale — do not re-derive it.
25
- - [CONTEXT — the Planner's rationale carried forward (boundary, blast radius, traps), what was previously validated, what is settled and must not be re-litigated, and everything your own Dig confirmed about the current surface. If it isn't in the brief, it doesn't exist.]
25
+ - [CONTEXT — the Planner's rationale carried forward (boundary, blast radius, traps), what was previously validated, what is settled and must not be re-litigated, and everything your own Dig confirmed about the current surface. If it isn't in the brief, it doesn't exist. No behavioural fact about code belongs here as prose — a `Premise:` pin or a fenced command with its executed output is the only form (skill §2's rule).]
26
26
 
27
27
  ## 3. Technical dependencies
28
28
 
@@ -58,9 +58,9 @@ git worktree add .worktrees/task/[tranche-slug]/[n] -b task/[tranche-slug]/[n] o
58
58
 
59
59
  On any failure: STOP and report.
60
60
 
61
- ## 6. Numbered parts — commit and push after EACH part (push-per-Part)
61
+ ## 6. Numbered parts — commit after EACH part; push once, before opening the PR
62
62
 
63
- 1. **Part 1:** [exact files + exact function/type signatures + constraints — not prose]
63
+ 1. **Part 1:** [exact files + exact function/type signatures + constraints — not prose. A Part that depends on a fact about current code opens with the fenced command that establishes it, followed by the executed output (skill §2's rule).]
64
64
  2. **Part 2:** [next bounded unit of work]
65
65
 
66
66
  ## 7. Documentation-update list
@@ -69,7 +69,7 @@ On any failure: STOP and report.
69
69
 
70
70
  ## 8. Verification before claiming done
71
71
 
72
- - [the repo's static gates, by command — this repo: `bun run typecheck`, `bun run test`, lint, build]
72
+ - [the repo's static gates, by command — this repo: `bun run typecheck`, lint, build; `bunx turbo test --affected` per Part — the full `bun run test` suite is CI's to run, on the one push, never the Developer's to run locally]
73
73
  - [every blast-radius consumer named in §4 re-verified, by name]
74
74
  - `roles/developer.md`'s tier checklist genuinely satisfied, and `PR_BODY="$(cat <body-file>)" vinaya check doc-coverage` green. (On this repo's toolchain, `PR_BODY="$(cat <body-file>)" bun packages/aeg-core/bin/verify-docs.ts --pr` runs both as one command.)
75
75
 
@@ -90,7 +90,7 @@ STOP and report if: pre-flight fails; [the Planner's stop-and-escalate condition
90
90
  - [forbidden patterns for this task — deferred features, off-limits paths]
91
91
  - Never write status anywhere; never add execution metadata to the tranche file.
92
92
 
93
- > **Autonomy:** Do not stop to ask clarifying questions. For any ambiguity not covered by a Section 10 stop condition, choose the most reasonable option consistent with this brief, record the choice in the PR body, and continue. Halt only for the explicit Section 10 stop conditions — and when you halt, record the blocker in the PR body or an Issue comment rather than waiting interactively for input.
93
+ > **Autonomy:** Do not stop to ask clarifying questions. For any ambiguity not covered by a Section 10 stop condition, choose the most reasonable option consistent with this brief, record the choice in the PR body at open, or in a PR comment after open, and continue. Halt only for the explicit Section 10 stop conditions — and when you halt, record the blocker in a PR comment or an Issue comment rather than waiting interactively for input.
94
94
 
95
95
  ## 12. Deliverable
96
96
 
@@ -7,7 +7,7 @@ sidebar_title: "Template: PR report"
7
7
 
8
8
  **The anchor comments are load-bearing.** Each gate-read field — `Closes #N`, `Project:`, `Tier:`, the Test Plan section, the Premise block, the Evidence block — sits inside an AEG anchor pair (an HTML comment pair, invisible on the rendered PR). When an anchor pair for a field is present, every gate reads that field **exclusively from inside the pair**, ignoring identical-looking text anywhere else in the body — a pasted reference brief, a quoted example, a duplicate section can no longer be mistaken for the real field. Bodies without anchors remain fully recognized (prose recognition is the compatibility fallback) for every field **except Evidence**, which has no prose fallback — it is never hand-typed. Use at most one anchor pair per field. Keep the anchors when you fill this in.
9
9
 
10
- **The `AEG:PREMISE` anchor is not optional when the brief carried a `Premise:` block.** Without it, `premise-recheck` scans the *whole* body for anything premise-shaped — including the brief's own original pins, pasted verbatim into the `<details>` reference copy at the bottom — and re-asserts those against the code you just changed. A premise pinning the *pre-fix* state will correctly fail once your fix lands, because the pin describes what you just changed away from. Put a fresh, post-fix, currently-true assertion inside `<!-- AEG:PREMISE:START -->` / `<!-- AEG:PREMISE:END -->` so the re-check asserts something true of the shipped diff, not the brief's stale snapshot.
10
+ **The `AEG:PREMISE` anchor is not optional when the brief carried a `Premise:` block.** Without it, `premise-recheck` scans the *whole* body for anything premise-shaped — and re-asserts those against the code you just changed. A premise pinning the *pre-fix* state will correctly fail once your fix lands, because the pin describes what you just changed away from. Put a fresh, post-fix, currently-true assertion inside `<!-- AEG:PREMISE:START -->` / `<!-- AEG:PREMISE:END -->` so the re-check asserts something true of the shipped diff, not the brief's stale snapshot — this holds even though the brief's own original pins no longer live in the *posted* body at all: `pr create` splits the `## Reference` section (below) out into the separate `aeg:brief` PR comment before the body ever reaches the forge.
11
11
 
12
12
  **No bare digit outside a fenced block.** `body-bare-digits` (CI) refuses a countable claim — a test count, a file count, a timing figure, "N passed" — written loose in a sentence anywhere in this body. A digit is exempt for exactly one reason: it sits inside an inline code span or a fenced/indented code block (`` `N` `` or a fenced block), or inside `Closes #N`/`Project:` (this header block) / `Tier:` (under `## Scope`) / `Evidence` (under `## Evidence`), correctly placed under its own documented section. **Nowhere else** — including inside `Premise`/`Test plan` (both scanned exactly like ordinary prose, no anchor exemption at all — evidence there, byte counts, exit codes all need their own backticks too), an Issue/PR reference, a date, a version, a file path, or a section number: any of those now needs its own backticks (`` `#N` ``, `` `2026-08-18` ``, `` `0.12.0` ``) the same as any other digit. Write the number inside a fenced block or backticks, or don't write it bare at all.
13
13
 
@@ -29,7 +29,7 @@ Closes #[N]
29
29
  ## Test plan
30
30
 
31
31
  <!-- AEG:TEST-PLAN:START -->
32
- - [ ] **[agent]** [item carried from the brief's §9 — tick only after pasting the actual command output as evidence]
32
+ - [ ] **[agent]** [item carried from the brief's §9 — tick only after running it; the tick is the only mark this line ever carries, never the pasted command output, which goes in the round comment headed `Head: <sha>` instead]
33
33
  - [ ] **[principal]** [item carried from the brief's §9 — the Principal ticks after verifying in a real browser/session]
34
34
  <!-- AEG:TEST-PLAN:END -->
35
35
 
@@ -40,7 +40,7 @@ Closes #[N]
40
40
  - [path/inside/the/shipped/diff.ts] contains: [a literal substring that is TRUE of the code AFTER your fix — never the brief's original pre-fix pin]
41
41
  <!-- AEG:PREMISE:END -->
42
42
 
43
- [Omit this whole section — anchors and all — only when §4 of the brief had no real code surface (a Tier 0 doc-only or planning-only change). Any brief with a `Premise:` block gets a fresh one here; do not leave the brief's original block as the only copy in the body, since it lives inside the `<details>` reference copy below and unanchored will be picked up by the re-check instead of this one.]
43
+ [Omit this whole section — anchors and all — only when §4 of the brief had no real code surface (a Tier 0 doc-only or planning-only change). Any brief with a `Premise:` block gets a fresh one here; do not rely on the brief's original block as a substitute `pr create` splits it into the separate `aeg:brief` PR comment, never the posted body, and the re-check reads this anchored section, not that comment.]
44
44
 
45
45
  ## Evidence
46
46
 
@@ -64,15 +64,20 @@ The block opens with `Head:` and a `Summary:` line — a file and line count der
64
64
 
65
65
  ## Token report
66
66
 
67
+ <!-- AEG:TOKENS:START -->
67
68
  | Phase | Role | Agent/Model | Tokens in | Tokens out | Cost | Date |
68
69
  |---|---|---|---|---|---|---|
69
70
  | [task-id]: develop | Developer | [model] | [exact in] | [exact out] | [cost] | [YYYY-MM-DD] |
71
+ <!-- AEG:TOKENS:END -->
70
72
 
71
- ## Reference — the dispatched brief
73
+ ---
72
74
 
73
- <details>
74
- <summary>Full brief (reference copy — the gates read the anchored fields above, never this block)</summary>
75
+ <!-- aeg:brief:start -->
76
+ ## Reference — the dispatched brief
75
77
 
76
78
  [paste the entire dispatched brief here, verbatim]
79
+ <!-- aeg:brief:end -->
80
+
81
+ **`pr create` splits this section out — never sends it to the forge as body text.** Everything from the `aeg:brief:start` marker to `aeg:brief:end` — this whole `## Reference` section — is extracted and posted as its own PR comment marked `<!-- aeg:brief -->`, once, at open. The body `gh pr create` actually receives ends at the divider above it; paste the brief here exactly as before, the split is mechanical, not a change to what you author.
77
82
 
78
- </details>
83
+ **This body is written once, at open.** After the PR is open the Developer changes nothing outside the `AEG:EVIDENCE` anchor and one appended `AEG:TOKENS` row. The Principal's `[principal]` ticks are the Principal's writes and must survive every Developer edit. A round's response, its re-run evidence, and any disclosure the brief didn't anticipate are PR comments, never edits to this body.
@@ -10,7 +10,7 @@ section: Overview
10
10
  **Ratifies via:** the `needs:principal-input` label
11
11
  **Amended:** the Milestone layer (`0.19.0`) added a real altitude above the tranche — this file no longer claims to be the top of AEG. See `milestone-model.md`. The task altitude below the tranche now has its own file too — see `task-model.md`.
12
12
 
13
- This design was reviewed in three rounds by an external panel (Gemini, DeepSeek, ChatGPT) and unanimously endorsed after the corrections below.
13
+ This design was reviewed in three rounds by an external panel of independently-hosted models, each from a different provider than the one that authored it, and unanimously endorsed after the corrections below.
14
14
 
15
15
  The **tranche** is the middle altitude in Agentic Execution Governance — a **Milestone** may sit above it (`milestone-model.md`, most tranches have none and need none), and a **task** always sits below it (`task-model.md`). AEG's execution model is these three altitudes; nothing sits above the Milestone and nothing sits below the task.
16
16
 
@@ -293,7 +293,7 @@ Token reporting is three separable things, and only one of them depends on the a
293
293
  2. **Collection — host-specific.** *How* a role obtains true figures for its own turn. This is the only layer an adapter belongs in, and the only layer that may name a host, a transcript format, or a script path.
294
294
  3. **The destination and the grammar — portable.** The `Tokens: …` line, in the artifact the role's turn already produced: the PR body's "Token report" section for a role that holds a branch, the verdict comment for a reviewing role, the plan PR or planning report for the Planner. The ledger stays append-only, and the Archivist transcribes what each role reported rather than re-deriving it.
295
295
 
296
- The destination was never the coupled part — no role writes a shared ledger file on a task branch, so layer 3 is satisfied through the forge for every task-branch role. Two sources remain the known open gap recorded in `roles/archivist.md`: the Archivist's own row, and the Planner's tranche-wide report. **An adopter implements layer 2 for their own harness and inherits layers 1 and 3 unchanged.** A doctrine sentence that names a tool belongs in layer 2 or nowhere.
296
+ The destination was never the coupled part — no role writes a shared ledger file on a task branch, so layer 3 is satisfied through the forge for every task-branch role. One source remains the known open gap recorded in `roles/archivist.md`: the Planner's tranche-wide report — the Archivist's own row is not part of it (see the "Known gap" paragraph below). **An adopter implements layer 2 for their own harness and inherits layers 1 and 3 unchanged.** A doctrine sentence that names a tool belongs in layer 2 or nowhere.
297
297
 
298
298
  ### Two collection capabilities (the design constraint, not a bug)
299
299
 
@@ -308,13 +308,17 @@ The split is **operator vs. agent, not terminal vs. chat** — a figure a human
308
308
 
309
309
  Which capability applies is a fact about the **host**, not a fixed property of the role: the same role is self-metering on a harness that exposes usage and operator-metered on one that does not. Read the role names above as today's common case, not as an allocation.
310
310
 
311
- Self-metering capture is real, not estimated: the adapter sums the session's own usage records, so a Developer or automated Archivist turn's numbers are exact rather than approximated. Whether it also runs with *no* operator step depends on the host's wiring — where a Stop hook writes a transcript pointer — configured in the repo or in the operator's own host settings — the adapter finds it unaided; with no pointer written, the caller names the transcript with `--transcript <path>`. Either way the figures are read, never guessed. The remaining manual seam is operator-metered roles only — closing it depends on the host giving a session a way to read its own usage, which conversational surfaces generally do not today. **Known gap (flagged, not solved):** tranche-wide operator-metered turns with no task PR to report into a Planner session outside a plan PR, a Brief Author session — have no established recording path; see `roles/planner.md` "Plan-PR close-out."
311
+ Self-metering capture is real, not estimated: the adapter sums the session's own usage records, so a Developer or automated Archivist turn's numbers are exact rather than approximated. Whether it also runs with *no* operator step depends on the host's wiring — where a Stop hook writes a transcript pointer — configured in the repo or in the operator's own host settings — the adapter finds it unaided; with no pointer written, the caller names the transcript with `--transcript <path>`. Either way the figures are read, never guessed. The remaining manual seam is operator-metered roles only — closing it depends on the host giving a session a way to read its own usage, which conversational surfaces generally do not today. **Known gap now partly closed:** tranche-wide operator-metered turns with no task PR to report into no longer lack a destination across the board. A Planner session outside a plan PR now reports into a comment on the pinned lessons Issue — the existing forge object, never a new one (`roles/planner.md` "Turn-end: report your tokens, don't append them"). A Brief Author session already has a destination when a plan PR exists the same plan PR the Planner reports into (`roles/brief-author.md`) — unchanged by this fix. The Archivist's own `<task-id>: archive` row was never actually homeless either: `vinaya archive` folds the Archivist's `Tokens: …` line into the same provenance comment it posts on the merged task PR (`roles/archivist.md` "The provenance block") — a different fact from the narrower Studio live-read caveat that same file still carries, which is about re-deriving ledger totals from a PR's own body/comments, not about where the row is written. What remains genuinely open: a Brief Author session that ends with no PR of any kind yet to write into — mid-authoring, before a plan PR exists — still has nowhere durable to report; it falls back to an ephemeral report to the Principal, and that fallback is not fixed here.
312
312
 
313
313
  ### The collection adapter AEG ships (one layer-2 instance, not the requirement)
314
314
 
315
- AEG ships exactly one collection adapter, for the Claude Code host, exposed as `vinaya tokens`. It reads that host's session transcript — a JSONL file carrying a `usage` object per assistant message sums it, and emits a layer-3 `Tokens: …` line. Every doctrine citation of it is an **example of one way to satisfy layer 2**, never the requirement; a role on another host satisfies the same obligation by other means and is equally compliant.
315
+ This is doctrine's one fenced, concrete instance of a layer-2 adapter named here, by product, so a first-time adopter has something real to look at; nowhere else in this doctrine tree names this or any other host by product name. Everywhere else, the concept stays generic: "the agent's own host," "whatever your harness offers."
316
+
317
+ <!-- AEG:VENDOR-EXAMPLE:START -->
318
+ AEG ships exactly one collection adapter, for today's shipped reference host, Claude Code, exposed as `vinaya tokens`. It reads that host's session transcript — a JSONL file carrying a `usage` object per assistant message — sums it, and emits a layer-3 `Tokens: …` line. Every doctrine citation of it is an **example of one way to satisfy layer 2**, never the requirement; a role on another host satisfies the same obligation by other means and is equally compliant.
316
319
 
317
320
  **The seam is the summary shape, not the file tree.** An adapter's whole job is to produce a `TranscriptSummary` — four integers (fresh input, cache creation, cache read, output) plus a model id. Everything downstream of that shape is portable and already shipped: `formatTokensLine` renders the grammar, `parse-token-report.ts` reads it back. Two things sit adapter-side because both know host-specific facts: `summarizeTranscript` (`@attalabs/aeg-core`'s Claude Code transcript module), which knows Claude Code's transcript JSONL and its `usage` field names, and the bin itself, which knows how that host points a session at its own transcript. The `bin/` vs `src/` split does **not** mark this seam and never did.
321
+ <!-- AEG:VENDOR-EXAMPLE:END -->
318
322
 
319
323
  **To satisfy layer 2 on another harness:** obtain your turn's usage figures by whatever means your host offers — its own transcript or log, an API usage response, a meter the harness exposes, or an operator reading them off a dashboard and handing them over — and write the layer-3 line yourself. Reusing this adapter is not required, and neither is writing any code: the requirement is the reported figures, in the grammar, in the right artifact. If your host exposes nothing to the agent, you are operator-metered and the `—` rule above applies — that is the sanctioned outcome, not a failure to comply.
320
324
 
@@ -322,7 +326,7 @@ AEG ships exactly one collection adapter, for the Claude Code host, exposed as `
322
326
 
323
327
  Vinaya Studio's tranche page no longer reads `<name>.tokens.md` off disk to render token totals — it re-derives the same row shape live off the forge: every MERGED PR on a task's own branch (`task/<tranche>/<id>`), parsing the Developer's "Token report" entries from the PR body (every one, including re-push entries) and the Reviewer's/Security's `Tokens: …` lines from that PR's comments (`@attalabs/aeg-core`'s token-report parser, `aggregateTaskTokenRows`, fetched by Studio's own forge-reading layer in the repo that hosts it). Same row shape, same `sumLedger` totals math (`parse-ledger.ts`) — different source.
324
328
 
325
- This is deliberately **narrower** than what the Archivist collects into the file: it cannot recover the Archivist's own `<task-id>: archive` row (no PR carries it — the file itself is that row's only record) or the Planner's `Tokens: planning …` report (no reliable way to attribute a plan PR to one task from the forge alone without false-positive cross-task matches, confirmed live during 4b's build — a task Issue's cross-reference timeline picks up ANY PR that merely mentions its number in passing prose, not just its own plan PR). Both remain recoverable only from `.tokens.md`, which is why the file is not deleted here (task 7's job, once the live mechanism is proven in wider use). A task's report that's missing or malformed (e.g. a "Token report" heading with no table and no parseable text after it) yields no row for that report, never a fabricated one — same discipline as the Archivist's own DANGLING convention.
329
+ This is deliberately **narrower** than what the Archivist collects into the file: it cannot recover the Planner's `Tokens: planning …` report (no reliable way to attribute a plan PR to one task from the forge alone without false-positive cross-task matches, confirmed live during 4b's build — a task Issue's cross-reference timeline picks up ANY PR that merely mentions its number in passing prose, not just its own plan PR). The Archivist's own `<task-id>: archive` row is not part of that gap: `vinaya archive` posts it inside the same provenance comment it posts on the merged task PR, so this mechanism recovers it exactly as it recovers every other role's row on that PR. The Planner's report remains recoverable only from `.tokens.md`, which is why the file is not deleted here (task 7's job, once the live mechanism is proven in wider use). A task's report that's missing or malformed (e.g. a "Token report" heading with no table and no parseable text after it) yields no row for that report, never a fabricated one — same discipline as the Archivist's own DANGLING convention.
326
330
 
327
331
  ### Anti-regression
328
332