@attalabs/vinaya 0.24.1 → 0.26.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 (130) hide show
  1. package/README.md +26 -3
  2. package/aeg-root/contracts/architect-planner.md +5 -5
  3. package/aeg-root/contracts/developer-reviewer.md +10 -7
  4. package/aeg-root/contracts/planner-developer.md +142 -0
  5. package/aeg-root/contracts/reviewer-archivist.md +2 -2
  6. package/aeg-root/contracts/tranche-archivist-planner.md +12 -11
  7. package/aeg-root/enforcement.md +25 -11
  8. package/aeg-root/process.md +53 -75
  9. package/aeg-root/roles/archivist.md +3 -3
  10. package/aeg-root/roles/developer.md +30 -24
  11. package/aeg-root/roles/planner.md +100 -21
  12. package/aeg-root/roles/principal.md +14 -11
  13. package/aeg-root/roles/reviewer.md +33 -17
  14. package/aeg-root/roles/security.md +28 -13
  15. package/aeg-root/roles/tranche-archivist.md +2 -2
  16. package/aeg-root/skills/aeg/SKILL.md +5 -5
  17. package/aeg-root/skills/aeg-roles/SKILL.md +7 -7
  18. package/aeg-root/state-machine.md +36 -35
  19. package/aeg-root/task-model.md +3 -3
  20. package/aeg-root/templates/brief-template.md +22 -6
  21. package/aeg-root/templates/issue-rationale-template.md +35 -2
  22. package/aeg-root/templates/pr-report-template.md +5 -13
  23. package/aeg-root/tranche-model.md +21 -21
  24. package/dist/checks/bin/check-body-bare-digits.js +684 -142
  25. package/dist/checks/bin/check-branch-topology.js +741 -88
  26. package/dist/checks/bin/check-brief-shape.js +708 -83
  27. package/dist/checks/bin/check-changeset-coverage.js +1445 -149
  28. package/dist/checks/bin/check-closes-n.js +741 -88
  29. package/dist/checks/bin/check-coherence.js +808 -149
  30. package/dist/checks/bin/check-dead-branch-push.js +617 -81
  31. package/dist/checks/bin/check-dispatch-readiness.js +811 -152
  32. package/dist/checks/bin/check-doc-coverage-push.js +1445 -149
  33. package/dist/checks/bin/check-doc-coverage.js +1447 -151
  34. package/dist/checks/bin/check-doctrine-no-procedures.js +684 -142
  35. package/dist/checks/bin/check-doctrine-portability.js +1445 -149
  36. package/dist/checks/bin/check-evidence-fresh.js +684 -142
  37. package/dist/checks/bin/check-exec-bits.js +1445 -149
  38. package/dist/checks/bin/check-first-push-dispatch.js +808 -149
  39. package/dist/checks/bin/check-issue-assignment.js +741 -88
  40. package/dist/checks/bin/check-main-branch-refusal.js +618 -82
  41. package/dist/checks/bin/check-no-disk-state.js +617 -81
  42. package/dist/checks/bin/check-pr-premise-reassert.js +5401 -0
  43. package/dist/checks/bin/check-pr-report-density.js +617 -81
  44. package/dist/checks/bin/check-quoted-command.js +1443 -147
  45. package/dist/checks/bin/check-reader-resolvable-prose.js +1481 -153
  46. package/dist/checks/bin/check-registry-gates.js +659 -85
  47. package/dist/checks/bin/check-retired-vocabulary.js +1443 -147
  48. package/dist/checks/bin/check-review-gate.js +758 -145
  49. package/dist/checks/bin/check-single-plan-pr.js +617 -81
  50. package/dist/checks/bin/check-surface-scope.js +5722 -0
  51. package/dist/checks/bin/check-test-plan.js +617 -81
  52. package/dist/checks/bin/check-token-collection-wired.js +617 -81
  53. package/dist/checks/bin/check-token-report.js +629 -88
  54. package/dist/checks/bin/check-workspace-escape.js +1443 -147
  55. package/dist/index.js +8548 -4335
  56. package/package.json +1 -1
  57. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/brief-render.ts +2 -2
  58. package/studio-standalone/_node_modules/@attalabs/aeg-core/src/main-branch-refusal.ts +26 -1
  59. package/studio-standalone/apps/vinaya-studio/web/.next/BUILD_ID +1 -1
  60. package/studio-standalone/apps/vinaya-studio/web/.next/build-manifest.json +3 -3
  61. package/studio-standalone/apps/vinaya-studio/web/.next/prerender-manifest.json +3 -3
  62. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.html +1 -1
  63. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.rsc +1 -1
  64. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  65. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  66. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  67. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  68. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  69. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page/server-reference-manifest.json +2 -2
  70. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  71. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  72. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/api/coherence/route.js.nft.json +1 -1
  73. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page/server-reference-manifest.json +2 -2
  74. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page.js.nft.json +1 -1
  75. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page_client-reference-manifest.js +1 -1
  76. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page/server-reference-manifest.json +2 -2
  77. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page.js.nft.json +1 -1
  78. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page_client-reference-manifest.js +1 -1
  79. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page/server-reference-manifest.json +2 -2
  80. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page.js.nft.json +1 -1
  81. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page_client-reference-manifest.js +1 -1
  82. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page/server-reference-manifest.json +2 -2
  83. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page.js.nft.json +1 -1
  84. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page_client-reference-manifest.js +1 -1
  85. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page/server-reference-manifest.json +2 -2
  86. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page.js.nft.json +1 -1
  87. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page_client-reference-manifest.js +1 -1
  88. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page/server-reference-manifest.json +2 -2
  89. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page.js.nft.json +1 -1
  90. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page_client-reference-manifest.js +1 -1
  91. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page/server-reference-manifest.json +2 -2
  92. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page.js.nft.json +1 -1
  93. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page_client-reference-manifest.js +1 -1
  94. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page/server-reference-manifest.json +2 -2
  95. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page.js.nft.json +1 -1
  96. package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page_client-reference-manifest.js +1 -1
  97. 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
  98. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0053k9k._.js +1 -1
  99. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0112h-k._.js +1 -1
  100. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0o771t1._.js +1 -1
  101. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__1pndh3_._.js → [root-of-the-server]__0p8q38b._.js} +1 -1
  102. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0puovz5._.js +1 -1
  103. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1hs0dcu._.js +1 -1
  104. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1wc4-ip._.js +1 -1
  105. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_03x_w6q._.js +1 -1
  106. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0gvm3og._.js +1 -1
  107. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0lwxg63._.js +1 -1
  108. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0wxycau._.js +1 -1
  109. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1n0cnq-._.js +1 -1
  110. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/node_modules_1vo08dj._.js +2 -2
  111. package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_topbar_index_tsx_1h1gs1y._.js +1 -1
  112. package/studio-standalone/apps/vinaya-studio/web/.next/server/middleware-build-manifest.js +3 -3
  113. package/studio-standalone/apps/vinaya-studio/web/.next/server/pages/500.html +1 -1
  114. package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.js +1 -1
  115. package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.json +3 -3
  116. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{3m1kgax7j2vgs.js → 0bn8c8v5q429o.js} +1 -1
  117. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0doqwpd81sjzn.js → 0keji7wvbe1d1.js} +1 -1
  118. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/1maoxbrl3pv5d.css +1 -0
  119. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1uogpj5w2n5ju.js → 3-6a3tinbdb-7.js} +1 -1
  120. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0zebsmmk1bvnb.js → 3_9xytdmiv1xi.js} +4 -4
  121. package/studio-standalone/apps/vinaya-studio/web/package.json +2 -2
  122. package/aeg-root/contracts/brief-developer.md +0 -141
  123. package/aeg-root/contracts/planner-brief.md +0 -130
  124. package/aeg-root/roles/brief-author.md +0 -114
  125. package/aeg-root/skills/brief-authoring/SKILL.md +0 -509
  126. package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/3qc67qhcvbg0o.css +0 -1
  127. /package/studio-standalone/_node_modules/@attalabs/vinaya/studio-standalone/_node_modules/@attalabs/vinaya/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
  128. /package/studio-standalone/apps/vinaya-studio/web/.next/static/{QY2GhiI47-765D9DHGy1I → DMofV2-9FrHE7100GfrpI}/_buildManifest.js +0 -0
  129. /package/studio-standalone/apps/vinaya-studio/web/.next/static/{QY2GhiI47-765D9DHGy1I → DMofV2-9FrHE7100GfrpI}/_clientMiddlewareManifest.js +0 -0
  130. /package/studio-standalone/apps/vinaya-studio/web/.next/static/{QY2GhiI47-765D9DHGy1I → DMofV2-9FrHE7100GfrpI}/_ssgManifest.js +0 -0
