@attalabs/vinaya 0.4.3 → 0.4.5

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 (262) hide show
  1. package/aeg-root/enforcement.md +1 -1
  2. package/aeg-root/state-machine.md +1 -1
  3. package/dist/checks/bin/check-branch-topology.js +55 -33
  4. package/dist/checks/bin/check-brief-shape.js +61 -34
  5. package/dist/checks/bin/check-closes-n.js +55 -33
  6. package/dist/checks/bin/check-coherence.js +55 -33
  7. package/dist/checks/bin/check-dead-branch-push.js +55 -33
  8. package/dist/checks/bin/check-dispatch-readiness.js +55 -33
  9. package/dist/checks/bin/check-doc-coverage-push.js +232 -36
  10. package/dist/checks/bin/check-doc-coverage.js +232 -36
  11. package/dist/checks/bin/check-first-push-dispatch.js +55 -33
  12. package/dist/checks/bin/check-issue-assignment.js +55 -33
  13. package/dist/checks/bin/check-no-disk-state.js +55 -33
  14. package/dist/checks/bin/check-reader-resolvable-prose.js +55 -33
  15. package/dist/checks/bin/check-registry-gates.js +55 -33
  16. package/dist/checks/bin/check-review-gate.js +233 -38
  17. package/dist/checks/bin/check-single-plan-pr.js +55 -33
  18. package/dist/checks/bin/check-test-plan.js +55 -33
  19. package/dist/index.js +138 -42
  20. package/package.json +1 -1
  21. package/studio-standalone/.worktrees/fix/bump-0.4.4/.vinaya/projects.md +63 -0
  22. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/aeg-manual-flow.md +216 -0
  23. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/contracts/archivist-tranche-archivist.md +92 -0
  24. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/contracts/brief-developer.md +140 -0
  25. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/contracts/developer-reviewer.md +106 -0
  26. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/contracts/planner-brief.md +130 -0
  27. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/contracts/reviewer-archivist.md +96 -0
  28. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/contracts/tranche-archivist-planner.md +116 -0
  29. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/coordination.md +293 -0
  30. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/documentation-coherence.md +65 -0
  31. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/enforcement.md +161 -0
  32. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/glossary.md +36 -0
  33. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/process.md +371 -0
  34. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/reviewer-prompt.md +68 -0
  35. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/roles/archivist.md +167 -0
  36. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/roles/brief-author.md +108 -0
  37. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/roles/developer.md +429 -0
  38. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/roles/planner.md +285 -0
  39. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/roles/principal.md +107 -0
  40. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/roles/reviewer.md +130 -0
  41. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/roles/security.md +121 -0
  42. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/roles/tranche-archivist.md +257 -0
  43. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/skills/aeg/SKILL.md +90 -0
  44. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/skills/aeg-roles/SKILL.md +58 -0
  45. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/skills/brief-authoring/SKILL.md +497 -0
  46. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/state-machine.md +656 -0
  47. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/templates/brief-template.md +103 -0
  48. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/templates/issue-rationale-template.md +35 -0
  49. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/templates/pr-report-template.md +68 -0
  50. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/tranche-model.md +306 -0
  51. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/tranches/completed/aeg-coherence-v1.md +55 -0
  52. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/tranches/completed/aeg-coherence-v1.tokens.md +13 -0
  53. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/tranches/completed/aeg-consolidation.md +28 -0
  54. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/tranches/completed/aeg-governance-hardening.md +80 -0
  55. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/tranches/completed/aeg-governance-ui-v2.md +168 -0
  56. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/tranches/completed/aeg-governance-ui-v2.tokens.md +18 -0
  57. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/tranches/completed/aeg-studio-cleanup.md +37 -0
  58. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/tranches/completed/aeg-ui-v1.md +176 -0
  59. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/tranches/completed/aeg-ui-v1.tokens.md +17 -0
  60. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/tranches/completed/herald-agents-v2.md +35 -0
  61. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/tranches/completed/herald-agents-v2.tokens.md +11 -0
  62. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/tranches/completed/herald-onto-engine.md +99 -0
  63. package/studio-standalone/.worktrees/fix/bump-0.4.4/aeg-root/tranches/completed/vada-agents-v2.md +220 -0
  64. package/studio-standalone/.worktrees/fix/bump-0.4.4/apps/vinaya/cli/tests/fixtures/checks/vinaya.config.json +9 -0
  65. package/studio-standalone/.worktrees/fix/bump-0.4.4/node_modules/@attalabs/vinaya/tests/fixtures/checks/vinaya.config.json +9 -0
  66. package/studio-standalone/.worktrees/fix/bump-0.4.4/vinaya.config.json +36 -0
  67. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/.vinaya/projects.md +63 -0
  68. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/aeg-manual-flow.md +216 -0
  69. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/contracts/archivist-tranche-archivist.md +92 -0
  70. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/contracts/brief-developer.md +140 -0
  71. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/contracts/developer-reviewer.md +106 -0
  72. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/contracts/planner-brief.md +130 -0
  73. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/contracts/reviewer-archivist.md +96 -0
  74. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/contracts/tranche-archivist-planner.md +116 -0
  75. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/coordination.md +293 -0
  76. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/documentation-coherence.md +65 -0
  77. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/enforcement.md +161 -0
  78. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/glossary.md +36 -0
  79. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/process.md +371 -0
  80. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/reviewer-prompt.md +68 -0
  81. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/roles/archivist.md +167 -0
  82. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/roles/brief-author.md +108 -0
  83. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/roles/developer.md +429 -0
  84. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/roles/planner.md +285 -0
  85. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/roles/principal.md +107 -0
  86. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/roles/reviewer.md +130 -0
  87. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/roles/security.md +121 -0
  88. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/roles/tranche-archivist.md +257 -0
  89. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/skills/aeg/SKILL.md +90 -0
  90. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/skills/aeg-roles/SKILL.md +58 -0
  91. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/skills/brief-authoring/SKILL.md +497 -0
  92. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/state-machine.md +656 -0
  93. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/templates/brief-template.md +103 -0
  94. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/templates/issue-rationale-template.md +35 -0
  95. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/templates/pr-report-template.md +68 -0
  96. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/tranche-model.md +306 -0
  97. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/tranches/completed/aeg-coherence-v1.md +55 -0
  98. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/tranches/completed/aeg-coherence-v1.tokens.md +13 -0
  99. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/tranches/completed/aeg-consolidation.md +28 -0
  100. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/tranches/completed/aeg-governance-hardening.md +80 -0
  101. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/tranches/completed/aeg-governance-ui-v2.md +168 -0
  102. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/tranches/completed/aeg-governance-ui-v2.tokens.md +18 -0
  103. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/tranches/completed/aeg-studio-cleanup.md +37 -0
  104. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/tranches/completed/aeg-ui-v1.md +176 -0
  105. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/tranches/completed/aeg-ui-v1.tokens.md +17 -0
  106. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/tranches/completed/herald-agents-v2.md +35 -0
  107. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/tranches/completed/herald-agents-v2.tokens.md +11 -0
  108. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/tranches/completed/herald-onto-engine.md +99 -0
  109. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/aeg-root/tranches/completed/vada-agents-v2.md +220 -0
  110. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/apps/vinaya/cli/tests/fixtures/checks/vinaya.config.json +9 -0
  111. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/node_modules/@attalabs/vinaya/tests/fixtures/checks/vinaya.config.json +9 -0
  112. package/studio-standalone/.worktrees/fix/check-lifecycle-phase/vinaya.config.json +36 -0
  113. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/.vinaya/projects.md +63 -0
  114. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/aeg-manual-flow.md +216 -0
  115. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/contracts/archivist-tranche-archivist.md +92 -0
  116. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/contracts/brief-developer.md +140 -0
  117. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/contracts/developer-reviewer.md +106 -0
  118. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/contracts/planner-brief.md +130 -0
  119. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/contracts/reviewer-archivist.md +96 -0
  120. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/contracts/tranche-archivist-planner.md +116 -0
  121. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/coordination.md +293 -0
  122. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/documentation-coherence.md +65 -0
  123. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/enforcement.md +161 -0
  124. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/glossary.md +36 -0
  125. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/process.md +371 -0
  126. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/reviewer-prompt.md +68 -0
  127. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/roles/archivist.md +167 -0
  128. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/roles/brief-author.md +108 -0
  129. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/roles/developer.md +429 -0
  130. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/roles/planner.md +285 -0
  131. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/roles/principal.md +107 -0
  132. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/roles/reviewer.md +130 -0
  133. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/roles/security.md +121 -0
  134. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/roles/tranche-archivist.md +257 -0
  135. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/skills/aeg/SKILL.md +90 -0
  136. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/skills/aeg-roles/SKILL.md +58 -0
  137. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/skills/brief-authoring/SKILL.md +497 -0
  138. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/state-machine.md +656 -0
  139. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/templates/brief-template.md +103 -0
  140. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/templates/issue-rationale-template.md +35 -0
  141. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/templates/pr-report-template.md +68 -0
  142. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/tranche-model.md +306 -0
  143. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/tranches/completed/aeg-coherence-v1.md +55 -0
  144. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/tranches/completed/aeg-coherence-v1.tokens.md +13 -0
  145. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/tranches/completed/aeg-consolidation.md +28 -0
  146. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/tranches/completed/aeg-governance-hardening.md +80 -0
  147. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/tranches/completed/aeg-governance-ui-v2.md +168 -0
  148. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/tranches/completed/aeg-governance-ui-v2.tokens.md +18 -0
  149. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/tranches/completed/aeg-studio-cleanup.md +37 -0
  150. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/tranches/completed/aeg-ui-v1.md +176 -0
  151. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/tranches/completed/aeg-ui-v1.tokens.md +17 -0
  152. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/tranches/completed/herald-agents-v2.md +35 -0
  153. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/tranches/completed/herald-agents-v2.tokens.md +11 -0
  154. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/tranches/completed/herald-onto-engine.md +99 -0
  155. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/aeg-root/tranches/completed/vada-agents-v2.md +220 -0
  156. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/apps/vinaya/cli/tests/fixtures/checks/vinaya.config.json +9 -0
  157. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/node_modules/@attalabs/vinaya/tests/fixtures/checks/vinaya.config.json +9 -0
  158. package/studio-standalone/.worktrees/fix/vinaya-cli-noconsole/vinaya.config.json +36 -0
  159. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/.vinaya/projects.md +63 -0
  160. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/aeg-manual-flow.md +216 -0
  161. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/contracts/archivist-tranche-archivist.md +92 -0
  162. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/contracts/brief-developer.md +140 -0
  163. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/contracts/developer-reviewer.md +106 -0
  164. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/contracts/planner-brief.md +130 -0
  165. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/contracts/reviewer-archivist.md +96 -0
  166. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/contracts/tranche-archivist-planner.md +116 -0
  167. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/coordination.md +293 -0
  168. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/documentation-coherence.md +65 -0
  169. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/enforcement.md +161 -0
  170. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/glossary.md +36 -0
  171. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/process.md +371 -0
  172. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/reviewer-prompt.md +68 -0
  173. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/roles/archivist.md +167 -0
  174. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/roles/brief-author.md +108 -0
  175. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/roles/developer.md +429 -0
  176. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/roles/planner.md +285 -0
  177. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/roles/principal.md +107 -0
  178. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/roles/reviewer.md +130 -0
  179. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/roles/security.md +121 -0
  180. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/roles/tranche-archivist.md +257 -0
  181. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/skills/aeg/SKILL.md +90 -0
  182. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/skills/aeg-roles/SKILL.md +58 -0
  183. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/skills/brief-authoring/SKILL.md +497 -0
  184. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/state-machine.md +656 -0
  185. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/templates/brief-template.md +103 -0
  186. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/templates/issue-rationale-template.md +35 -0
  187. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/templates/pr-report-template.md +68 -0
  188. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/tranche-model.md +306 -0
  189. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/tranches/completed/aeg-coherence-v1.md +55 -0
  190. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/tranches/completed/aeg-coherence-v1.tokens.md +13 -0
  191. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/tranches/completed/aeg-consolidation.md +28 -0
  192. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/tranches/completed/aeg-governance-hardening.md +80 -0
  193. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/tranches/completed/aeg-governance-ui-v2.md +168 -0
  194. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/tranches/completed/aeg-governance-ui-v2.tokens.md +18 -0
  195. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/tranches/completed/aeg-studio-cleanup.md +37 -0
  196. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/tranches/completed/aeg-ui-v1.md +176 -0
  197. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/tranches/completed/aeg-ui-v1.tokens.md +17 -0
  198. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/tranches/completed/herald-agents-v2.md +35 -0
  199. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/tranches/completed/herald-agents-v2.tokens.md +11 -0
  200. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/tranches/completed/herald-onto-engine.md +99 -0
  201. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/aeg-root/tranches/completed/vada-agents-v2.md +220 -0
  202. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/apps/vinaya/cli/tests/fixtures/checks/vinaya.config.json +9 -0
  203. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/node_modules/@attalabs/vinaya/tests/fixtures/checks/vinaya.config.json +9 -0
  204. package/studio-standalone/.worktrees/task/vinaya-adopter-ci-hotfix-v1/1/vinaya.config.json +36 -0
  205. package/studio-standalone/_node_modules/@atta/vinaya-cli/aeg-root/enforcement.md +1 -1
  206. package/studio-standalone/_node_modules/@atta/vinaya-cli/aeg-root/state-machine.md +1 -1
  207. package/studio-standalone/_node_modules/@attalabs/vinaya/aeg-root/enforcement.md +1 -1
  208. package/studio-standalone/_node_modules/@attalabs/vinaya/aeg-root/state-machine.md +1 -1
  209. package/studio-standalone/apps/vinaya/cli/aeg-root/enforcement.md +1 -1
  210. package/studio-standalone/apps/vinaya/cli/aeg-root/state-machine.md +1 -1
  211. package/studio-standalone/apps/vinaya/web/.next/BUILD_ID +1 -1
  212. package/studio-standalone/apps/vinaya/web/.next/build-manifest.json +3 -3
  213. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/cli/page.js.nft.json +1 -1
  214. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/config/page.js.nft.json +1 -1
  215. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/docs/(standalone)/cli/page.js.nft.json +1 -1
  216. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/docs/(standalone)/harness/page.js.nft.json +1 -1
  217. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/docs/(standalone)/state-machine/page.js.nft.json +1 -1
  218. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/docs/(with-sidebar)/[...slug]/page.js.nft.json +1 -1
  219. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/docs/(with-sidebar)/reference/page.js.nft.json +1 -1
  220. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/docs/page.js.nft.json +1 -1
  221. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/install/page.js.nft.json +1 -1
  222. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/page.js.nft.json +1 -1
  223. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/roadmap/page.js.nft.json +1 -1
  224. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/start/archive/page.js.nft.json +1 -1
  225. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/start/brief/page.js.nft.json +1 -1
  226. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/start/develop/page.js.nft.json +1 -1
  227. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/start/overview/page.js.nft.json +1 -1
  228. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/start/page.js.nft.json +1 -1
  229. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/start/plan/page.js.nft.json +1 -1
  230. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/start/quick/page.js.nft.json +1 -1
  231. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/start/review/page.js.nft.json +1 -1
  232. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/start/security/page.js.nft.json +1 -1
  233. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/start/wrap-up/page.js.nft.json +1 -1
  234. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/state-machine/page.js.nft.json +1 -1
  235. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/the-harness/page.js.nft.json +1 -1
  236. package/studio-standalone/apps/vinaya/web/.next/server/app/(site)/the-studio/page.js.nft.json +1 -1
  237. package/studio-standalone/apps/vinaya/web/.next/server/app/_global-error/page.js.nft.json +1 -1
  238. package/studio-standalone/apps/vinaya/web/.next/server/app/_global-error.html +1 -1
  239. package/studio-standalone/apps/vinaya/web/.next/server/app/_global-error.rsc +1 -1
  240. package/studio-standalone/apps/vinaya/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  241. package/studio-standalone/apps/vinaya/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  242. package/studio-standalone/apps/vinaya/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  243. package/studio-standalone/apps/vinaya/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  244. package/studio-standalone/apps/vinaya/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  245. package/studio-standalone/apps/vinaya/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  246. package/studio-standalone/apps/vinaya/web/.next/server/app/api/coherence/route.js.nft.json +1 -1
  247. package/studio-standalone/apps/vinaya/web/.next/server/app/studio/backlog/page.js.nft.json +1 -1
  248. package/studio-standalone/apps/vinaya/web/.next/server/app/studio/docs/[...slug]/page.js.nft.json +1 -1
  249. package/studio-standalone/apps/vinaya/web/.next/server/app/studio/docs/page.js.nft.json +1 -1
  250. package/studio-standalone/apps/vinaya/web/.next/server/app/studio/page.js.nft.json +1 -1
  251. package/studio-standalone/apps/vinaya/web/.next/server/app/studio/projects/[name]/page.js.nft.json +1 -1
  252. package/studio-standalone/apps/vinaya/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page.js.nft.json +1 -1
  253. package/studio-standalone/apps/vinaya/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page.js.nft.json +1 -1
  254. package/studio-standalone/apps/vinaya/web/.next/server/app/studio/projects/page.js.nft.json +1 -1
  255. package/studio-standalone/apps/vinaya/web/.next/server/app/studio/tranches/page.js.nft.json +1 -1
  256. package/studio-standalone/apps/vinaya/web/.next/server/chunks/ssr/[root-of-the-server]__0kqmrho._.js +1 -1
  257. package/studio-standalone/apps/vinaya/web/.next/server/chunks/ssr/[root-of-the-server]__1dxaovd._.js +2 -2
  258. package/studio-standalone/apps/vinaya/web/.next/server/middleware-build-manifest.js +3 -3
  259. package/studio-standalone/apps/vinaya/web/.next/server/pages/500.html +1 -1
  260. /package/studio-standalone/apps/vinaya/web/.next/static/{Afs41Lu9uNQ-T6uC-tm4_ → LixrFgIixvAYndTclqOnR}/_buildManifest.js +0 -0
  261. /package/studio-standalone/apps/vinaya/web/.next/static/{Afs41Lu9uNQ-T6uC-tm4_ → LixrFgIixvAYndTclqOnR}/_clientMiddlewareManifest.js +0 -0
  262. /package/studio-standalone/apps/vinaya/web/.next/static/{Afs41Lu9uNQ-T6uC-tm4_ → LixrFgIixvAYndTclqOnR}/_ssgManifest.js +0 -0