@@ -11,8 +11,8 @@
11
11
  "test": "vitest run"
12
12
  },
13
13
  "dependencies": {
14
- "@attalabs/aeg-core": "^0.23.0",
15
- "@attalabs/aeg-forge-state": "^0.23.0",
14
+ "@attalabs/aeg-core": "^0.24.1",
15
+ "@attalabs/aeg-forge-state": "^0.24.1",
16
16
  "@atta/cms": "workspace:*",
17
17
  "@atta/instrumentation": "workspace:*",
18
18
  "@atta/ui": "workspace:*",
@@ -1,141 +0,0 @@
1
- ---
2
- sidebar_title: Brief Author → Developer
3
- title: Brief Author → Developer
4
- order: 2
5
- contract_id: brief-developer
6
- description: Carries a brief to the agent that executes it, so nothing the author knew is left implicit.
7
- status: active
8
- producer: brief-author
9
- consumer: developer
10
- carrier: pr-body
11
- summary: Ever handed someone a task and they missed something you thought was obvious?
12
- ---
13
- # Contract: Brief Author → Developer
14
-
15
- ## The short version
16
-
17
- This seam sits between the brief and the agent that executes it. It exists to close the gap where an author assumes something is obvious and an executor never sees it stated.
18
-
19
- **What crosses** — one brief, complete. The exact command that creates the isolated working copy and branch, to be run before anything else. The impact tier, which decides how much documentation and record-keeping the work owes. The projects it touches. The context: what the task is not, and the traps already found. What must exist and be merged before it can start. The bounded file surface it may touch. Pinned assertions about the current code, so a brief written yesterday cannot be executed against a surface that has moved. The documents it must update. The checklist it satisfies before opening a pull request. A test plan, each item marked as one an agent can run or one only a person can. The conditions that stop it. The constraints it may not weigh against convenience.
20
-
21
- **The hand-off is malformed when** — any of those is missing. A brief without stop conditions is not a terse brief; it is one whose executor will invent them. A file surface described as "wherever else turns out to need it" is not bounded. A documentation list assembled from memory rather than reading is not a list. It is equally malformed to skim rather than read it, to treat a stop condition as advice, to execute past the file surface because nothing blocked it, or to paraphrase a verification result instead of pasting what the command printed.
22
-
23
- **What it does not carry** — status, which is derived from branches and pull requests and never written; the planner's durable reasoning, which crossed the previous seam and lives on the issue; and any authority to amend the brief. The brief is frozen at dispatch; a change to it is an escalation, not an edit.
24
-
25
- **How it physically runs** — the carrier is the pull-request body, which holds the brief verbatim. That is the brief's permanent home: the executing agent reads it there, the reviewer reads it there to judge intent against outcome, and the close-out reads it there as evidence. It is never committed into the repository and never stored in the issue, which holds task identity only — a brief kept anywhere durable goes stale before the work starts.
26
-
27
-
28
- ---
29
-
30
- ## Reference
31
-
32
- **Status:** active
33
- **Seam:** the hand-off from the Brief Author (producer) to the Developer (consumer).
34
- **Single source of truth for this seam.** The two role docs do **not** redefine what crosses this boundary — they point here. `aeg-root/skills/brief-authoring/SKILL.md` (producer side) and `aeg-root/roles/developer.md` (consumer side) each reference this file; this file is where the field-by-field hand-off lives, once.
35
-
36
- ---
37
-
38
- ## Why this file exists
39
-
40
- A brief is the executable contract between intent and implementation. When the hand-off from Brief Author to Developer is described separately in each role doc, the descriptions drift: the Brief Author believes the Developer will infer certain things; the Developer misses the fields the Brief Author thought were obvious. This contract removes that drift structurally — there is exactly one description of what a brief must carry and what the Developer must do with each field.
41
-
42
- The failure mode this prevents: a Developer who starts work without reading the full brief, or who treats stop conditions as suggestions, or who improvises past a surface-map boundary because nothing explicitly blocked them. Every field below is present in every well-formed brief; its absence is a signal the brief is malformed, not that the field is optional.
43
-
44
- ---
45
-
46
- ## The hand-off carrier
47
-
48
- The **PR body** — which the Developer opens at the start of execution and which carries the full brief verbatim. The brief is not in the Issue (the Issue is task identity + Planner's rationale only). The PR body is the brief's permanent, durable home. The Developer reads the PR body as the brief; the Reviewer and Archivist read it as evidence of intent.
49
-
50
- ---
51
-
52
- ## The contract — field-by-field mapping
53
-
54
- Every field the Brief Author emits (left) has exactly one named obligation for the Developer (right). A brief missing any left-column field is malformed — the Brief Author refuses to dispatch it. A Developer who drops a right-column obligation is executing incorrectly.
55
-
56
- | Brief Author emits | Developer consumes at | What the consumption means |
57
- |---|---|---|
58
- | **Worktree step 0** (verbatim `git worktree add` command) | First action before any other command | The Developer must execute this exact command first. No exceptions. Never assume the right branch exists. Before executing it, the Developer independently re-verifies the branch-name suffix literal-matches the topology's `#` column — the same check the Brief Author already ran before writing the command. |
59
- | **Tier:** field | PR-open checklist + `vinaya/tier:*` label | The Developer sets the matching `vinaya/tier:*` label on the Issue at PR open. The field is binding; the label is the scannable projection. |
60
- | **Project:** field | PR description + `verify-docs` | The Developer confirms the project resolves against `.vinaya/projects.md`. |
61
- | **Context** including boundary + traps | Mental model before any code | The Developer reads the boundary ("what this task is NOT") to know what to refuse to build, and the traps to know what not to do. |
62
- | **Technical Dependencies** | Verify all depends-on are merged | The Developer confirms every named dependency is on `main` before starting. A depends-on not yet merged is a hard stop. |
63
- | **Technical Surface Map** | Bounds the diff | The Developer touches only files in the surface map. Files outside it are a stop-and-escalate. |
64
- | **Premise pins (`Premise:` block, mandatory when the surface map names a real code surface)** | Re-asserted before Step 0, via `verify-dispatch --premise <body-file>`; re-asserted again pre-PR via `verify-task` | A failed premise means the surface moved since the brief was authored — the Developer stops and re-digs rather than executing against a stale mental model. This is a stop condition, not a silent re-guess. `checkPremiseCoverage` (Brief Validation) fails a brief with a real code surface and zero premise coverage. |
65
- | **A fenced command with its executed output pasted beneath it (the only other form a behavioural fact about code may take, per the rule in `aeg-root/skills/brief-authoring/SKILL.md` §2)** | Re-run before the Part that depends on it; output pasted in that round's PR comment | The Developer re-runs the command and compares its own output against what the brief pasted. A mismatch is a brief defect, not a fact to transcribe — the Developer stops, `severity: strategy`, and never writes the brief's sentence into doctrine or code. |
66
- | **Documentation-update list** | Self-check before opening PR + Reviewer doc check | The Developer updates every doc named in the list before claiming done. The list is a DoD obligation, not a recommendation — a named doc not updated is a BLOCKER at review. `verify-docs --pr` gates structural presence; the Reviewer gates content correctness. |
67
- | **Task Done checklist** | Self-check before opening PR | The Developer runs every item before opening the PR. An unchecked item means the PR is not ready. |
68
- | **Test Plan** tagged `[agent]` / `[principal]` | Runs `[agent]` items; leaves `[principal]` for Principal | The Developer runs every `[agent]` item and posts evidence. Does not tick `[principal]` boxes. |
69
- | **Stop conditions** | Halt triggers | The Developer stops and posts a blocker comment on the Issue when any condition is met. Never improvises past a stop condition. |
70
- | **Constraints** | Hard rules during execution | The Developer treats these as absolute — not "guidelines." A violated constraint is a PR that must not merge. |
71
-
72
- **Reading the table:** left is the producer obligation (Brief Author enforces it by refusing to dispatch a malformed brief), right is the consumer obligation (Developer role doc and executor protocol enforce it). The two role docs must not contradict this table.
73
-
74
- ---
75
-
76
- ## Producer obligations (the Brief Author)
77
-
78
- - Every field in the left column above must be present. A brief missing any of them is malformed — the Brief Author refuses to dispatch it.
79
- - The brief is frozen at dispatch; amendments go through escalation (`severity:execution` or `severity:strategy` depending on what changed).
80
- - The worktree step 0 command must be exact — branch name, base ref (`origin/main`), and destination path must all be present. The branch name's suffix must literal-match the task's row in the tranche topology file's `#` column — character for character, no added prefix, no case change, no truncation.
81
- - Stop conditions must be explicit, not inferred. Every known failure mode for this task belongs in the brief's stop conditions — the Developer will not invent stop conditions that aren't stated.
82
- - The surface map must be bounded and named. "Wherever else turns out to need it" is not a surface map.
83
- - **The documentation-update list must be populated from reading, not memory.** The Brief Author's Dig must identify and read any relevant specs/skills/docs before drafting it. The list for Tier 1+ must be non-empty unless the surface map genuinely touches no documented surface (state "No doc updates required" explicitly in that case). A list populated from the Planner's rationale alone without the Brief Author's own reading is malformed.
84
- - **A brief with a real code surface must carry a `Premise:` block pinning at least one checkable fact inside that surface.** A Tier 0 brief with zero code/runtime surface has nothing to pin.
85
-
86
- ## Task-status coherence precondition — hard STOP before authoring or executing any task
87
-
88
- > **SUPERSEDED (2026-07-13).** This precondition (the per-task archival / row-adjacency gate) is no longer a hard-STOP for the Brief Author or the Developer — automated post-merge provenance posting made the drift signal it protected moot. The section below is preserved as historical record — do NOT enforce it.
89
-
90
- ~~The Brief Author MUST verify this precondition before authoring any task brief. The Developer MUST verify it before step 0. **If any predicate fails for any in-scope prior, STOP and report to the Principal what is owed — do NOT author, do NOT begin work, do NOT rationalize past it.**~~
91
-
92
- **The archival bar.** A prior task is "done" when ALL THREE predicates hold:
93
- 1. Its forge Issue is **closed**
94
- 2. Its PR is **merged to main**
95
- 3. Its **provenance block** comment is present on the merged PR (posted by the Archivist)
96
-
97
- "PR merged" alone is NOT the bar. A merged PR whose Issue is still open, or whose provenance block is absent, is an incomplete archival — the Archivist has not fully closed out.
98
-
99
- **Scope of "prior task" — verify all three predicates for each:**
100
- - **Mid-tranche task:** every earlier task in the same tranche that this task depends on (direct `depends-on` edges).
101
- - **First task of an vinaya/tranche:** the entire previous tranche of that product must be archived — all Issues closed, all PRs in main, all tasks with provenance blocks, tranche file in `aeg-root/tranches/completed/`.
102
- - **ALL tasks:** every cross-tranche dependency declared in the topology (e.g. a task in one project that depends on a task in another, from an earlier tranche) must also satisfy all three predicates.
103
-
104
- **Hard STOP language:** *"Prior task [Y] does not pass the coherence gate: Issue #N is [open/closed], PR #M is [merged/unmerged], provenance block is [present/absent]. The Archivist must fully close out task [Y] before this task can proceed. Here is what is owed: [list]."*
105
-
106
- **Accepted-backfill never bypasses this gate.** Deferring backfill of historical provenance on **already-closed tranches** is a permitted debt record; proceeding with a new task on an **unarchived active prior** is not. The accepted-gap clause is strictly limited to closed historical tranches; it cannot be cited to bypass the coherence precondition for tasks in an active tranche. An accepted historical backlog is a debt record, not a gate bypass. The coherence precondition applies to active prior tasks; it cannot be waived by citing accepted historical gaps.
107
-
108
- The Brief Author's enforcement is at Dig stage, item (c) (see `aeg-root/skills/brief-authoring/SKILL.md`). The Developer's enforcement is at entry gate items 3–5 (see `aeg-root/roles/developer.md`). The Brief Author gate fires one stage earlier than the Developer gate — catching the gap before a brief the Developer will immediately refuse is dispatched.
109
-
110
- ---
111
-
112
- ## Consumer obligations (the Developer)
113
-
114
- - **Honor the documentation-update list.** Every doc named in the list must be updated as part of the task deliverable — not post-merge cleanup, not a follow-up task. A named doc not updated is a BLOCKER at review. If the list names a doc you cannot find or access, stop and report — do not silently skip it.
115
- - **Row-existence precondition (hard STOP before step 0).** Before executing step 0, `git fetch origin main`, then confirm this task's row exists at all in its tranche topology file (`aeg-root/tranches/<name>.md`) — read from the freshly-fetched `origin/main`, never a stale local checkout or memory. This is distinct from and prior to the Issue-existence precondition below: a missing row means the plan PR that adds this task has not merged yet. STOP: *"Task <id> is not present in `aeg-root/tranches/<name>.md` on a freshly-fetched `origin/main` — the plan PR that adds it has not merged. Not dispatchable until it does."* This gate is enforced in `aeg-root/roles/developer.md` (entry gate, item 7).
116
- - **Issue-existence precondition (hard STOP before step 0).** Before executing step 0, locate this task in its tranche topology file (`aeg-root/tranches/<name>.md`) and confirm the Issue column carries a real GitHub Issue number — not `#TBD`, not blank. If it is `#TBD` or blank, the task has no forge Issue and is not dispatchable. STOP: *"Task <id> in tranche `<name>` has no Issue (#TBD) — it is not dispatchable. The Planner must cut the Issue before this task can start."* This gate is enforced in `aeg-root/roles/developer.md` (entry gate, item 3).
117
- - ~~**Prior-archival precondition (hard STOP before step 0).**~~ **SUPERSEDED (2026-07-13)** — no longer a Developer obligation. See the notice above the task-status coherence precondition section. Preserved as historical record: ~~Before executing step 0, apply the task-status coherence precondition above to every in-scope prior task. Verify all three predicates (Issue closed, PR in main, provenance block present) for each. If any predicate fails for any in-scope prior, STOP: report to the Principal exactly what is owed and do not begin work. If no prior task exists in scope (first task of a fresh tranche with no prior tranche on this product), this check passes trivially. This gate was enforced in `aeg-root/roles/developer.md` (entry gate, item 4) and the coherence signal it read is defined in `aeg-root/contracts/reviewer-archivist.md`.~~
118
- - **Branch-ID verification precondition (hard STOP before step 0).** Before executing step 0, read this task's row in the tranche topology file and confirm the Step 0 branch-name suffix literal-matches the `#` column — character for character, no added prefix, no case change, no truncation. If it doesn't, STOP: do not create the worktree/branch, report the mismatch to the Brief Author/Principal rather than silently using either name. This is the same check the Brief Author already ran before writing the command — the Developer re-runs it independently rather than trusting the brief was authored correctly. This gate is enforced in `aeg-root/roles/developer.md` (entry gate, item 6).
119
- - **Mechanized precondition check.** The three preceding preconditions (row-existence, Issue-existence, and the prior-tranche-archival check in `roles/developer.md` entry gate item 5) are all re-derivable in one run: `vinaya check dispatch-readiness`, run from the task branch. A `NOT READY` result names the exact failing precondition and is the same STOP described above. **Known gap:** the shipped check's prior-tranche-archival predicate always reports empty — confirm item 5 yourself rather than trusting its pass. (The prior-archival/row-adjacency precondition previously listed here was removed from this composed check.) **On this repo's toolchain**, the unabridged derivation (including the real prior-tranche-archival predicate) is `bun packages/aeg-core/bin/verify-dispatch.ts <tranche> <n>`.
120
- - **Premise re-check (hard STOP before step 0).** If the brief carries a `Premise:` block, re-assert it before step 0 by confirming its stated facts still hold against the live forge/codebase. A failed premise means the surface moved since authoring — STOP and re-dig, do not proceed on a stale mental model. **On this repo's toolchain**, `bun packages/aeg-core/bin/verify-dispatch.ts <tranche> <n> --premise <body-file>` (the body-file being the dispatched brief text) automates that re-assertion.
121
- - Read the full brief before opening the worktree. Not a skim — every section.
122
- - Execute step 0 first, always. Never branch from `HEAD` of the current local checkout.
123
- - Verify all dependencies are merged before the first line of code.
124
- - Stay within the surface map. Files outside it are a stop-and-escalate, not a judgment call.
125
- - Run every `[agent]` Test Plan item and post the actual command output as evidence. Do not paraphrase verification results.
126
- - Stop on any stop condition — post a blocker comment, do not improvise.
127
- - Append one row to the tranche's token ledger at turn-end (before opening PR, and again on each re-push after `CHANGES_REQUESTED`).
128
-
129
- ---
130
-
131
- ## Changing this contract
132
-
133
- A contract changes **as a unit**. You may not change what the Brief Author emits without, in the same change, updating what the Developer consumes — because the property that makes the seam sound is that the producer's output side is *identical* to the consumer's input side. Concretely:
134
-
135
- - A change to this file is a **Tier 3** change: it alters a cross-role contract, so the reasoning belongs in the pull request that makes it, where the reviewer and the close-out both read it.
136
- - The same PR that edits this contract must verify both `aeg-root/skills/brief-authoring/SKILL.md` and `aeg-root/roles/developer.md` still point here and still match the table.
137
- - Never edit one side's role doc to add/drop a hand-off field directly. Add/drop it **here**; the role docs inherit it by reference.
138
-
139
- ---
140
-
141
- *This contract is the seam. The Brief Author fills the left column; the Developer drains the right. One source of truth, changed as a unit.*
@@ -1,130 +0,0 @@
1
- ---
2
- sidebar_title: Planner → Brief Author
3
- title: Planner → Brief Author
4
- order: 1
5
- contract_id: planner-brief
6
- description: Carries a tranche’s plan down to a single task’s brief, so a task keeps the reasoning that shaped it.
7
- status: active
8
- producer: planner
9
- consumer: brief-author
10
- carrier: issue-body
11
- summary: Ever had a plan's key details get lost the moment someone else picked it up?
12
- ---
13
- # Contract: Planner → Brief Author
14
-
15
- ## The short version
16
-
17
- This seam sits between planning a tranche and writing one task's brief. It exists because a role boundary is where work is lost: the planner does a deep technical pass, and without a contract its conclusions quietly fail to arrive.
18
-
19
- **What crosses** — the planner's rationale for one task, written into that task's issue: what the task is and deliberately is not; why it is one task rather than three; every project and shared-package consumer in its blast radius; why each dependency and conflict edge exists; the traps the dig already found; the class of agent the work needs; when the executing agent must stop rather than improvise; and the documents this work will make incoherent. Each has exactly one named home in the brief that consumes it, so a conclusion cannot arrive without a place to land.
20
-
21
- **The hand-off is malformed when** — a rationale is missing any of those parts, in which case the planner does not emit it; or when a brief drops one on the floor, in which case the brief is wrong rather than merely thin. It is malformed too when the rationale carries detail that cannot survive the wait — exact signatures, precise file lists — which goes stale between planning and dispatch; re-deriving that fresh is the brief author's half. And when the brief author's own dig contradicts the rationale, that is escalated back, never silently overridden.
22
-
23
- **What it does not carry** — the brief itself, which is written later and lives elsewhere; any statement of status, which is derived from the forge and never written down; scheduling or estimates, which belong to whatever tool plans the roadmap; and the freshly pinned facts a brief asserts about current code, which belong entirely to the next seam.
24
-
25
- **How it physically runs** — the carrier is the task's issue body. The planner writes the rationale there in a fixed grammar, readable by a person and checkable by a machine alike; an issue whose body does not carry every part is refused at creation, and the same check re-runs against issues already open. The brief author reads it there and writes the brief, which lands in the pull-request body at dispatch. The issue holds the reasoning; the pull request holds the instruction.
26
-
27
-
28
- ---
29
-
30
- ## Reference
31
-
32
- **Status:** active
33
- **Seam:** the hand-off from the Planner (producer) to the Brief Author (consumer).
34
- **Single source of truth for this seam.** The two role docs do **not** redefine what crosses this boundary — they point here. `aeg-root/roles/planner.md` (producer side) and `aeg-root/skills/brief-authoring/SKILL.md` (consumer side) each reference this file; this file is where the field-by-field hand-off lives, once.
35
-
36
- ---
37
-
38
- ## Why this file exists
39
-
40
- A role boundary is where work is lost. The Planner does a deep technical pass and produces durable conclusions; the Brief Author must consume *every one* of them or the conclusion is dropped and the executing agent walks into a trap the planner already saw. When the hand-off is described separately in each role doc, the two descriptions drift (they already did once — the brief side was missing "Sizing" and "Dependency rationale" that the planner side required). A **contract** removes the drift structurally: there is exactly one description of the seam, and both roles are bound to it.
41
-
42
- This is the first of AEG's role-seam contracts. Others (`brief-developer`, `developer-reviewer`, …) follow the same shape as each seam is modeled. A contract is a Class 1 artifact and changes **as a unit** — see "Changing this contract" below.
43
-
44
- ---
45
-
46
- ## The hand-off carrier
47
-
48
- The Planner's output unit is the **task**, which exists as a forge Issue (identity + metadata + Planner's rationale) and a row in the tranche topology file (Issue link + edges only). The thing that crosses this seam is the **Planner's rationale** block, which the Planner writes into the **Issue body**. The Brief Author reads the rationale from the Issue — the forge artifact — and turns it into the executable brief that lands in the PR body. The tranche file row is a topology pointer (the Issue number); the Issue is the definition.
49
-
50
- The Planner persists **durable conclusions** (which do not decay). The Brief Author adds **perishable detail** (current signatures, exact files, final model pick) at dispatch. Neither re-does the other's half; the rationale is the carrier between them, and the Issue is its home.
51
-
52
- ---
53
-
54
- ## The contract — field-by-field mapping
55
-
56
- Every field the Planner emits in the rationale (left) has exactly one named home in the brief (right). The Planner MUST emit every left-column field; the Brief Author MUST consume every one into the named brief section. A rationale missing a field is malformed (Planner refuses). A brief that drops a field on the floor is malformed (Brief Author error).
57
-
58
- | Planner emits (rationale field) | Brief Author consumes it in (brief section) | What the consumption means |
59
- |---|---|---|
60
- | **Boundary** (what this task is / is not) | Context + Technical Surface Map | The brief's scope and out-of-surface set are the planner's boundary made concrete against current code. |
61
- | **Sizing** (passed the four "too big?" tests) | Re-confirmation only | The brief assumes the task is one PR. If the Brief Author's own dig finds it no longer fits (code moved), that is **stop-and-escalate**, not a silent re-split. |
62
- | **Project(s) + blast radius** (every project/consumer touched) | `Project:` field + blast-radius re-verification in the Done checklist | The brief carries the identical `Project(s)`; the Done checklist re-verifies every blast-radius consumer the planner named. |
63
- | **Dependency rationale** (why each depends-on / conflicts-with edge) | Technical Dependencies | The brief turns the *why* of each edge into the concrete "what must already exist" preconditions (exports, migrations, capabilities, merged dependencies). |
64
- | **Traps to avoid** (concrete pitfalls the dig surfaced) | Context + Constraints | The trap becomes an explicit "do NOT do X; do Y instead" the executing agent cannot miss. Highest-value field — never drop it. |
65
- | **Suggested agent-class** (high/mid/fast + one-line reason) | `For:` + `Reason:` header | The Brief Author confirms or deviates (with stated reason) and makes the **final** model pick. Class is the planner's; pick is the brief's. |
66
- | **Stop-and-escalate** (when the agent must stop, not improvise) | Stop conditions | The planner's stop conditions are copied into the brief's stop-condition list verbatim in substance. |
67
- | **Docs to keep coherent** (which specs/skills/docs this task will make incoherent) | the documentation-update list | The Brief Author turns the Planner's named list into the explicit doc-update items. Conditional: if the Planner stated "No docs touched," the list is "No doc updates required (Tier 0)." If the Planner named docs, they are all in the list. Presence-**and-correctness** of the list is the Planner's mechanical obligation, not naming docs from memory: the Planner names intended surfaces and the Brief Author derives the floor at brief-authoring time by matching those surfaces against `.vinaya/doc-owners` (`deriveSection7`), then supplements from the read obligation. Any override of the derived floor (added doc, or a derived pointer marked out of scope) must carry a one-line reason in the brief — silent overrides are a regression. |
68
-
69
- **Reading the table:** left is the producer obligation (Planner role doc enforces it), right is the consumer obligation (brief-authoring skill enforces it). The two role docs must not contradict this table; if either needs to change what it emits or consumes, it changes *here*, and both sides update together.
70
-
71
- **Premise pinning is deliberately NOT a field in this table.** `verify-dispatch`/`verify-task`'s `Premise:` block is file-content-level, perishable detail — current signatures, current constants — squarely inside the Brief Author's half of the division of labor this contract already describes, not a durable conclusion the Planner should seed as a rationale field. It is governed entirely by the Brief Author → Developer seam (`contracts/brief-developer.md`), not this one.
72
-
73
- ---
74
-
75
- ## Rationale grammar
76
-
77
- The eight left-column fields above are the rationale's **content**; this section defines its **format** — how a field must be written in the Issue body for it to be machine-detectable. Before this grammar existed the rationale was prose with no defined format; a check cannot parse what has no format.
78
-
79
- Two serializations are accepted, case-insensitive, matched by field name (or an established synonym — e.g. `Depends-on` for **Dependency rationale**):
80
-
81
- - **Bold-inline:** `**<Field>** — <content>` (e.g. `**Boundary** — …`)
82
- - **Heading:** `### <Field>` followed by the content on subsequent lines (e.g. `### Traps to avoid`)
83
-
84
- A ready-to-fill skeleton of the full eight-field rationale lives at `aeg-root/templates/issue-rationale-template.md` — copy it rather than reconstructing the shape from this section's prose; this section remains the grammar's definition.
85
-
86
- **`Dependency rationale` carries one exception to the two-serialization tolerance above: it must be written `**Dependency rationale** — <content>` exactly** — bold-inline only, with the closing `**` immediately after the label, no colon inside the bold (`**Dependency rationale:**` is rejected) and no heading form. This field alone has a downstream consumer beyond the creation gate: `amendRationaleDeps`, the only sanctioned way to edit `Depends-on`/`Conflicts-with` after creation (this repo's implementation lives in `@attalabs/aeg-forge-state`), locates the section by the exact anchor `SECTION_HEADER` (same package) and refuses any other form. `checkIssueRationale` imports that same constant rather than a second regex, so a body it accepts is always rewritable by `amend-deps` — the two consumers share one grammar for this field. Found live 2026-08-05 on a real task Issue that used the colon form for all eight fields: it passed creation but could not be amended.
87
-
88
- A task Issue's body must carry all eight fields in one of these two forms. **Canonical implementation:** `checkIssueRationale`/`isTaskIssueLabelSet`, exported from `@attalabs/aeg-core` — the single grammar/parser, consumed at two enforcement points per `aeg-root/enforcement.md`'s ring model:
89
-
90
- - **Ring 0 (creation gate):** `vinaya issue create`/`vinaya issue edit` refuses to create or edit a task Issue (any Issue labeled `vinaya/tranche:<slug>`) whose body fails `checkIssueRationale`. **It also refuses on three content checks, which grade what the fields *say* rather than that they exist:**
91
- - `checkBlastRadiusScope` — if **Boundary** or **Project(s) + blast radius** names a path under a collision domain that none of the declared projects owns (ownership resolves against `.vinaya/projects.md`), the Issue must declare a second **registered** project or carry a `blast-radius-ack: <why one lens is enough>` line. `Project(s)` drives the review fan-out, so an under-declared blast radius under-governs the change. **Registered is the operative word:** a name with no row in `.vinaya/projects.md` buys no review lens, so it cannot buy the bypass either — the check filters declared names against the registry before counting them. The domain list itself is live-derived (every `packages/*` workspace member — `package.json`’s `workspaces`, or `pnpm-workspace.yaml`’s `packages:` list on a pnpm repo) plus a built-in cross-cutting default set (lockfile, monorepo config, CI, git hooks), with `vinaya.config.json`'s `blastRadius.extraDomains` adding anything beyond those — see `blast-radius-domains.ts`. The legacy static `.aeg/packages` file is retired; it is no longer read. Dormant only when none of those sources yields any domain at all, which a real repo essentially never hits.
92
- - `checkNoBriefContent` — the body must carry no `## References`, `Technical surface map`, `Premise`, `Step 0`, or `Test Plan` section. Those are Brief-Author artifacts; an Issue is not a brief's home (it would go stale before work starts).
93
- - `checkRationaleNamesDocs` — **Docs to keep coherent** and/or **Traps to avoid** must name at least one concrete doc path (`aeg-root/…`, `.claude/skills/…`, `.claude/rules/…`, `apps/<x>/CLAUDE.md`, `apps/<x>/specs/…`, a repo-level `*.md`). A genuinely doc-less surface uses the explicit `no-doc-surface` sentinel — the same shape as `Test Plan: unit-tests-only`. This is the only read-obligation signal a forge write leaves: the skill-check hook fires on file edits, and cutting an Issue edits no file.
94
-
95
- A fourth check, `checkConflictCompleteness`, **warns and never blocks**: two open task Issues naming the same collision domain with no mutual `Conflicts-with` edge. Non-blocking because an Issue declares no precise file surface, so the overlap is a hint, not a fact.
96
- - **Ring 1/2 (continuous oracle):** `vinaya check coherence`'s **R1** check re-runs the same function against the live stock of open task Issues, catching bodies edited by ungated writers or predating the gate. Pre-grammar Issues are grandfathered by explicit Issue number (`R1_GRANDFATHERED_ISSUES`, `@attalabs/aeg-core`) — visible as `info`, never blocking.
97
-
98
- R1 checks **presence/structure only**; whether the content is correct (sizing actually right, traps actually real) stays the Reviewer's judgment, never CI's.
99
-
100
- ---
101
-
102
- ## Producer obligations (the Planner)
103
-
104
- - **Cut a real forge Issue for every task before dispatch.** Before the Brief Author can author a brief, the Planner must have replaced any `#TBD` in the topology table's Issue column with a real GitHub Issue number. A `#TBD` entry means the task has no forge Issue — it is neither briefable nor executable regardless of its derived status. The Brief Author hard-STOPs on `#TBD` during Dig; the Developer hard-STOPs at entry gate item 3. Cutting the Issue makes the task forge-addressable and dispatchable; it is a Planner-only act.
105
- - Emit a rationale block per task containing **all eight left-column fields**. (Enforced in `planner.md` — a task missing its rationale is refused.) The eighth field, **Docs to keep coherent**, must name every spec/skill/doc this task will make incoherent, or state "No docs touched" explicitly. Omitting it forces the Brief Author to populate the documentation-update list from memory — the exact failure the read obligation exists to close.
106
- - The rationale holds durable conclusions only — no perishable line-level detail (that's the Brief Author's half).
107
- - `Project(s)` must include every shared-package consumer in the blast radius (the blast-radius rule in `planner.md`).
108
- - **Read relevant docs before emitting the "Docs to keep coherent" field.** The read obligation requires the Planner to have identified and read the relevant specs/skills/docs before planning. The "Docs to keep coherent" field is only trustworthy if it was derived from reading, not from memory.
109
-
110
- ## Consumer obligations (the Brief Author)
111
-
112
- - Read the rationale first; **start from it, never from a blank page**. (Enforced in `brief-authoring`.)
113
- - Consume **every** right-column mapping — no field dropped.
114
- - Add the perishable detail the planner deliberately left out (current signatures, exact file list, final model pick).
115
- - **Read obligation:** During the Dig, identify and read any specs/skills/docs relevant to this task's code surface. Then (a) surface in Context what the Developer must know from those docs, and (b) populate the documentation-update list from this reading — the Planner's "Docs to keep coherent" field is the starting point, but the Brief Author's own reading may surface additional docs the Planner missed.
116
- - If the Brief Author's own dig **contradicts** the rationale (the boundary moved, sizing no longer holds), that is a `severity:strategy` escalation back toward the Planner — not a silent override.
117
-
118
- ---
119
-
120
- ## Changing this contract
121
-
122
- A contract changes **as a unit**. You may not change what the Planner emits without, in the same change, updating what the Brief Author consumes — because the property that makes the seam sound is that the producer's output side is *identical* to the consumer's input side. Concretely:
123
-
124
- - A change to this file is a **Tier 3** change: it alters a cross-role contract, so the reasoning belongs in the pull request that makes it, where the reviewer and the close-out both read it.
125
- - The same PR that edits this contract must verify both `planner.md` and `brief-authoring/SKILL.md` still point here and still match the table (they should need no field-level edits, since the fields live here — but their references must stay valid).
126
- - Never edit one side's role doc to add/drop a hand-off field directly. Add/drop it **here**; the role docs inherit it by reference.
127
-
128
- ---
129
-
130
- *This contract is the seam. The Planner fills the left column; the Brief Author drains the right. One source of truth, changed as a unit.*
@@ -1,114 +0,0 @@
1
- ---
2
- sidebar_title: Brief Author
3
- title: Brief Author
4
- order: 2
5
- role_id: brief-author
6
- description: Turns one planned task into one executable brief — the context, the boundary, and the definition of done a task needs before it starts.
7
- actor: agent
8
- performs:
9
- - author-briefs
10
- - pressure-test-ideas
11
- - review-specs-on-completed-prs
12
- - maintain-state-docs
13
- refuses_when: >
14
- The task has no forge issue yet; its dependencies have not merged or a
15
- conflicting sibling is still open; the planner's rationale is missing a
16
- field; the relevant specs and skills have not been read; or a brief has
17
- been dispatched and the session is on a coding-agent surface — that is
18
- the Developer role.
19
- summary: Ever had a task handed off missing the context the person who scoped it had?
20
- ---
21
- # Brief Author — Role Reference
22
-
23
- ## The short version
24
-
25
- You turn one planned task into one executable brief, just in time, and hand it over. You are the last role that can still prevent a bad task from starting.
26
-
27
- **You own** — the brief, and everything in it. You start from the planner's rationale rather than a blank page, and you carry every one of its conclusions into a named section: the boundary and the traps into context, the dependency reasoning into what must already be merged, the stop-and-escalate conditions into stop conditions, the named documents into the documentation-update list. To that you add what the planner deliberately left out because it decays — the current file surface, the real signatures, the exact first command, the pinned assertions about today's code, and the final choice of model. You also own the readable half of the record: the specs and state notes that describe what the work will make true.
28
-
29
- **You refuse** — to author a brief for a task with no issue, whose dependency has not merged, or whose conflicting sibling is still open. To write from memory instead of from the specs and skills for the surfaces in scope. To emit a brief missing a bounded file surface, stop conditions, a documentation-update list, or a test plan. To state a fact about code as prose — what it does, checks, refuses, reads, or returns — where a `Premise:` pin or a fenced command with its executed output pasted beneath it is the only form that fact may take. And to quietly resolve a contradiction: when your own reading of the code disagrees with the plan, that goes back as an escalation, because a boundary that moved is a planning decision, not a wording problem.
30
-
31
- **You never** write production code, execute the brief you wrote, dispatch it yourself, merge, write status anywhere, or amend a brief after dispatch — a frozen brief that turns out wrong is escalated and reissued, never edited underneath the agent already working from it.
32
-
33
- **How it physically runs** — you work in conversation, not in a repository: the brief is written, handed over, and lands in the pull-request body at dispatch. That is its only durable home; it is never committed and never stored in the issue, because a brief kept anywhere permanent goes stale before the work begins. The task's issue is where you read the plan from; the pull request is where your output lives. Nothing you write records status — the branch and the pull request are the status. At the end of a session you report your own token usage rather than writing it into a file.
34
-
35
-
36
- ---
37
-
38
- ## Reference
39
-
40
- **Audience:** an agent on a chat / planning surface, asked to turn one planned task into one brief.
41
-
42
- You are the Brief Author when a task already exists on the forge with a planner's rationale, and the Principal asks for it to be briefed. You are NOT the Planner (you do not decide what the tasks are, or their edges) and you are NOT the Developer (you do not execute what you wrote). Environment and input determine the role: a rationale in front of you and no code to write means you are here.
43
-
44
- > **The full authoring procedure — every required section, in order, with the canonical example — lives in the brief-authoring skill. Load it before writing.** This doc holds the role's gates and refusals; the skill holds the shape of the artifact.
45
-
46
- ---
47
-
48
- ## When you are the Brief Author
49
-
50
- - A planned task exists, with its rationale, and it has a real forge issue
51
- - The Principal has asked for a brief, or approved briefing the next task
52
- - You are not executing anything — if a brief has been dispatched to you on a coding-agent surface, you are the Developer
53
-
54
- ---
55
-
56
- ## Entry gate (self-locating) — refuse if it isn't your turn
57
-
58
- Item 1 governs every brief, whatever the branch: a real Issue is required either way, though its Planner-cuts-it clause applies only to a task dispatched via `task/<tranche>/<n>` — a standalone fix's Issue can be filed by anyone. Items 2 and 3 govern a further decision specific to that same branch pattern: whether the task's dependency graph is clear and its Planner's eight-field rationale complete. A standalone fix, briefed onto a `fix/<slug>` branch instead, has neither for them to check. Item 4's read obligation applies to every brief too. Items 2 and 3 simply do not apply — there is nothing standing in for them. See **the standalone-fix path**, named after item 4 below, for what a standalone fix does instead of the `tranche` route.
59
-
60
- 1. **The task has a real issue.** A task with no forge issue is not briefable. Cutting the issue is the Planner's act and cannot be delegated to you: *"Task <id> has no issue yet — it is backlog, not dispatchable. The Planner cuts it first."*
61
- 2. **Its dispatch gates are clear.** Every `depends-on` task's pull request is merged, and no `conflicts-with` sibling has an open one. If not, the task serializes behind it and briefing it now produces a brief that goes stale while it waits.
62
- 3. **The rationale is complete.** All eight planner fields present. A rationale missing one is malformed — send it back rather than inventing the missing half; the whole point of the seam is that you do not re-derive the planner's work cold.
63
- 4. **You have read the surfaces.** The specs, skills and docs for every surface this task touches, read now — not recalled. **First, render the mechanical skeleton:** `vinaya brief render <tranche> <n> --surfaces <glob,...>` (task 12) fills every section a program can derive — the header, Step 0, the dispatch-gate pre-flight line, §4's file list with consumer packages and a `sha256` premise pin per file, §7 from the doc-owners derivation, and every remaining section from the Issue's eight-field rationale — straight from the forge and the tree, refusing and naming the missing fact when a derived section cannot be derived. What is left is the judgment: the sections it could not derive, and confirming what it did derive still matches the current code. The documentation-update list §7 renders from the same mechanical derivation against the current `.vinaya/doc-owners` bindings the Planner runs during Dig (`roles/planner.md` explains it) — match the brief's real file surface globs against every binding's own glob (segment-wise overlap, not exact-string match) and the union of fired pointers, or the explicit zero-match line, is what the renderer already pastes in. Where the renderer isn't available, `bun packages/aeg-core/bin/verify-dispatch.ts <tranche> <n> --surfaces <glob1,glob2,...>` runs the §7 derivation alone and prints exactly that; failing that, do the glob-match by hand. A list written from memory is the exact failure the read obligation exists to close.
64
-
65
- **The standalone-fix path.** A plain forge Issue with no `task/<tranche>/<n>` row and no Planner rationale, briefed onto a `fix/<slug>` branch instead, is still a brief: `aeg-root/skills/brief-authoring/SKILL.md`'s `brief-shape` paragraph states the gate applies whatever the branch is, and the same check's non-task-branch path (**on this repo's toolchain**, `bun packages/aeg-core/bin/verify-brief.ts --body-file <brief.md>`) validates the same sections without requiring `Closes #N`. Item 4's own named command needs a `<tranche> <n>` pair a standalone fix doesn't have: match the brief's file surface against `.vinaya/doc-owners` by hand instead.
66
-
67
- ---
68
-
69
- ## What you own
70
-
71
- **The brief.** Every required section, in the order the skill defines: who it is for and why, the premise pins, the context with boundary and traps, the technical dependencies, the bounded file surface, the documentation-update list, the test plan tagged by who can run each item, the stop conditions, the constraints, the autonomy clause, and the deliverable. A brief missing any of them is malformed and you do not dispatch it. The documentation-update list in particular has a mechanical floor, and you are the role that computes it: at authoring time, run the entry gate's `--surfaces` command against the brief's final file list — or, for a standalone fix with no `<tranche> <n>` pair, the by-hand glob-match the standalone-fix path names instead — and carry every binding that turns up into the list, or mark it out of scope with a one-line reason, because silent overrides are a regression (`contracts/planner-brief.md`).
72
-
73
- **The perishable half of the hand-off.** The planner persists durable conclusions; you add what decays: current signatures, the exact file list, the literal first command, the pinned facts that let the executing agent detect that the surface moved since you wrote. This division is the substance of the Planner→Brief contract — read it before authoring, because it names field-by-field what you must consume.
74
-
75
- **The final model choice.** The planner suggests a class; you make the pick against current reality, and you state the reason on the brief.
76
-
77
- **The readable record.** The specs that describe what the work makes true. This is where a decision that still binds belongs — in the spec for the surface it governs, where a binding keeps it current.
78
-
79
- ---
80
-
81
- ## What you do NOT do
82
-
83
- - **Write production code.** The Developer does that.
84
- - **Execute your own brief.** Writing it and running it in one session collapses the check that the brief is complete enough for someone else.
85
- - **Dispatch autonomously.** Dispatch is the Principal's act.
86
- - **Merge, or write task status anywhere.** Status is derived from the forge.
87
- - **Amend a dispatched brief.** It is frozen at dispatch; a change goes through escalation and a reissue.
88
- - **Re-plan.** If your dig contradicts the rationale — the boundary moved, the sizing no longer holds — that is a `severity:strategy` escalation back toward planning, not a silent rewrite.
89
-
90
- ---
91
-
92
- ## Anti-patterns
93
-
94
- **Writing from memory instead of from the surfaces.** The single most common cause of a documentation-update list that misses the doc the change actually breaks.
95
-
96
- **A brief sentence asserting what code does instead of a `Premise:` pin or a fenced command with its output.** A brief sentence about code that the Developer transcribed into doctrine, and a reviewer then proved false against the code — the failure `aeg-root/skills/brief-authoring/SKILL.md`'s own anti-pattern names. Nothing verifies a prose claim before the Developer builds on it; a pin or a command's pasted output is checkable, a sentence is not.
97
-
98
- **A file surface that says "and wherever else turns out to need it."** That is not a bounded surface; it is permission to wander, and the Developer will take it.
99
-
100
- **Stop conditions inferred rather than stated.** The executing agent will not invent stop conditions you did not write. Every known failure mode for this task belongs in the list.
101
-
102
- **A test plan with no `[agent]` items on work that has runtime behaviour.** "Unit tests only" is a real answer, but only when the change genuinely has no runtime surface — it is a sentinel, not a shortcut.
103
-
104
- **Padding the brief with the planner's reasoning restated.** The rationale is on the issue; consume it into the named sections rather than quoting it back.
105
-
106
- ---
107
-
108
- ## Where you sit in the process
109
-
110
- Between planning and execution. The Planner produces the task and its rationale; you produce the brief; the Developer executes it in an isolated worktree and opens the pull request carrying your brief in its body; the Reviewer judges the result against it. Both seams you touch are governed by contracts — `contracts/planner-brief.md` on the way in, `contracts/brief-developer.md` on the way out — and those contracts, not this doc, are the single source of truth for what crosses each boundary.
111
-
112
- ## Turn-end: report your tokens, don't append them
113
-
114
- You do not append your own row to any ledger file — self-append was retired for every role. At the end of a brief-authoring session, report your tokens instead: `Tokens: <task-id>: brief — Brief Author — <model> — in/out/cost`, in the plan pull request if one exists, or in your report to the Principal otherwise. If your surface cannot read its own token count, report `—` for the numeric cells and the Principal fills them. Re-briefing reports again, never edits the prior report.