@@ -44,7 +44,7 @@ The same check implementations run at ring 0 and ring 1 — one codebase, two en
44
44
  | Starting the Dig (before authoring a brief) / starting Step 0 (before executing one) / **every push on a task branch before its PR exists** | Ever started work only to find out halfway it was blocked on something else? | hook | Refuses to start work until every precondition for the task is checked live and found clear. | **`verify-dispatch` CLI** (`packages/aeg-core/bin/verify-dispatch.ts` — mandated by `roles/developer.md` and `skills/brief-authoring/SKILL.md`; **now also hook-automated** — task 25) | Every dispatch precondition is re-checked live against the forge (the task's row/Issue are derived directly from a Milestone + `vinaya/tranche:<slug>`-labeled Issues as of the forge-native migration — no `origin/main` file read involved; leftover-branch detection still fetches `origin/main` for its own commit-count comparison): the task's row and Issue exist; the Issue passes the rationale gate; every `depends-on` PR is merged and no `conflicts-with` PR is open/in-flight; every named project's prior tranche is archived. (2026-07-13: the immediately-prior task's three-predicate archival bar — the row-adjacency predicate — was removed once the provenance-posting signal it existed to protect became automated.) A `NOT READY` result is a stop condition. Every `gh` call this script makes carries an explicit `-R <owner>/<repo>` (task 23) — from a linked `git worktree add` checkout, an untargeted `gh issue list`/`gh issue view`/`gh pr list` silently scopes to the wrong repo (or returns nothing), which previously produced false prior-tranche-archival blockers. **`.husky/pre-push`** now runs this gate itself on a `task/*/*` branch's first push (before a PR exists), refusing on genuine `NOT READY` and failing OPEN — loudly — when a `gh auth status` reachability probe fails or `verify-dispatch`'s own repo/token resolution fails (task 18's fail-open precedent). The gate reads only the `dispatch-readiness:` predicate, not verify-dispatch's combined exit code, which also folds in `leftover-detection` (a pre-Step-0 "safe to branch fresh" advisory that would otherwise false-block every push after the first on a task legitimately mid-flight — discovered live while building this gate). Once a PR exists, later pushes skip the gate: dispatch was already validated once. | `packages/aeg-core/bin/verify-dispatch.ts` |
45
45
  | Opening a task PR whose surface includes real code | Ever had a PR's description quietly stop matching what the code does? | event | Refuses a code-carrying pull request whose description no longer matches what it changes. | **Brief Validation — `checkPremiseCoverage`** | The PR body carries a `Premise:` block with at least one assertion (`contains`/`absent`/`sha256`) whose path falls inside the task's surface map — re-assertable at any point via `verify-dispatch --premise` or `verify-task`. | `packages/aeg-core/src/brief-validation.ts` |
46
46
  | Opening a task PR (final self-check before creation) | Ever opened a PR and only then discovered the tests were failing? | event | Runs the whole exit check before a pull request is created, so failures surface first. | **`verify-task` CLI** (`packages/aeg-core/bin/verify-task.ts` — mandated by `roles/developer.md`; **now also hook-automated** — task 25) | Typecheck, lint, tests, build, `verify-docs --pr`, and the premise coverage/recheck pair all pass, as one summary, against the PR's actual diff, before `open-pr.ts` is invoked. **`open-pr.ts` now runs this composite itself** for task branches (via `gatePlanForBranch`), invoked wholesale rather than partially re-implemented — non-task branches are unaffected (byte-identical gate set). `verify-docs --pr` runs twice on a task-branch PR-open as an accepted, measured overlap (~4s with a warm turbo cache). | `packages/aeg-core/bin/verify-task.ts` |
47
- | Spawning a check (`vinaya check`, ring-0 pre-push AND ring-1 CI) | Ever had a check quietly read a secret it had no business seeing, because nothing scoped what it could reach? | hook | Governs which environment variables a spawned check's child process can see, instead of every check inheriting the full parent environment unconditionally. | **Env allowlist** (`CheckSpec['env']`, `apps/vinaya/cli/src/checks/contract.ts`; construction: `buildCheckEnv`, `apps/vinaya/cli/src/checks/runner.ts`) | **⚠️ BREAKING, live (task 3):** a spawned check's child process sees only a fixed baseline (`PATH`, `LANG`, `HOME`, `HTTPS_PROXY`, `HTTP_PROXY`, `NO_PROXY`, `TMPDIR`) plus whatever its own `env` declaration (`true` / `{ optional: true }` / `{ anyOf: [...] }` / a literal string) explicitly forwards — **no longer the full parent environment.** An undeclared variable a check's own code reads is now genuinely invisible to it, not merely warned about; a `true` or unsatisfied `anyOf` declaration missing from the caller's environment synthesizes a `CheckError` and the check never spawns at all. All 15 core checks in `registry.ts` carry an audited declaration, and every core check that spawns `gh` or reaches the forge through the token-resolution chain additionally forwards `GITHUB_TOKEN`/`GH_TOKEN` as `{ optional: true }` — on a CI runner those env vars are `gh`'s only authentication path, so a check that shells out without forwarding them runs unauthenticated there (hard-failing or silently degrading, depending on the bin's failure mode) while passing locally on `gh`'s keyring; the pairing is coupling-tested (`apps/vinaya/cli/tests/checks/registry-env.test.ts` detects `gh` invocations in any call shape — array-form, string-form, and template-literal — and demands both declarations); that detection is source-text pattern matching, so it does not yet catch a check that reaches the forge indirectly through `createForgeSource` (`@atta/vinaya-sources`) with no literal `gh` call of its own — found live: `closes-n` reaches the forge this way and had shipped without either token declared, passing locally under a developer's own `gh` keyring and failing unauthenticated on every CI runner, a known gap in the coupling test's own coverage rather than in the rule it's checking. This repo's own core checks are therefore unaffected — an adopter's **custom** check that reads `process.env` directly with no `env` declared will lose that access at this minor; declare `env` on it (`vinaya.config.json`'s `checks.<name>.env`) before upgrading. `vinaya check`'s prior warn-phase print (task 2) is retired now that the behavior it warned about is live; `vinaya doctor` still carries the same missing-declaration diagnostic permanently, at `info` severity, so a custom check's gap remains visible after upgrade even though `vinaya check` no longer prints it inline. | `apps/vinaya/cli/src/checks/runner.ts` |
47
+ | Spawning a check (`vinaya check`, ring-0 pre-push AND ring-1 CI) | Ever had a check quietly read a secret it had no business seeing, because nothing scoped what it could reach? | hook | Governs which environment variables a spawned check's child process can see, instead of every check inheriting the full parent environment unconditionally. | **Env allowlist** (`CheckSpec['env']`, `apps/vinaya/cli/src/checks/contract.ts`; construction: `buildCheckEnv`, `apps/vinaya/cli/src/checks/runner.ts`) | **⚠️ BREAKING, live (task 3):** a spawned check's child process sees only a fixed baseline (`PATH`, `LANG`, `HOME`, `HTTPS_PROXY`, `HTTP_PROXY`, `NO_PROXY`, `TMPDIR`) plus whatever its own `env` declaration (`true` / `{ optional: true }` / `{ anyOf: [...] }` / a literal string) explicitly forwards — **no longer the full parent environment.** An undeclared variable a check's own code reads is now genuinely invisible to it, not merely warned about; a `true` or unsatisfied `anyOf` declaration missing from the caller's environment synthesizes a `CheckError` and the check never spawns at all. All 15 core checks in `registry.ts` carry an audited declaration, and every core check that spawns `gh` or reaches the forge through the token-resolution chain additionally forwards `GITHUB_TOKEN`/`GH_TOKEN` as `{ optional: true }` — on a CI runner those env vars are `gh`'s only authentication path, so a check that shells out without forwarding them runs unauthenticated there (hard-failing or silently degrading, depending on the bin's failure mode) while passing locally on `gh`'s keyring; the pairing is coupling-tested (`apps/vinaya/cli/tests/checks/registry-env.test.ts` detects `gh` invocations in any call shape — array-form, string-form, and template-literal — and demands both declarations); that detection is source-text pattern matching, so it does not yet catch a check that reaches the forge indirectly through `createForgeSource` (`@atta/vinaya-sources`) with no literal `gh` call of its own — found live: `closes-n` reaches the forge this way and had shipped without either token declared, passing locally under a developer's own `gh` keyring and failing unauthenticated on every CI runner, a known gap in the coupling test's own coverage rather than in the rule it's checking. This repo's own core checks are therefore unaffected — an adopter's **custom** check that reads `process.env` directly with no `env` declared will lose that access at this minor; declare `env` on it (`vinaya.config.json`'s `checks.<name>.env`) before upgrading. `vinaya check`'s prior warn-phase print (task 2) is retired now that the behavior it warned about is live; `vinaya doctor` still carries the same missing-declaration diagnostic permanently, at `info` severity, so a custom check's gap remains visible after upgrade even though `vinaya check` no longer prints it inline. A second field, `requiresOpenPr?: boolean` (same no-privileged-field discipline as `env` — a custom check can declare it exactly like a core one), marks a check that can only evaluate meaningfully once a pull request exists; the generated `pre-commit`/`pre-push` hooks pass a new `--local` flag that skips every check declaring it, while CI (`vinaya-checks.yml`, `pull_request`-triggered) omits the flag and always runs them for real. Found live: `closes-n`/`test-plan` ran unconditionally in both hooks with no `requiresOpenPr` field to opt out on, so the first commit on a fresh task branch could never satisfy either — no PR exists yet at commit or push time, only after. Found live again, same missing-declaration class: `brief-shape` read `BRANCH` from `process.env` in its own bin without declaring it in `registry.ts`'s allowlist, so the runner stripped the variable before the child ever spawned — the non-task-branch bypass its logic depended on (skipping the `Closes #N` requirement for a standalone brief with no Issue to close) silently never fired; `registry.ts` now declares `BRANCH: { optional: true }` on that entry alongside `PR_BODY`, mirroring `test-plan`'s existing declaration for the same pair. `vinaya.config.json`'s `principals` field (the review-gate/waiver trust anchor, `apps/vinaya/cli/src/lib/config.ts`'s `resolvePrincipalAllowlist`) is resolved via `loadTrustAnchorConfig()` — a `gh api` read of the repository's DEFAULT BRANCH, never local git, the PR's working tree, or any env var. Three successive attempts got this wrong before landing (all caught pre-merge): reading the PR's working tree; reading `git show ${BASE_SHA}:…` where `BASE_SHA` was an env var; and reading `git show origin/main:…`, where `origin/main` is a LOCAL remote-tracking ref the PR's own workflow can `git update-ref`. The rule they establish: **inside a `pull_request`-triggered workflow nothing on the job's own disk or environment is a trust boundary against the PR author**, because the workflow definition itself comes from the PR. `check-doc-coverage.ts`/`check-doc-coverage-push.ts` keep their own, separate, legitimately-overridable `BASE_SHA` for diff-scoping only, never reused for a trust decision. The API read raises the bar but is not itself the boundary — a PR can still delete the gate's step from its own workflow copy; only **branch protection with the check marked required** makes review enforcement unbypassable, which is why `init` prints that command and `doctor` reports its absence. | `apps/vinaya/cli/src/checks/runner.ts` |
48
48
  | `vinaya check` / `vinaya check --plan` (a CLI mechanism, not a git hook — this row is `.husky`-free) | Ever had a config entry silently double-run alongside the core check it was meant to replace, with no way to see that from the outside? | event | Resolves core-registered and config-registered checks into one deterministic table before anything runs, instead of letting a config entry run alongside the core check it collides with, unannounced. | **Checks-side resolver** (`resolveChecks`/`isValidNamespacedKey`, `apps/vinaya/cli/src/checks/resolver.ts`) | An exact-key match against a core check ID is an **override** — a complete replacement of the spec, never a merge. A key containing exactly one `/`, both segments matching `[a-z0-9][a-z0-9-]*` and the `vinaya` prefix rejected as an exact segment match, is **additive**. Anything else — a bare key with no `/` matching no core ID — is a loud `FAIL_CLOSED` refusal: never silently dropped, never defaulted, never last-wins. `--plan` never resolves or prints an env *value*, only how each one resolves. **This release feeds `vinaya check --plan` / `--plan --json` only** — `vinaya check`'s real execution (`check.ts`'s flat `[...coreCheckRegistry(), ...customSpecs]` concat) is unaffected until a later task wires it in. | `apps/vinaya/cli/src/checks/resolver.ts` |
49
49
 
50
50
  **Documentation coverage, specifically** (a historical pain point): the code→document ownership rule is enforced at *two* prevention chokepoints — at every push (over the branch's cumulative change set) and again at pull-request creation and editing. A change to owned code cannot be published, let alone turned into a pull request, without its owning document.
@@ -444,7 +444,7 @@ For each changed code file in the PR, glob-match against every binding. Per **ma
444
444
  | **Strong-pass** | The in-repo pointer is in the PR diff. |
445
445
  | **URL-ack** | The pointer is a URL **and** the PR body carries `Doc-ack: <pointer> — <note>` whose `<pointer>` exactly matches the binding's URL. |
446
446
  | **Neutral-edit** | The pointer is in-repo, absent from the diff, **and** the PR body carries `Doc-neutral: <pointer> — <note>` whose `<pointer>` exactly matches the binding's doc, **and** the diff of every matched code file is comment/whitespace-only (see below). Both the declaration and the evidence are required — either alone fails. |
447
- | **Waiver** | The pull request carries the `vinaya/waiver:docs` label, AND the actor of that label's most recent labeling timeline event is a configured principal. PR-wide, not per-binding — one verified label satisfies every fired binding in the PR. Label presence alone is never sufficient; there is no PR-body waiver field. |
447
+ | **Waiver** | The pull request carries the `vinaya/waiver:docs` label, AND the actor of that label's most recent labeling timeline event is a configured principal (`isPrincipal`, `packages/aeg-core/src/waiver-label.ts` — matched **case-insensitively**, since GitHub logins are; an exact-match test fails closed but invisibly, stranding a real principal's action for a reason nothing states). PR-wide, not per-binding — one verified label satisfies every fired binding in the PR. Label presence alone is never sufficient; there is no PR-body waiver field. |
448
448
 
449
449
  If none of the above hold, C5 fails the PR. A binding whose in-repo pointer **does not exist on disk** is a distinct *dangling* failure (fix the binding or add the doc) — never silently ignored, because a dangling pointer is the failure mode the seam was built to prevent.
450
450
 
@@ -1451,12 +1451,16 @@ function isCodeFile(p) {
1451
1451
  var WAIVER_LABEL = label("waiver-docs");
1452
1452
  var WAIVER_LABEL_REVIEW = label("waiver-review");
1453
1453
  var PRINCIPAL_ALLOWLIST = ["daniboomerang"];
1454
+ function isPrincipal(login, principalAllowlist) {
1455
+ if (login === null)
1456
+ return false;
1457
+ const normalized = login.toLowerCase();
1458
+ return principalAllowlist.some((p) => p.toLowerCase() === normalized);
1459
+ }
1454
1460
  function isWaiverLabelActorVerified(opts) {
1455
1461
  if (!opts.labels.includes(opts.label))
1456
1462
  return false;
1457
- if (opts.labelActor === null)
1458
- return false;
1459
- return opts.principalAllowlist.includes(opts.labelActor);
1463
+ return isPrincipal(opts.labelActor, opts.principalAllowlist);
1460
1464
  }
1461
1465
 
1462
1466
  // ../../../packages/aeg-core/src/doc-owners.ts
@@ -1644,6 +1648,27 @@ function overrideActive(opts) {
1644
1648
  // ../../../packages/aeg-core/src/premise-check.ts
1645
1649
  var ASSERTION_KINDS = new Set(["contains", "absent", "sha256"]);
1646
1650
 
1651
+ // ../../../packages/aeg-core/src/test-plan-section.ts
1652
+ var HEADING_FORM_RE = /^#{1,4}[ \t]*(?:\d+[a-z]?\.[ \t]*)?\*{0,2}Test Plan\*{0,2}[ \t]*$/im;
1653
+ var INLINE_FORM_RE = /^[ \t]*\*{0,2}Test Plan:?\*{0,2}/im;
1654
+ var NEXT_SECTION_RE = /\n(?:#{1,3}[ \t]|\*\*[A-Z][^*\n]*:\*\*)/;
1655
+ function locateTestPlanSection(body) {
1656
+ const region = anchoredRegion(body, "TEST-PLAN");
1657
+ if (region !== null)
1658
+ return { found: true, section: region };
1659
+ const headingMatch = HEADING_FORM_RE.exec(body);
1660
+ const match = headingMatch ?? INLINE_FORM_RE.exec(body);
1661
+ if (!match || match.index === undefined)
1662
+ return { found: false };
1663
+ const sectionBody = body.slice(match.index);
1664
+ const firstLineEnd = sectionBody.indexOf(`
1665
+ `);
1666
+ const searchFrom = firstLineEnd === -1 ? sectionBody.length : firstLineEnd + 1;
1667
+ const nextMatch = sectionBody.slice(searchFrom).match(NEXT_SECTION_RE);
1668
+ const sectionEnd = nextMatch ? searchFrom + (nextMatch.index ?? 0) : sectionBody.length;
1669
+ return { found: true, section: sectionBody.slice(0, sectionEnd) };
1670
+ }
1671
+
1647
1672
  // ../../../packages/aeg-core/src/brief-validation.ts
1648
1673
  function headerRegion(prBody) {
1649
1674
  const m = prBody.match(/^##\s/m);
@@ -1682,10 +1707,15 @@ function checkTierField(prBody, readTier) {
1682
1707
  };
1683
1708
  }
1684
1709
  var TEST_PLAN_UNIT_TESTS_ONLY_RE = /(?:\*\*)?Test Plan(?:\*\*)?\s*:\s*(?:\*\*)?\s*unit-tests-only/i;
1710
+ function testPlanRegion(prBody) {
1711
+ const located = locateTestPlanSection(prBody);
1712
+ return located.found ? located.section : prBody;
1713
+ }
1685
1714
  function checkTestPlan(prBody) {
1686
- if (TEST_PLAN_UNIT_TESTS_ONLY_RE.test(prBody))
1715
+ const region = testPlanRegion(prBody);
1716
+ if (TEST_PLAN_UNIT_TESTS_ONLY_RE.test(region))
1687
1717
  return { status: "pass", errors: [] };
1688
- if (/\*\*\[(?:agent|principal)\]\*\*/.test(prBody))
1718
+ if (/\*\*\[(?:agent|principal)\]\*\*/.test(region))
1689
1719
  return { status: "pass", errors: [] };
1690
1720
  return {
1691
1721
  status: "fail",
@@ -1695,9 +1725,10 @@ function checkTestPlan(prBody) {
1695
1725
  };
1696
1726
  }
1697
1727
  function checkTestPlanExclusivity(prBody) {
1698
- if (!TEST_PLAN_UNIT_TESTS_ONLY_RE.test(prBody))
1728
+ const region = testPlanRegion(prBody);
1729
+ if (!TEST_PLAN_UNIT_TESTS_ONLY_RE.test(region))
1699
1730
  return { status: "pass", errors: [] };
1700
- if (/^-\s*\[[ xX]\]\s*\*{2}\[(?:agent|principal)\]\*{2}/im.test(prBody)) {
1731
+ if (/^-\s*\[[ xX]\]\s*\*{2}\[(?:agent|principal)\]\*{2}/im.test(region)) {
1701
1732
  return {
1702
1733
  status: "fail",
1703
1734
  errors: [
@@ -1708,8 +1739,9 @@ function checkTestPlanExclusivity(prBody) {
1708
1739
  return { status: "pass", errors: [] };
1709
1740
  }
1710
1741
  function checkPrincipalPlaceholder(prBody) {
1742
+ const region = testPlanRegion(prBody);
1711
1743
  const lineRe = /^-\s*\[[ xX]\]\s*\*{2}\[principal\]\*{2}(.*)$/gim;
1712
- for (const m of prBody.matchAll(lineRe)) {
1744
+ for (const m of region.matchAll(lineRe)) {
1713
1745
  const content = m[1] ?? "";
1714
1746
  if (/^\s*None\b/i.test(content)) {
1715
1747
  return {
@@ -1788,6 +1820,15 @@ function checkClosesN(prBody) {
1788
1820
  errors: ["brief-validation Closes #N: no `Closes #<N>` (or Fixes/Resolves) reference found in the PR body."]
1789
1821
  };
1790
1822
  }
1823
+ var BRIEF_SHAPE_MARKERS = [checkSurfaceMap, checkDocUpdateList, checkStopConditions, checkAutonomyClause];
1824
+ var TASK_BRANCH_PATTERN = /^task\/[^/]+\/[^/]+$/;
1825
+ function isTaskBranch(branch) {
1826
+ return TASK_BRANCH_PATTERN.test(branch);
1827
+ }
1828
+ function isBriefShaped(prBody) {
1829
+ const stripped = stripCode(prBody);
1830
+ return BRIEF_SHAPE_MARKERS.filter((check) => check(stripped).status === "pass").length >= 2;
1831
+ }
1791
1832
  function checkBriefSections(prBody, readTier, options = {}) {
1792
1833
  const { requireClosesN = true } = options;
1793
1834
  const results = [
@@ -2157,11 +2198,12 @@ function isReviewGateExemptBranch(branch) {
2157
2198
  return branch.startsWith("plan/");
2158
2199
  }
2159
2200
  function checkReviewGate(input) {
2201
+ const principalAllowlist = input.principalAllowlist ?? PRINCIPAL_ALLOWLIST;
2160
2202
  const waived = isWaiverLabelActorVerified({
2161
2203
  label: WAIVER_LABEL_REVIEW,
2162
2204
  labels: input.labels,
2163
2205
  labelActor: input.waiverLabelActor,
2164
- principalAllowlist: PRINCIPAL_ALLOWLIST
2206
+ principalAllowlist
2165
2207
  });
2166
2208
  if (waived) {
2167
2209
  return {
@@ -2170,8 +2212,8 @@ function checkReviewGate(input) {
2170
2212
  waived: true
2171
2213
  };
2172
2214
  }
2173
- const verified = input.comments.filter((c) => c.author !== null && PRINCIPAL_ALLOWLIST.includes(c.author));
2174
- const ignoredCount = input.comments.filter((c) => (c.author === null || !PRINCIPAL_ALLOWLIST.includes(c.author)) && c.body.includes("VERDICT")).length;
2215
+ const verified = input.comments.filter((c) => isPrincipal(c.author, principalAllowlist));
2216
+ const ignoredCount = input.comments.filter((c) => !isPrincipal(c.author, principalAllowlist) && c.body.includes("VERDICT")).length;
2175
2217
  const verifiedBodies = verified.map((c) => c.body);
2176
2218
  const codeReview = extractCodeReviewVerdict(verifiedBodies);
2177
2219
  const security = extractSecurityReviewVerdict(verifiedBodies);
@@ -2724,28 +2766,8 @@ function decideIssueAssignment(input) {
2724
2766
  reason: `First push of \`${branch}\` — assigning Issue #${issue} to @${login} (the authenticated pusher).`
2725
2767
  };
2726
2768
  }
2727
- // ../../../packages/aeg-core/src/test-plan-section.ts
2728
- var HEADING_FORM_RE = /^#{1,4}[ \t]*(?:\d+[a-z]?\.[ \t]*)?\*{0,2}Test Plan\*{0,2}[ \t]*$/im;
2729
- var INLINE_FORM_RE = /^[ \t]*\*{0,2}Test Plan:?\*{0,2}/im;
2730
- var NEXT_SECTION_RE = /\n(?:#{1,3}[ \t]|\*\*[A-Z][^*\n]*:\*\*)/;
2731
- function locateTestPlanSection(body) {
2732
- const region = anchoredRegion(body, "TEST-PLAN");
2733
- if (region !== null)
2734
- return { found: true, section: region };
2735
- const headingMatch = HEADING_FORM_RE.exec(body);
2736
- const match = headingMatch ?? INLINE_FORM_RE.exec(body);
2737
- if (!match || match.index === undefined)
2738
- return { found: false };
2739
- const sectionBody = body.slice(match.index);
2740
- const firstLineEnd = sectionBody.indexOf(`
2741
- `);
2742
- const searchFrom = firstLineEnd === -1 ? sectionBody.length : firstLineEnd + 1;
2743
- const nextMatch = sectionBody.slice(searchFrom).match(NEXT_SECTION_RE);
2744
- const sectionEnd = nextMatch ? searchFrom + (nextMatch.index ?? 0) : sectionBody.length;
2745
- return { found: true, section: sectionBody.slice(0, sectionEnd) };
2746
- }
2747
2769
  // ../../../packages/aeg-core/src/test-plan-gate.ts
2748
- var TASK_BRANCH_PATTERN = /^task\/[^/]+\/[^/]+$/;
2770
+ var TASK_BRANCH_PATTERN2 = /^task\/[^/]+\/[^/]+$/;
2749
2771
  function evaluateTestPlanGate(body, branch) {
2750
2772
  if (!body) {
2751
2773
  return {
@@ -2758,7 +2780,7 @@ function evaluateTestPlanGate(body, branch) {
2758
2780
  }
2759
2781
  const located = locateTestPlanSection(body);
2760
2782
  if (!located.found) {
2761
- if (TASK_BRANCH_PATTERN.test(branch)) {
2783
+ if (TASK_BRANCH_PATTERN2.test(branch)) {
2762
2784
  return {
2763
2785
  verdict: "fail",
2764
2786
  messages: [
@@ -1448,12 +1448,16 @@ function isCodeFile(p) {
1448
1448
  var WAIVER_LABEL = label("waiver-docs");
1449
1449
  var WAIVER_LABEL_REVIEW = label("waiver-review");
1450
1450
  var PRINCIPAL_ALLOWLIST = ["daniboomerang"];
1451
+ function isPrincipal(login, principalAllowlist) {
1452
+ if (login === null)
1453
+ return false;
1454
+ const normalized = login.toLowerCase();
1455
+ return principalAllowlist.some((p) => p.toLowerCase() === normalized);
1456
+ }
1451
1457
  function isWaiverLabelActorVerified(opts) {
1452
1458
  if (!opts.labels.includes(opts.label))
1453
1459
  return false;
1454
- if (opts.labelActor === null)
1455
- return false;
1456
- return opts.principalAllowlist.includes(opts.labelActor);
1460
+ return isPrincipal(opts.labelActor, opts.principalAllowlist);
1457
1461
  }
1458
1462
 
1459
1463
  // ../../../packages/aeg-core/src/doc-owners.ts
@@ -1641,6 +1645,27 @@ function overrideActive(opts) {
1641
1645
  // ../../../packages/aeg-core/src/premise-check.ts
1642
1646
  var ASSERTION_KINDS = new Set(["contains", "absent", "sha256"]);
1643
1647
 
1648
+ // ../../../packages/aeg-core/src/test-plan-section.ts
1649
+ var HEADING_FORM_RE = /^#{1,4}[ \t]*(?:\d+[a-z]?\.[ \t]*)?\*{0,2}Test Plan\*{0,2}[ \t]*$/im;
1650
+ var INLINE_FORM_RE = /^[ \t]*\*{0,2}Test Plan:?\*{0,2}/im;
1651
+ var NEXT_SECTION_RE = /\n(?:#{1,3}[ \t]|\*\*[A-Z][^*\n]*:\*\*)/;
1652
+ function locateTestPlanSection(body) {
1653
+ const region = anchoredRegion(body, "TEST-PLAN");
1654
+ if (region !== null)
1655
+ return { found: true, section: region };
1656
+ const headingMatch = HEADING_FORM_RE.exec(body);
1657
+ const match = headingMatch ?? INLINE_FORM_RE.exec(body);
1658
+ if (!match || match.index === undefined)
1659
+ return { found: false };
1660
+ const sectionBody = body.slice(match.index);
1661
+ const firstLineEnd = sectionBody.indexOf(`
1662
+ `);
1663
+ const searchFrom = firstLineEnd === -1 ? sectionBody.length : firstLineEnd + 1;
1664
+ const nextMatch = sectionBody.slice(searchFrom).match(NEXT_SECTION_RE);
1665
+ const sectionEnd = nextMatch ? searchFrom + (nextMatch.index ?? 0) : sectionBody.length;
1666
+ return { found: true, section: sectionBody.slice(0, sectionEnd) };
1667
+ }
1668
+
1644
1669
  // ../../../packages/aeg-core/src/brief-validation.ts
1645
1670
  function headerRegion(prBody) {
1646
1671
  const m = prBody.match(/^##\s/m);
@@ -1679,10 +1704,15 @@ function checkTierField(prBody, readTier) {
1679
1704
  };
1680
1705
  }
1681
1706
  var TEST_PLAN_UNIT_TESTS_ONLY_RE = /(?:\*\*)?Test Plan(?:\*\*)?\s*:\s*(?:\*\*)?\s*unit-tests-only/i;
1707
+ function testPlanRegion(prBody) {
1708
+ const located = locateTestPlanSection(prBody);
1709
+ return located.found ? located.section : prBody;
1710
+ }
1682
1711
  function checkTestPlan(prBody) {
1683
- if (TEST_PLAN_UNIT_TESTS_ONLY_RE.test(prBody))
1712
+ const region = testPlanRegion(prBody);
1713
+ if (TEST_PLAN_UNIT_TESTS_ONLY_RE.test(region))
1684
1714
  return { status: "pass", errors: [] };
1685
- if (/\*\*\[(?:agent|principal)\]\*\*/.test(prBody))
1715
+ if (/\*\*\[(?:agent|principal)\]\*\*/.test(region))
1686
1716
  return { status: "pass", errors: [] };
1687
1717
  return {
1688
1718
  status: "fail",
@@ -1692,9 +1722,10 @@ function checkTestPlan(prBody) {
1692
1722
  };
1693
1723
  }
1694
1724
  function checkTestPlanExclusivity(prBody) {
1695
- if (!TEST_PLAN_UNIT_TESTS_ONLY_RE.test(prBody))
1725
+ const region = testPlanRegion(prBody);
1726
+ if (!TEST_PLAN_UNIT_TESTS_ONLY_RE.test(region))
1696
1727
  return { status: "pass", errors: [] };
1697
- if (/^-\s*\[[ xX]\]\s*\*{2}\[(?:agent|principal)\]\*{2}/im.test(prBody)) {
1728
+ if (/^-\s*\[[ xX]\]\s*\*{2}\[(?:agent|principal)\]\*{2}/im.test(region)) {
1698
1729
  return {
1699
1730
  status: "fail",
1700
1731
  errors: [
@@ -1705,8 +1736,9 @@ function checkTestPlanExclusivity(prBody) {
1705
1736
  return { status: "pass", errors: [] };
1706
1737
  }
1707
1738
  function checkPrincipalPlaceholder(prBody) {
1739
+ const region = testPlanRegion(prBody);
1708
1740
  const lineRe = /^-\s*\[[ xX]\]\s*\*{2}\[principal\]\*{2}(.*)$/gim;
1709
- for (const m of prBody.matchAll(lineRe)) {
1741
+ for (const m of region.matchAll(lineRe)) {
1710
1742
  const content = m[1] ?? "";
1711
1743
  if (/^\s*None\b/i.test(content)) {
1712
1744
  return {
@@ -1785,6 +1817,15 @@ function checkClosesN(prBody) {
1785
1817
  errors: ["brief-validation Closes #N: no `Closes #<N>` (or Fixes/Resolves) reference found in the PR body."]
1786
1818
  };
1787
1819
  }
1820
+ var BRIEF_SHAPE_MARKERS = [checkSurfaceMap, checkDocUpdateList, checkStopConditions, checkAutonomyClause];
1821
+ var TASK_BRANCH_PATTERN = /^task\/[^/]+\/[^/]+$/;
1822
+ function isTaskBranch(branch) {
1823
+ return TASK_BRANCH_PATTERN.test(branch);
1824
+ }
1825
+ function isBriefShaped(prBody) {
1826
+ const stripped = stripCode(prBody);
1827
+ return BRIEF_SHAPE_MARKERS.filter((check) => check(stripped).status === "pass").length >= 2;
1828
+ }
1788
1829
  function checkBriefSections(prBody, readTier, options = {}) {
1789
1830
  const { requireClosesN = true } = options;
1790
1831
  const results = [
@@ -2154,11 +2195,12 @@ function isReviewGateExemptBranch(branch) {
2154
2195
  return branch.startsWith("plan/");
2155
2196
  }
2156
2197
  function checkReviewGate(input) {
2198
+ const principalAllowlist = input.principalAllowlist ?? PRINCIPAL_ALLOWLIST;
2157
2199
  const waived = isWaiverLabelActorVerified({
2158
2200
  label: WAIVER_LABEL_REVIEW,
2159
2201
  labels: input.labels,
2160
2202
  labelActor: input.waiverLabelActor,
2161
- principalAllowlist: PRINCIPAL_ALLOWLIST
2203
+ principalAllowlist
2162
2204
  });
2163
2205
  if (waived) {
2164
2206
  return {
@@ -2167,8 +2209,8 @@ function checkReviewGate(input) {
2167
2209
  waived: true
2168
2210
  };
2169
2211
  }
2170
- const verified = input.comments.filter((c) => c.author !== null && PRINCIPAL_ALLOWLIST.includes(c.author));
2171
- const ignoredCount = input.comments.filter((c) => (c.author === null || !PRINCIPAL_ALLOWLIST.includes(c.author)) && c.body.includes("VERDICT")).length;
2212
+ const verified = input.comments.filter((c) => isPrincipal(c.author, principalAllowlist));
2213
+ const ignoredCount = input.comments.filter((c) => !isPrincipal(c.author, principalAllowlist) && c.body.includes("VERDICT")).length;
2172
2214
  const verifiedBodies = verified.map((c) => c.body);
2173
2215
  const codeReview = extractCodeReviewVerdict(verifiedBodies);
2174
2216
  const security = extractSecurityReviewVerdict(verifiedBodies);
@@ -2721,28 +2763,8 @@ function decideIssueAssignment(input) {
2721
2763
  reason: `First push of \`${branch}\` — assigning Issue #${issue} to @${login} (the authenticated pusher).`
2722
2764
  };
2723
2765
  }
2724
- // ../../../packages/aeg-core/src/test-plan-section.ts
2725
- var HEADING_FORM_RE = /^#{1,4}[ \t]*(?:\d+[a-z]?\.[ \t]*)?\*{0,2}Test Plan\*{0,2}[ \t]*$/im;
2726
- var INLINE_FORM_RE = /^[ \t]*\*{0,2}Test Plan:?\*{0,2}/im;
2727
- var NEXT_SECTION_RE = /\n(?:#{1,3}[ \t]|\*\*[A-Z][^*\n]*:\*\*)/;
2728
- function locateTestPlanSection(body) {
2729
- const region = anchoredRegion(body, "TEST-PLAN");
2730
- if (region !== null)
2731
- return { found: true, section: region };
2732
- const headingMatch = HEADING_FORM_RE.exec(body);
2733
- const match = headingMatch ?? INLINE_FORM_RE.exec(body);
2734
- if (!match || match.index === undefined)
2735
- return { found: false };
2736
- const sectionBody = body.slice(match.index);
2737
- const firstLineEnd = sectionBody.indexOf(`
2738
- `);
2739
- const searchFrom = firstLineEnd === -1 ? sectionBody.length : firstLineEnd + 1;
2740
- const nextMatch = sectionBody.slice(searchFrom).match(NEXT_SECTION_RE);
2741
- const sectionEnd = nextMatch ? searchFrom + (nextMatch.index ?? 0) : sectionBody.length;
2742
- return { found: true, section: sectionBody.slice(0, sectionEnd) };
2743
- }
2744
2766
  // ../../../packages/aeg-core/src/test-plan-gate.ts
2745
- var TASK_BRANCH_PATTERN = /^task\/[^/]+\/[^/]+$/;
2767
+ var TASK_BRANCH_PATTERN2 = /^task\/[^/]+\/[^/]+$/;
2746
2768
  function evaluateTestPlanGate(body, branch) {
2747
2769
  if (!body) {
2748
2770
  return {
@@ -2755,7 +2777,7 @@ function evaluateTestPlanGate(body, branch) {
2755
2777
  }
2756
2778
  const located = locateTestPlanSection(body);
2757
2779
  if (!located.found) {
2758
- if (TASK_BRANCH_PATTERN.test(branch)) {
2780
+ if (TASK_BRANCH_PATTERN2.test(branch)) {
2759
2781
  return {
2760
2782
  verdict: "fail",
2761
2783
  messages: [
@@ -2819,7 +2841,12 @@ function main() {
2819
2841
  if (!prBody) {
2820
2842
  process.exit(0);
2821
2843
  }
2822
- const { errors } = checkBriefSections(prBody, readTierFromPrBody);
2844
+ const branch = process.env.BRANCH ?? "";
2845
+ const taskBranch = isTaskBranch(branch);
2846
+ if (branch && !taskBranch && !isBriefShaped(prBody)) {
2847
+ process.exit(0);
2848
+ }
2849
+ const { errors } = checkBriefSections(prBody, readTierFromPrBody, { requireClosesN: taskBranch });
2823
2850
  if (errors.length > 0) {
2824
2851
  for (const message of errors) {
2825
2852
  emitCheckError({
@@ -1451,12 +1451,16 @@ function isCodeFile(p) {
1451
1451
  var WAIVER_LABEL = label("waiver-docs");
1452
1452
  var WAIVER_LABEL_REVIEW = label("waiver-review");
1453
1453
  var PRINCIPAL_ALLOWLIST = ["daniboomerang"];
1454
+ function isPrincipal(login, principalAllowlist) {
1455
+ if (login === null)
1456
+ return false;
1457
+ const normalized = login.toLowerCase();
1458
+ return principalAllowlist.some((p) => p.toLowerCase() === normalized);
1459
+ }
1454
1460
  function isWaiverLabelActorVerified(opts) {
1455
1461
  if (!opts.labels.includes(opts.label))
1456
1462
  return false;
1457
- if (opts.labelActor === null)
1458
- return false;
1459
- return opts.principalAllowlist.includes(opts.labelActor);
1463
+ return isPrincipal(opts.labelActor, opts.principalAllowlist);
1460
1464
  }
1461
1465
 
1462
1466
  // ../../../packages/aeg-core/src/doc-owners.ts
@@ -1644,6 +1648,27 @@ function overrideActive(opts) {
1644
1648
  // ../../../packages/aeg-core/src/premise-check.ts
1645
1649
  var ASSERTION_KINDS = new Set(["contains", "absent", "sha256"]);
1646
1650
 
1651
+ // ../../../packages/aeg-core/src/test-plan-section.ts
1652
+ var HEADING_FORM_RE = /^#{1,4}[ \t]*(?:\d+[a-z]?\.[ \t]*)?\*{0,2}Test Plan\*{0,2}[ \t]*$/im;
1653
+ var INLINE_FORM_RE = /^[ \t]*\*{0,2}Test Plan:?\*{0,2}/im;
1654
+ var NEXT_SECTION_RE = /\n(?:#{1,3}[ \t]|\*\*[A-Z][^*\n]*:\*\*)/;
1655
+ function locateTestPlanSection(body) {
1656
+ const region = anchoredRegion(body, "TEST-PLAN");
1657
+ if (region !== null)
1658
+ return { found: true, section: region };
1659
+ const headingMatch = HEADING_FORM_RE.exec(body);
1660
+ const match = headingMatch ?? INLINE_FORM_RE.exec(body);
1661
+ if (!match || match.index === undefined)
1662
+ return { found: false };
1663
+ const sectionBody = body.slice(match.index);
1664
+ const firstLineEnd = sectionBody.indexOf(`
1665
+ `);
1666
+ const searchFrom = firstLineEnd === -1 ? sectionBody.length : firstLineEnd + 1;
1667
+ const nextMatch = sectionBody.slice(searchFrom).match(NEXT_SECTION_RE);
1668
+ const sectionEnd = nextMatch ? searchFrom + (nextMatch.index ?? 0) : sectionBody.length;
1669
+ return { found: true, section: sectionBody.slice(0, sectionEnd) };
1670
+ }
1671
+
1647
1672
  // ../../../packages/aeg-core/src/brief-validation.ts
1648
1673
  function headerRegion(prBody) {
1649
1674
  const m = prBody.match(/^##\s/m);
@@ -1682,10 +1707,15 @@ function checkTierField(prBody, readTier) {
1682
1707
  };
1683
1708
  }
1684
1709
  var TEST_PLAN_UNIT_TESTS_ONLY_RE = /(?:\*\*)?Test Plan(?:\*\*)?\s*:\s*(?:\*\*)?\s*unit-tests-only/i;
1710
+ function testPlanRegion(prBody) {
1711
+ const located = locateTestPlanSection(prBody);
1712
+ return located.found ? located.section : prBody;
1713
+ }
1685
1714
  function checkTestPlan(prBody) {
1686
- if (TEST_PLAN_UNIT_TESTS_ONLY_RE.test(prBody))
1715
+ const region = testPlanRegion(prBody);
1716
+ if (TEST_PLAN_UNIT_TESTS_ONLY_RE.test(region))
1687
1717
  return { status: "pass", errors: [] };
1688
- if (/\*\*\[(?:agent|principal)\]\*\*/.test(prBody))
1718
+ if (/\*\*\[(?:agent|principal)\]\*\*/.test(region))
1689
1719
  return { status: "pass", errors: [] };
1690
1720
  return {
1691
1721
  status: "fail",
@@ -1695,9 +1725,10 @@ function checkTestPlan(prBody) {
1695
1725
  };
1696
1726
  }
1697
1727
  function checkTestPlanExclusivity(prBody) {
1698
- if (!TEST_PLAN_UNIT_TESTS_ONLY_RE.test(prBody))
1728
+ const region = testPlanRegion(prBody);
1729
+ if (!TEST_PLAN_UNIT_TESTS_ONLY_RE.test(region))
1699
1730
  return { status: "pass", errors: [] };
1700
- if (/^-\s*\[[ xX]\]\s*\*{2}\[(?:agent|principal)\]\*{2}/im.test(prBody)) {
1731
+ if (/^-\s*\[[ xX]\]\s*\*{2}\[(?:agent|principal)\]\*{2}/im.test(region)) {
1701
1732
  return {
1702
1733
  status: "fail",
1703
1734
  errors: [
@@ -1708,8 +1739,9 @@ function checkTestPlanExclusivity(prBody) {
1708
1739
  return { status: "pass", errors: [] };
1709
1740
  }
1710
1741
  function checkPrincipalPlaceholder(prBody) {
1742
+ const region = testPlanRegion(prBody);
1711
1743
  const lineRe = /^-\s*\[[ xX]\]\s*\*{2}\[principal\]\*{2}(.*)$/gim;
1712
- for (const m of prBody.matchAll(lineRe)) {
1744
+ for (const m of region.matchAll(lineRe)) {
1713
1745
  const content = m[1] ?? "";
1714
1746
  if (/^\s*None\b/i.test(content)) {
1715
1747
  return {
@@ -1788,6 +1820,15 @@ function checkClosesN(prBody) {
1788
1820
  errors: ["brief-validation Closes #N: no `Closes #<N>` (or Fixes/Resolves) reference found in the PR body."]
1789
1821
  };
1790
1822
  }
1823
+ var BRIEF_SHAPE_MARKERS = [checkSurfaceMap, checkDocUpdateList, checkStopConditions, checkAutonomyClause];
1824
+ var TASK_BRANCH_PATTERN = /^task\/[^/]+\/[^/]+$/;
1825
+ function isTaskBranch(branch) {
1826
+ return TASK_BRANCH_PATTERN.test(branch);
1827
+ }
1828
+ function isBriefShaped(prBody) {
1829
+ const stripped = stripCode(prBody);
1830
+ return BRIEF_SHAPE_MARKERS.filter((check) => check(stripped).status === "pass").length >= 2;
1831
+ }
1791
1832
  function checkBriefSections(prBody, readTier, options = {}) {
1792
1833
  const { requireClosesN = true } = options;
1793
1834
  const results = [
@@ -2157,11 +2198,12 @@ function isReviewGateExemptBranch(branch) {
2157
2198
  return branch.startsWith("plan/");
2158
2199
  }
2159
2200
  function checkReviewGate(input) {
2201
+ const principalAllowlist = input.principalAllowlist ?? PRINCIPAL_ALLOWLIST;
2160
2202
  const waived = isWaiverLabelActorVerified({
2161
2203
  label: WAIVER_LABEL_REVIEW,
2162
2204
  labels: input.labels,
2163
2205
  labelActor: input.waiverLabelActor,
2164
- principalAllowlist: PRINCIPAL_ALLOWLIST
2206
+ principalAllowlist
2165
2207
  });
2166
2208
  if (waived) {
2167
2209
  return {
@@ -2170,8 +2212,8 @@ function checkReviewGate(input) {
2170
2212
  waived: true
2171
2213
  };
2172
2214
  }
2173
- const verified = input.comments.filter((c) => c.author !== null && PRINCIPAL_ALLOWLIST.includes(c.author));
2174
- const ignoredCount = input.comments.filter((c) => (c.author === null || !PRINCIPAL_ALLOWLIST.includes(c.author)) && c.body.includes("VERDICT")).length;
2215
+ const verified = input.comments.filter((c) => isPrincipal(c.author, principalAllowlist));
2216
+ const ignoredCount = input.comments.filter((c) => !isPrincipal(c.author, principalAllowlist) && c.body.includes("VERDICT")).length;
2175
2217
  const verifiedBodies = verified.map((c) => c.body);
2176
2218
  const codeReview = extractCodeReviewVerdict(verifiedBodies);
2177
2219
  const security = extractSecurityReviewVerdict(verifiedBodies);
@@ -2724,28 +2766,8 @@ function decideIssueAssignment(input) {
2724
2766
  reason: `First push of \`${branch}\` — assigning Issue #${issue} to @${login} (the authenticated pusher).`
2725
2767
  };
2726
2768
  }
2727
- // ../../../packages/aeg-core/src/test-plan-section.ts
2728
- var HEADING_FORM_RE = /^#{1,4}[ \t]*(?:\d+[a-z]?\.[ \t]*)?\*{0,2}Test Plan\*{0,2}[ \t]*$/im;
2729
- var INLINE_FORM_RE = /^[ \t]*\*{0,2}Test Plan:?\*{0,2}/im;
2730
- var NEXT_SECTION_RE = /\n(?:#{1,3}[ \t]|\*\*[A-Z][^*\n]*:\*\*)/;
2731
- function locateTestPlanSection(body) {
2732
- const region = anchoredRegion(body, "TEST-PLAN");
2733
- if (region !== null)
2734
- return { found: true, section: region };
2735
- const headingMatch = HEADING_FORM_RE.exec(body);
2736
- const match = headingMatch ?? INLINE_FORM_RE.exec(body);
2737
- if (!match || match.index === undefined)
2738
- return { found: false };
2739
- const sectionBody = body.slice(match.index);
2740
- const firstLineEnd = sectionBody.indexOf(`
2741
- `);
2742
- const searchFrom = firstLineEnd === -1 ? sectionBody.length : firstLineEnd + 1;
2743
- const nextMatch = sectionBody.slice(searchFrom).match(NEXT_SECTION_RE);
2744
- const sectionEnd = nextMatch ? searchFrom + (nextMatch.index ?? 0) : sectionBody.length;
2745
- return { found: true, section: sectionBody.slice(0, sectionEnd) };
2746
- }
2747
2769
  // ../../../packages/aeg-core/src/test-plan-gate.ts
2748
- var TASK_BRANCH_PATTERN = /^task\/[^/]+\/[^/]+$/;
2770
+ var TASK_BRANCH_PATTERN2 = /^task\/[^/]+\/[^/]+$/;
2749
2771
  function evaluateTestPlanGate(body, branch) {
2750
2772
  if (!body) {
2751
2773
  return {
@@ -2758,7 +2780,7 @@ function evaluateTestPlanGate(body, branch) {
2758
2780
  }
2759
2781
  const located = locateTestPlanSection(body);
2760
2782
  if (!located.found) {
2761
- if (TASK_BRANCH_PATTERN.test(branch)) {
2783
+ if (TASK_BRANCH_PATTERN2.test(branch)) {
2762
2784
  return {
2763
2785
  verdict: "fail",
2764
2786
  messages: [