@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.
- package/README.md +26 -3
- package/aeg-root/contracts/architect-planner.md +5 -5
- package/aeg-root/contracts/developer-reviewer.md +10 -7
- package/aeg-root/contracts/planner-developer.md +142 -0
- package/aeg-root/contracts/reviewer-archivist.md +2 -2
- package/aeg-root/contracts/tranche-archivist-planner.md +12 -11
- package/aeg-root/enforcement.md +25 -11
- package/aeg-root/process.md +53 -75
- package/aeg-root/roles/archivist.md +3 -3
- package/aeg-root/roles/developer.md +30 -24
- package/aeg-root/roles/planner.md +100 -21
- package/aeg-root/roles/principal.md +14 -11
- package/aeg-root/roles/reviewer.md +33 -17
- package/aeg-root/roles/security.md +28 -13
- package/aeg-root/roles/tranche-archivist.md +2 -2
- package/aeg-root/skills/aeg/SKILL.md +5 -5
- package/aeg-root/skills/aeg-roles/SKILL.md +7 -7
- package/aeg-root/state-machine.md +36 -35
- package/aeg-root/task-model.md +3 -3
- package/aeg-root/templates/brief-template.md +22 -6
- package/aeg-root/templates/issue-rationale-template.md +35 -2
- package/aeg-root/templates/pr-report-template.md +5 -13
- package/aeg-root/tranche-model.md +21 -21
- package/dist/checks/bin/check-body-bare-digits.js +684 -142
- package/dist/checks/bin/check-branch-topology.js +741 -88
- package/dist/checks/bin/check-brief-shape.js +708 -83
- package/dist/checks/bin/check-changeset-coverage.js +1445 -149
- package/dist/checks/bin/check-closes-n.js +741 -88
- package/dist/checks/bin/check-coherence.js +808 -149
- package/dist/checks/bin/check-dead-branch-push.js +617 -81
- package/dist/checks/bin/check-dispatch-readiness.js +811 -152
- package/dist/checks/bin/check-doc-coverage-push.js +1445 -149
- package/dist/checks/bin/check-doc-coverage.js +1447 -151
- package/dist/checks/bin/check-doctrine-no-procedures.js +684 -142
- package/dist/checks/bin/check-doctrine-portability.js +1445 -149
- package/dist/checks/bin/check-evidence-fresh.js +684 -142
- package/dist/checks/bin/check-exec-bits.js +1445 -149
- package/dist/checks/bin/check-first-push-dispatch.js +808 -149
- package/dist/checks/bin/check-issue-assignment.js +741 -88
- package/dist/checks/bin/check-main-branch-refusal.js +618 -82
- package/dist/checks/bin/check-no-disk-state.js +617 -81
- package/dist/checks/bin/check-pr-premise-reassert.js +5401 -0
- package/dist/checks/bin/check-pr-report-density.js +617 -81
- package/dist/checks/bin/check-quoted-command.js +1443 -147
- package/dist/checks/bin/check-reader-resolvable-prose.js +1481 -153
- package/dist/checks/bin/check-registry-gates.js +659 -85
- package/dist/checks/bin/check-retired-vocabulary.js +1443 -147
- package/dist/checks/bin/check-review-gate.js +758 -145
- package/dist/checks/bin/check-single-plan-pr.js +617 -81
- package/dist/checks/bin/check-surface-scope.js +5722 -0
- package/dist/checks/bin/check-test-plan.js +617 -81
- package/dist/checks/bin/check-token-collection-wired.js +617 -81
- package/dist/checks/bin/check-token-report.js +629 -88
- package/dist/checks/bin/check-workspace-escape.js +1443 -147
- package/dist/index.js +8548 -4335
- package/package.json +1 -1
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/brief-render.ts +2 -2
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/main-branch-refusal.ts +26 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/BUILD_ID +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/build-manifest.json +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/prerender-manifest.json +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.html +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/api/coherence/route.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page_client-reference-manifest.js +1 -1
- 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
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0053k9k._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0112h-k._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0o771t1._.js +1 -1
- 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
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0puovz5._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1hs0dcu._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1wc4-ip._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_03x_w6q._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0gvm3og._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0lwxg63._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0wxycau._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1n0cnq-._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/node_modules_1vo08dj._.js +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_topbar_index_tsx_1h1gs1y._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/middleware-build-manifest.js +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/server/pages/500.html +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.json +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{3m1kgax7j2vgs.js → 0bn8c8v5q429o.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0doqwpd81sjzn.js → 0keji7wvbe1d1.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/1maoxbrl3pv5d.css +1 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1uogpj5w2n5ju.js → 3-6a3tinbdb-7.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0zebsmmk1bvnb.js → 3_9xytdmiv1xi.js} +4 -4
- package/studio-standalone/apps/vinaya-studio/web/package.json +2 -2
- package/aeg-root/contracts/brief-developer.md +0 -141
- package/aeg-root/contracts/planner-brief.md +0 -130
- package/aeg-root/roles/brief-author.md +0 -114
- package/aeg-root/skills/brief-authoring/SKILL.md +0 -509
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/3qc67qhcvbg0o.css +0 -1
- /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
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{QY2GhiI47-765D9DHGy1I → DMofV2-9FrHE7100GfrpI}/_buildManifest.js +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{QY2GhiI47-765D9DHGy1I → DMofV2-9FrHE7100GfrpI}/_clientMiddlewareManifest.js +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{QY2GhiI47-765D9DHGy1I → DMofV2-9FrHE7100GfrpI}/_ssgManifest.js +0 -0
package/aeg-root/process.md
CHANGED
|
@@ -5,30 +5,28 @@ sidebar_title: Process
|
|
|
5
5
|
|
|
6
6
|
This document describes how work flows through the AEG operational model — from the moment the Principal has an idea to the moment that work merges to `main` with all specs and skills updated.
|
|
7
7
|
|
|
8
|
-
It is the canonical "how do we actually work?" document. Every other PM doc (`state-machine.md`, `tranche-model.md`, role docs
|
|
8
|
+
It is the canonical "how do we actually work?" document. Every other PM doc (`state-machine.md`, `tranche-model.md`, role docs) describes a slice of this process. This document stitches them together into a single readable walkthrough.
|
|
9
9
|
|
|
10
|
-
If you are starting a new session and need to understand the workflow, read this first. Then the `aeg` skill's session-start forge queries for orientation, then the role doc that applies to you, then any project-specific specs.
|
|
10
|
+
If you are starting a new session and need to understand the workflow, read this first. Then the `aeg` skill's session-start forge queries for orientation, then the role doc that applies to you, then any project-specific specs. Coined vocabulary used below (Dispatch, Impact tier, Ratification, …) is defined in the glossary at aeg-root/glossary.md.
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
14
|
## Where tasks come from: the tranche
|
|
15
15
|
|
|
16
|
-
The
|
|
16
|
+
The phases below are the **per-task** flow. Tasks do not appear from nowhere — they are produced by the **Planner**'s plan act when a tranche is planned: the Planner turns an intent plus a slice of tickets into a set of **forge Issues** (one per task) plus a thin topology file declaring their `depends-on` / `conflicts-with` edges (`tranche-model.md`, `roles/planner.md`). Each Issue that enters the flow below is a task the Planner already shaped — its rationale and judgment sections already written onto the Issue at plan time.
|
|
17
17
|
|
|
18
18
|
**Status is never stored.** Throughout every phase, a task's status is *derived* from the forge — Issue open/assigned, branch existence, PR open, review decision, merge — never written to a label or a file. When a phase below says a task "becomes in-review," it means *a PR was opened*, not that anyone set a status field.
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
## The
|
|
22
|
+
## The phases
|
|
23
23
|
|
|
24
|
-
Every piece of work moves through some subset of these. Trivial work (Tier 0) skips most; complex work (Tier 3) hits all and may loop back from review.
|
|
24
|
+
Every piece of work moves through some subset of these. Trivial work (Tier 0) skips most; complex work (Tier 3) hits all and may loop back from review. Numbered 1–13 for historical continuity with every cross-reference below and across `aeg-root/**`, but **not thirteen distinct phases any more**: the former Phases 3–5 (brief authoring, brief validation, dispatch) collapsed into one Planner phase, still numbered 3, performed by one command (`vinaya task dispatch`) — see Phase 3 below for why the numbers 4 and 5 are retired rather than reused. Every phase from 6 onward keeps its original number unchanged, so no downstream cross-reference in the doctrine tree needed to move.
|
|
25
25
|
|
|
26
26
|
```
|
|
27
27
|
1. Idea origination
|
|
28
28
|
2. Pressure-testing (optional; high-stakes only)
|
|
29
|
-
3.
|
|
30
|
-
4. Brief validation
|
|
31
|
-
5. Dispatch
|
|
29
|
+
3. Dispatch (brief authoring + validation + dispatch, one Planner phase — 4 and 5 retired into this one)
|
|
32
30
|
6. Execution
|
|
33
31
|
7. Escalation (optional; only when Developer blocks)
|
|
34
32
|
8. Task Done verification
|
|
@@ -49,11 +47,11 @@ After merge, the **Archivist** runs close-out (`roles/archivist.md`). That's the
|
|
|
49
47
|
|
|
50
48
|
**Who:** Principal and Planner.
|
|
51
49
|
|
|
52
|
-
The Principal brings an idea. The
|
|
50
|
+
The Principal brings an idea. The Planner pressure-tests, pushes back, surfaces related decisions, checks whether it's already specced. The Planner's job here is **not** to immediately agree and plan — it's to:
|
|
53
51
|
- Read the relevant specs to confirm the idea isn't already settled
|
|
54
52
|
- Push back if it's wrong, premature, or duplicative
|
|
55
53
|
- Identify the impact tier (0 / 1 / 3) — this drives everything downstream
|
|
56
|
-
- Identify the Type 1 (irreversible — Principal ratifies) vs Type 2 (reversible —
|
|
54
|
+
- Identify the Type 1 (irreversible — Principal ratifies) vs Type 2 (reversible — Planner ratifies) profile
|
|
57
55
|
|
|
58
56
|
If already locked or specced, the conversation ends here. If genuinely new, it produces a shared understanding of what the work is, why now, its tier, and its decision profile — which the Planner then turns into Issues (the tranche).
|
|
59
57
|
|
|
@@ -65,76 +63,56 @@ If already locked or specced, the conversation ends here. If genuinely new, it p
|
|
|
65
63
|
|
|
66
64
|
## Phase 2: Pressure-testing (optional)
|
|
67
65
|
|
|
68
|
-
**When:** high-stakes only — architectural locks, project-direction shifts, decisions blocking weeks of downstream work, or when the Principal's instinct and the
|
|
66
|
+
**When:** high-stakes only — architectural locks, project-direction shifts, decisions blocking weeks of downstream work, or when the Principal's instinct and the Planner's read disagree. **Not** for tactical decisions, naming, or style. The Principal may waive it and ratify in-session (the pull request notes the skip, for audit honesty).
|
|
69
67
|
|
|
70
|
-
**Who:**
|
|
68
|
+
**Who:** Planner orchestrates; external AI reviewers (vendor-diverse — independently hosted, each from a provider other than the one drafting the brainstorming brief) participate via pasted briefs.
|
|
71
69
|
|
|
72
|
-
The
|
|
70
|
+
The Planner writes a brainstorming brief (idea, sketch, alternatives, what to pushback on), pairs it with `reviewer-prompt.md`, and pastes to each reviewer. The Planner synthesizes. Converge on a flaw → back to Phase 1. Validate → proceed. **Max two rounds** — if two don't converge, the issue is framing, not a third round.
|
|
73
71
|
|
|
74
72
|
This phase pressure-tests an *idea*; Phase 10 reviews *shipped code*. Different things.
|
|
75
73
|
|
|
76
|
-
**Exit:**
|
|
74
|
+
**Exit:** Planner and Principal agree the direction holds.
|
|
77
75
|
|
|
78
76
|
---
|
|
79
77
|
|
|
80
|
-
## Phase 3:
|
|
78
|
+
## Phase 3: Dispatch (brief authoring + validation + dispatch)
|
|
81
79
|
|
|
82
|
-
**Who:** Planner
|
|
80
|
+
**Who:** Planner, in its dispatch act (`roles/planner.md` § The dispatch act).
|
|
83
81
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
**Formerly three phases (brief authoring, brief validation, dispatch); now one.** The brief is no longer hand-authored just-in-time by a separate Brief Author role — its judgment content (the eight-field rationale, `## Objectives`, and the four judgment sections `## Surface`/`## Parts`/`## Test plan`/`## Stop conditions`) was already written onto the task Issue at plan time (Phase 1), and validated then, by the same ring-0 creation gate and R1 continuous check that grade every open task Issue (`roles/planner.md` § Rationale grammar). What used to be three sequential human/CI steps is now one mechanical render plus one gate check, both performed by a single command.
|
|
83
|
+
|
|
84
|
+
Before dispatching a task, the Planner checks four gates (`roles/planner.md` § The dispatch act):
|
|
85
|
+
1. **Issue exists** — a real forge Issue number, not `#TBD`, not blank.
|
|
86
|
+
2. **Dependencies merged** — every `depends-on` task's PR is on `main`.
|
|
87
|
+
3. **No open conflicting sibling** — no `conflicts-with` task has an open PR.
|
|
88
|
+
4. **Render complete** — the brief render can derive every mechanical section from the Issue and the tree with no gap.
|
|
89
|
+
|
|
90
|
+
`vinaya check dispatch-readiness`, run against the task, re-derives gates 1–3 mechanically in one command.
|
|
91
|
+
|
|
92
|
+
**Running the dispatch:** `vinaya task dispatch <tranche> <n> [--agent claude | codex | gemini]` performs the whole phase once the gates pass: it renders the brief (the same render `brief render` uses, from `aeg-root/templates/brief-template.md` and every derivable fact), posts it once, frozen, as the task Issue's own `aeg:brief:v1` comment, then — with `--agent` — starts the Developer through `dispatchRole`. Without `--agent` it prints the rendered brief and the manual dispatch instruction and exits `0`, so a human can paste it instead. The brief MUST include (all mechanically derived or refused on):
|
|
93
|
+
- Impact tier (0 / 1 / 3), rendered from the Issue's tier declaration
|
|
94
|
+
- Type 1 / Type 2 declaration if architectural decisions are expected, gated at dispatch (a PENDING Type 1 decision blocks dispatch)
|
|
87
95
|
- `principal_delegate:` if the work runs while the Principal is offline
|
|
88
96
|
- Spike flag (`spike: true`) if exploratory
|
|
89
|
-
- The mandatory worktree-first Step 0 (`git worktree add .worktrees/task/<tranche>/<n> -b task/<tranche>/<n> origin/main` — no exceptions)
|
|
90
|
-
- An explicit documentation-update list tied to the tier
|
|
97
|
+
- The mandatory worktree-first Step 0 (`git worktree add .worktrees/task/<tranche>/<n> -b task/<tranche>/<n> --no-track origin/main` — no exceptions), rendered from the task's forge-derived branch id
|
|
98
|
+
- An explicit documentation-update list tied to the tier, mechanically derived against `.vinaya/doc-owners`
|
|
91
99
|
- Optional `Ticket:` (reference-only provenance) and, in a multi-project repo, `Project:` (resolves against `projects.md`)
|
|
92
100
|
- Clear scope, stop conditions, Task Done checklist
|
|
93
101
|
- A deliverable section stating "done" means "passed Phase 11 verification," not "PR opened"
|
|
94
102
|
|
|
95
|
-
A brief
|
|
103
|
+
A brief with any `[NEEDS CLARIFICATION: …]` marker left in it is not dispatched — the Planner resolves the ambiguity on the Issue's rationale (or puts it to the Principal) and re-renders. A brief is self-contained and executable without further conversation.
|
|
96
104
|
|
|
97
|
-
**Where the brief lives:**
|
|
105
|
+
**Where the brief lives:** the task Issue's own `aeg:brief:v1` comment, posted once, frozen, before the Developer starts — never in the PR body, which carries only the Developer's report. It is **not** committed and **not** put in the Issue's own body — the Issue body (written by the Planner at plan time) holds task identity + metadata + the rationale + judgment sections; the brief is a rendered comment on it, not a field of it.
|
|
98
106
|
|
|
99
107
|
**Artifacts:** the brief (a markdown block, not a committed file). The task's Issue already exists from tranche planning.
|
|
100
108
|
|
|
101
|
-
Before dispatch, a fresh-context Reviewer runs **Brief review mode** (`roles/reviewer.md`) on the brief
|
|
102
|
-
|
|
103
|
-
**Exit:** the brief is well-formed, has passed Brief review mode, and is ready to dispatch.
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
## Phase 4: Brief validation
|
|
108
|
-
|
|
109
|
-
**Who:** Archivist gate (automated) + the Developer's own entry gate.
|
|
110
|
-
|
|
111
|
-
Before work begins, the brief is checked for well-formedness:
|
|
112
|
-
- `tier:` present and valid; brief structure follows the skill (scope, stop conditions, deliverable)
|
|
113
|
-
- `principal_delegate:` valid if declared
|
|
114
|
-
- `Project:` (if present) resolves against the registry
|
|
115
|
-
- No obvious contradiction with the ratified specs (string-match heuristic)
|
|
116
|
-
- The task's Issue carries only execution metadata — **no** planning fields (priority/estimates/points), which the required Issue template + a CI check reject
|
|
117
|
-
|
|
118
|
-
If it fails, it's not dispatchable until fixed. The Developer also re-checks well-formedness as its entry gate (`roles/developer.md`) — a malformed brief is refused, not guessed at. (Brief Validation is a real blocking gate — the `Brief Validation` step (9/9) of the `aeg-gate-suite` job; see `state-machine.md` for mechanically-enforced vs trusted.)
|
|
119
|
-
|
|
120
|
-
**Exit:** the brief is well-formed and dispatchable.
|
|
121
|
-
|
|
122
|
-
---
|
|
123
|
-
|
|
124
|
-
## Phase 5: Dispatch
|
|
125
|
-
|
|
126
|
-
**Who:** Principal (or delegated Brief Author within ratification-window scope), by hand or via an automation layer.
|
|
127
|
-
|
|
128
|
-
Dispatch starts the task. There are two equivalent routes:
|
|
129
|
-
|
|
130
|
-
- **Manual:** the Principal pastes the brief into the coding agent. The brief's worktree-first Step 0 makes the Developer create its own worktree (`.worktrees/task/<tranche>/<n>/`, branch `task/<tranche>/<n>`, from `origin/main`) as its first action.
|
|
131
|
-
- **Automated:** an automation layer creates the worktree, generates the agent's config, spawns the Developer in it, and streams progress. This is a convenience; the semantics are identical to manual.
|
|
109
|
+
Before dispatch, a fresh-context Reviewer runs **Brief review mode** (`roles/reviewer.md`) on the rendered brief — a separate, time-boxed pass from the post-dispatch code review, under five minutes, returning one line, `BRIEF: READY` or `BRIEF: NOT READY`, with findings limited to two classes: a contradiction between two of the brief's own sentences, or a design the brief specifies that the party it constrains can defeat or that fails on an input the brief never named. `BRIEF: NOT READY` returns the rationale to the Planner rather than letting the render reach dispatch.
|
|
132
110
|
|
|
133
|
-
|
|
111
|
+
Once dispatched: **before starting, the Developer independently re-checks the same dispatch gates against the forge** (`roles/developer.md` entry gate) — every `depends-on` task's PR merged, no `conflicts-with` sibling's PR open, the branch-name suffix literal-matching the forge-derived id. If a gate isn't satisfied, it does not start (the task serializes). Opening the branch *is* the `todo → in-flight` transition; nobody writes a status label.
|
|
134
112
|
|
|
135
113
|
The branch name `task/<tranche>/<n>` is the convention that links the task to its branch and PR, so any role can derive its live status with one forge query.
|
|
136
114
|
|
|
137
|
-
**Exit:** the Developer is working in its worktree.
|
|
115
|
+
**Exit:** the brief is rendered, has passed Brief review mode, is posted frozen on the Issue, and the Developer is working in its worktree.
|
|
138
116
|
|
|
139
117
|
---
|
|
140
118
|
|
|
@@ -158,15 +136,15 @@ The Developer cannot author its own briefs, expand scope without escalation, mod
|
|
|
158
136
|
|
|
159
137
|
The Developer escalates through the escalation mechanism — a manual escalation note, or, if dispatched by an automation layer, its request-input mechanism — tagged with a `severity` that routes it:
|
|
160
138
|
|
|
161
|
-
- `severity: execution` →
|
|
162
|
-
- `severity: strategy` →
|
|
139
|
+
- `severity: execution` → Planner. Most common: a deprecated dependency, an unanticipated flag, a "null or throw?" call.
|
|
140
|
+
- `severity: strategy` → Planner. Less common: the brief's approach has a structural problem; the work touches an undiscussed area.
|
|
163
141
|
- `severity: product` → Principal. Rare: user-visible behavior the brief didn't address; a Type 1 decision is required.
|
|
164
142
|
|
|
165
143
|
The task is marked `blocked` (an `aeg:blocked` label — the one status with no native forge fact) until a reply arrives. The responder (Planner or Principal) formulates a reply and the Developer resumes.
|
|
166
144
|
|
|
167
145
|
**Type 1 during execution:** if the question needs an irreversible decision and the Principal isn't available, the Issue/PR stays labeled `needs:principal-input`; the next window resolves it. The Developer may terminate and resume via a follow-up dispatch after the window.
|
|
168
146
|
|
|
169
|
-
**Brief amendment:** if the brief itself is wrong in a way that blocks all paths, the
|
|
147
|
+
**Brief amendment:** if the brief itself is wrong in a way that blocks all paths, the Planner issues an amendment (logged as a separate event, not a brief edit — briefs are frozen after dispatch) or kills the task.
|
|
170
148
|
|
|
171
149
|
**Exit:** the Developer is unblocked and resumes.
|
|
172
150
|
|
|
@@ -193,7 +171,7 @@ Before opening the PR, the Developer runs the tier-appropriate Task Done checkli
|
|
|
193
171
|
|
|
194
172
|
The Developer opens a PR with:
|
|
195
173
|
- Title in commitlint format (`Type: Subject`)
|
|
196
|
-
- **
|
|
174
|
+
- **No brief in the body at all** — its permanent home is the task Issue's frozen `aeg:brief:v1` comment (posted at Phase 3, before the Developer ever started), which is where the Reviewer and Archivist read it
|
|
197
175
|
- A `Tier:` declaration (`Tier: 0|1|3`) so verify-docs reads the correct tier
|
|
198
176
|
- `Closes #N` linking the task's Issue (so the merge auto-closes it)
|
|
199
177
|
- Body following the PR template (what shipped, validated mechanism, what's not in scope, next steps)
|
|
@@ -208,20 +186,20 @@ CI runs typecheck, lint, tests, `verify-docs` (the load-bearing doc gate — fai
|
|
|
208
186
|
|
|
209
187
|
## Phase 10: Review
|
|
210
188
|
|
|
211
|
-
Two stages: independent **agent passes** (fresh-context), then **human reviews** (Principal +
|
|
189
|
+
Two stages: independent **agent passes** (fresh-context), then **human reviews** (Principal + Planner). Agent passes run first and feed the human reviews — they do not replace them.
|
|
212
190
|
|
|
213
191
|
```
|
|
214
|
-
code-reviewer pass → security pass → Principal code review →
|
|
192
|
+
code-reviewer pass → security pass → Principal code review → Planner spec review → merge
|
|
215
193
|
```
|
|
216
194
|
|
|
217
195
|
### Stage A — Agent review passes
|
|
218
196
|
|
|
219
|
-
Each pass is a **separate fresh-context invocation** with no memory of writing the code (the independence rule). Manual: the Principal pastes the review prompt. Automated: the automation layer dispatches the `code-reviewer` and `security-reviewer` passes. The agent reads its role doc + the PR diff + **the brief
|
|
197
|
+
Each pass is a **separate fresh-context invocation** with no memory of writing the code (the independence rule). Manual: the Principal pastes the review prompt. Automated: the automation layer dispatches the `code-reviewer` and `security-reviewer` passes. The agent reads its role doc + the PR diff + **the brief, read from the task Issue's frozen `aeg:brief:v1` comment**, and emits a structured verdict. Review agents do not edit code, do not merge, and do not write status.
|
|
220
198
|
|
|
221
199
|
1. **Code-reviewer pass** — `roles/reviewer.md`. Brief conformance, scope violations, test honesty, code quality, doc coupling, lock awareness, multi-project reach. Emits `VERDICT: APPROVE | REQUEST CHANGES` (BLOCKER / MAJOR / MINOR).
|
|
222
200
|
2. **Security pass** — `roles/security.md`. Secret leakage, BYOK/crypto, auth/permissions, MCP/agent-tooling exposure, injection surfaces, dependency risk. Runs a config-security scan over the agent/MCP/hook config when that config is touched. Emits `VERDICT: PASS | FAIL` (CRITICAL / HIGH / MEDIUM / LOW).
|
|
223
201
|
|
|
224
|
-
A BLOCKER (code) or CRITICAL/HIGH (security) returns the PR to the Developer, who fixes on the **same branch**; the pass re-runs. (Pushing fixes returns the PR's review decision to open — the `changes-requested → in-review` transition, derived.) A verdict binds to the head it judged; a push
|
|
202
|
+
A BLOCKER (code) or CRITICAL/HIGH (security) returns the PR to the Developer, who fixes on the **same branch**; the pass re-runs. (Pushing fixes returns the PR's review decision to open — the `changes-requested → in-review` transition, derived.) A verdict binds to the head it judged and the objectives list it judged against; a push or an objectives edit — including a mid-PR scope change made through `vinaya issue objectives edit` — voids the verdict, and a body edit alone changes nothing the gate reads. A voided verdict is named as such: `vinaya review status` prints `push after verdict — re-review required` for the head case, `objectives moved — re-review required` for the objectives case, and merge waits on a fresh review round either way. An escalation (`--escalate authority | strategy | product`) is its own review outcome, never a finding — it routes to Planner (`strategy`) or Principal (`authority`/`product`).
|
|
225
203
|
|
|
226
204
|
**A fix commit adds no mechanism beyond what the finding names.** The finding bounds the fix: a flag, a gate, a window, a config knob or a second code path that the finding did not ask for is new design, arriving inside a round that exists to close a defect and reviewed by nobody as design. A finding that genuinely cannot be answered without new mechanism is not a fix at all — it is escalated (`--escalate strategy`) and waits, and the mechanism it needs enters the work the way every other design does: as a constraint amended into the next brief. This is the round-count rule's twin. Rounds multiply when each one both closes something and opens something; a round that only closes is a round the loop can converge out of.
|
|
227
205
|
|
|
@@ -229,7 +207,7 @@ A BLOCKER (code) or CRITICAL/HIGH (security) returns the PR to the Developer, wh
|
|
|
229
207
|
|
|
230
208
|
**Code review (Principal).** The Principal reviews the diff — does it match the brief, scope violations, honest tests, spot-check quality. The agent verdict is an input, not a substitute; the Principal can overrule either way.
|
|
231
209
|
|
|
232
|
-
**Spec review (
|
|
210
|
+
**Spec review (Planner).** Do the specs describe what was built? Is the pull request's stated reasoning honest about what changed? Coherence, not technical correctness (that's the Principal's code review).
|
|
233
211
|
|
|
234
212
|
If both pass (and agent verdicts are APPROVE and PASS, and surfaced findings have been shown to the Principal at the go) → merge. If issues are found → back to the Developer with specific feedback. The loop ends by finding identity, never by round count — per the Review Cycle specification, round two judges only the lines changed since the previously judged head, for every non-blocking severity: a finding outside that delta is surfaced for the Principal's go rather than driving the verdict. A BLOCKER, CRITICAL or HIGH outside the delta still drives the verdict on any round; only MAJOR, MINOR, MEDIUM and LOW outside the delta are surfaced for the Principal's go. After round two the Principal decides, and there is no round three unless the Principal orders it. The loop pauses when a resolved finding reappears, when two consecutive rounds resolve no prior finding, or when one finding stays open three consecutive rounds while others resolve — every trigger is measured from the finding id sets, never from anyone's narrative of progress, and round five is a backstop, not a trigger. On a pause the Principal applies the `vinaya/needs:principal-input` label and works the stall menu cheapest first: a different role in the seat, resume with the trigger overridden, reseed the developer, abandon — a ruling re-enters the work as a constraint amended into the brief.
|
|
235
213
|
|
|
@@ -243,7 +221,7 @@ If both pass (and agent verdicts are APPROVE and PASS, and surfaced findings hav
|
|
|
243
221
|
|
|
244
222
|
**Who:** the Developer-agent (for `[agent]` items) and the Principal (for `[principal]` items). Verification is a *phase*, not a new actor — see `roles/developer.md` § Verification.
|
|
245
223
|
|
|
246
|
-
A PR that has passed code review and security review still has not been run. The reviews read the diff; the static gates of Phase 8 prove the code compiles and types and tests; CI does not boot the app. Phase 11 boots it, executes the brief's **Test Plan** (a required brief field, `
|
|
224
|
+
A PR that has passed code review and security review still has not been run. The reviews read the diff; the static gates of Phase 8 prove the code compiles and types and tests; CI does not boot the app. Phase 11 boots it, executes the brief's **Test Plan** (a required brief field, rendered from the Issue's `## Test plan` section — see `roles/planner.md` § The Planner's rationale), and posts the results onto the PR. Doctrine: **CI green ≠ app boots ≠ feature works** — runtime verification is its own gate.
|
|
247
225
|
|
|
248
226
|
The test plan is split by who can structurally execute each item:
|
|
249
227
|
|
|
@@ -262,7 +240,7 @@ The test plan is split by who can structurally execute each item:
|
|
|
262
240
|
|
|
263
241
|
## Phase 12: Merge
|
|
264
242
|
|
|
265
|
-
**Who:** Principal (or
|
|
243
|
+
**Who:** Principal (or the Planner if explicit per-PR delegation was set in the brief's `principal_delegate:` field).
|
|
266
244
|
|
|
267
245
|
The Principal merges. Tier 3 work merges during a ratification window (`roles/principal.md`); Tier 0/1 anytime. The merge **auto-closes the linked Issue** (via `Closes #N`) — and the merge *is* the `merged` status; nobody writes a label. An automation layer may surface a completion notification.
|
|
268
246
|
|
|
@@ -284,7 +262,7 @@ When the last task of a tranche has merged, the Principal declares it done and d
|
|
|
284
262
|
|
|
285
263
|
2. **Write the retrospective** — append a new section to `aeg-project/lessons.md` with observations on what went well, what stalled, carry-forward lessons, decisions made, and unbuilt tasks. Assembled from merged PR summaries and topology — not invented.
|
|
286
264
|
|
|
287
|
-
3. **Archive the tranche** — set `Lifecycle: complete` as the first line after the
|
|
265
|
+
3. **Archive the tranche** — close the tranche's Milestone. That closed Milestone is the current signal to the Planner's readiness gate (`contracts/tranche-archivist-planner.md`) and to any reader that the tranche is no longer active. **Legacy exception:** for a tranche still carrying a pre-cutover topology file, also set `Lifecycle: complete` as the first line after the file's heading and move it from `aeg-root/tranches/` to `aeg-root/tranches/completed/` (one commit: `git mv`) — kept for tranches created before the forge-native cutover; a forge-native tranche carries no such file to move.
|
|
288
266
|
|
|
289
267
|
4. **Update state docs** — refresh `aeg-project/state.md` (last-updated date, current focus pointer, recently shipped section, clear any resolved pending-manual-ops). Active-work state is derived from the forge — no `now.md`.
|
|
290
268
|
|
|
@@ -312,7 +290,7 @@ The Principal eventually removes the worktree (`git worktree remove …`) — de
|
|
|
312
290
|
`spike: true` → reduced Task Done (typecheck + lint, with what was tried and learned recorded in the pull request). Spike code does not merge — it rebases away or converts to a full Tier 1+ task in a separate brief.
|
|
313
291
|
|
|
314
292
|
### Tier 0 work (trivial)
|
|
315
|
-
Skips Phase 2; short brief; minimal checklist; light Phase 10 (a code-reviewer pass is cheap insurance, but the security pass and
|
|
293
|
+
Skips Phase 2; short brief; minimal checklist; light Phase 10 (a code-reviewer pass is cheap insurance, but the security pass and Planner spec review can be skipped when there's no config/auth surface and no spec change). Declare `Tier: 0` in the PR body so verify-docs doesn't require doc updates.
|
|
316
294
|
|
|
317
295
|
### Multi-developer parallel work
|
|
318
296
|
Each Developer gets its own worktree, branched from `origin/main`. Parallel safety is the dispatch gates: a task does not start while a `conflicts-with` sibling's PR is open, or before a `depends-on`'s PR merges (`tranche-model.md` §8). Conflicts are declared at planning time as package-level collision domains — the coordination lives in the tranche's edges, not in ad-hoc scope-checking. When unsure two tasks collide, the Planner declares the conflict and serializes.
|
|
@@ -327,17 +305,17 @@ A rollback is its own task with its own brief. The decision to roll back is a Ty
|
|
|
327
305
|
|
|
328
306
|
## Anti-patterns
|
|
329
307
|
|
|
330
|
-
- **Going straight to
|
|
331
|
-
- **Dispatching
|
|
308
|
+
- **Going straight to dispatch without Phase 1** — a rationale written on top of an unexamined idea produces briefs that solve the wrong problem.
|
|
309
|
+
- **Dispatching a task whose gates aren't met, or forcing a render past a gap it flagged** — the Developer's own entry gate refuses it anyway; bypassing the gate manually just moves the failure one stage later.
|
|
332
310
|
- **Letting the Developer review its own work** — the Phase 10 agent passes are separate fresh-context invocations for a reason.
|
|
333
311
|
- **Writing status anywhere** — status is derived from the forge. Setting a label or editing the tranche file to record state recreates the racing status model the design eliminated.
|
|
334
|
-
- **
|
|
312
|
+
- **Hand-writing brief content into the Issue's own body** — the Issue body is task identity + metadata + the Planner's rationale + judgment sections only; the brief itself is a mechanically rendered comment on it, posted by `vinaya task dispatch`, never typed by hand into either the Issue or the PR body.
|
|
335
313
|
- **Developer scope creep** — "while I'm here…" is a new task and a new brief.
|
|
336
|
-
- **
|
|
314
|
+
- **Planner self-ratifying Type 1 decisions in solo sessions** — they queue as PENDING for a ratification window.
|
|
337
315
|
- **Skipping the Task Done checklist under deadline pressure** — it's the load-bearing discipline; skipping it is how the BYOK gap happened.
|
|
338
316
|
- **Treating "PR opened" as "done"** — done is "passed Phase 11 verification" (which requires Phase 10 review to have already passed).
|
|
339
317
|
- **Treating "review passed" as "ready to merge"** — review reads the diff; verification runs the booted app. CI green ≠ app boots ≠ feature works. An unticked Test Plan box is the merge gate even when the reviews are clean.
|
|
340
|
-
- **Inventing a Test Plan at verification time when the
|
|
318
|
+
- **Inventing a Test Plan at verification time when the Issue's rationale omitted one** — the Test Plan is written onto the Issue at plan time and rendered mechanically at dispatch; verification *executes* the plan, it does not author it. A missing Test Plan is a rationale defect, caught by the ring-0 creation gate or the render's own refusal, not something verification improvises around.
|
|
341
319
|
- **Mis-tagging a `[principal]` Test Plan item as `[agent]`** to make the agent half look complete — the asymmetry is structural (the agent surface lacks auth/keys/eyes); reclassifying loses the point of the split.
|
|
342
320
|
- **Building a dynamic conflict scanner** to catch what the Planner missed — declare conflicts conservatively and serialize instead (`tranche-model.md` §9).
|
|
343
321
|
|
|
@@ -345,7 +323,7 @@ A rollback is its own task with its own brief. The decision to roll back is a Ty
|
|
|
345
323
|
|
|
346
324
|
## How this process maps to file artifacts
|
|
347
325
|
|
|
348
|
-
For which files get mutated in which phase by which actor, see `state-machine.md` (the artifact + mutation matrix). For the roles, see `roles/principal.md`, `roles/planner.md`, `
|
|
326
|
+
For which files get mutated in which phase by which actor, see `state-machine.md` (the artifact + mutation matrix). For the roles, see `roles/principal.md`, `roles/planner.md`, `developer.md`, `reviewer.md`, `security.md`, `archivist.md`. For the tranche/task model, see `tranche-model.md` and `roles/planner.md`. For dispatching a task, see `roles/planner.md` § The dispatch act.
|
|
349
327
|
|
|
350
328
|
---
|
|
351
329
|
|
|
@@ -100,7 +100,7 @@ Work through this checklist for the merged task. Confirm each against reality
|
|
|
100
100
|
|
|
101
101
|
At close-out you assemble one **provenance record** for the task and post it as a comment on the merged PR (the PR is a frozen truth domain once merged; the comment is append-only). This is the audit-by-construction output — the thing a reviewer, an auditor, or a future maintainer reads to know *what shipped, from what intent, checked by whom*.
|
|
102
102
|
|
|
103
|
-
**The cardinal constraint: you ASSEMBLE, you do not author.** Every field is **copied from a fact the merge already froze** — the brief (
|
|
103
|
+
**The cardinal constraint: you ASSEMBLE, you do not author.** Every field is **copied from a fact the merge already froze** — the brief (frozen on the task Issue's `aeg:brief:v1` comment), the PR's reviews, the forge's own merge metadata. You compute nothing new and you store no new state. The provenance block is a **projection of frozen facts**, exactly like derived status is a projection of forge state — which is why it does **not** violate the anti-regression rule against storing execution metadata: it lives on the merged PR, not in the tranche file or the Issue, and it is written once, never updated.
|
|
104
104
|
|
|
105
105
|
Fields (omit any whose source fact is genuinely absent; never invent one):
|
|
106
106
|
|
|
@@ -108,7 +108,7 @@ Fields (omit any whose source fact is genuinely absent; never invent one):
|
|
|
108
108
|
### AEG provenance — task <n> (tranche <name>)
|
|
109
109
|
- Issue: #N (closed by merge)
|
|
110
110
|
- Tier: 0|1|3
|
|
111
|
-
- Brief:
|
|
111
|
+
- Brief: frozen on the task Issue's `aeg:brief:v1` comment
|
|
112
112
|
- Project(s): <from the brief's Project: field, resolved via projects.md>
|
|
113
113
|
- Model/agent: <from the brief's `For:` line — AEG forbids commit-trailer attribution, so this is the source>
|
|
114
114
|
- Code review: APPROVE | REQUEST CHANGES→resolved (PR review by <reviewer>)
|
|
@@ -159,7 +159,7 @@ If required docs didn't move, or a required provenance source fact is absent, th
|
|
|
159
159
|
|
|
160
160
|
## Where you sit in the process
|
|
161
161
|
|
|
162
|
-
You are the last step of the flow (`process.md`) — the close-out that sits under **Phase 12 (Merge)**, not the review phase: code-reviewer pass → security pass → Principal code review →
|
|
162
|
+
You are the last step of the flow (`process.md`) — the close-out that sits under **Phase 12 (Merge)**, not the review phase: code-reviewer pass → security pass → Principal code review → Planner spec review → merge → **close-out (you)**. After you, the task is done, durable, and provenanced.
|
|
163
163
|
|
|
164
164
|
## Turn-end: record the ledger rows for every role that turned on this task
|
|
165
165
|
|
|
@@ -28,13 +28,13 @@ summary: Ever had someone review their own work?
|
|
|
28
28
|
|
|
29
29
|
You execute **one** brief, on **one** branch, and answer for it. You are the only role that writes code.
|
|
30
30
|
|
|
31
|
-
**You own** — the code, the tests, and the documentation the brief names; a clean typecheck, lint, test and production build; the worktree; and the pull request, carrying the report
|
|
31
|
+
**You own** — the code, the tests, and the documentation the brief names; a clean typecheck, lint, test and production build; the worktree; and the pull request, carrying the report, its impact tier, the issue it closes, and your own exact token figures. The brief itself lives elsewhere: dispatch tooling posts it once, frozen, as a comment on the task's own tracking issue, before you ever start — you never author or post it yourself.
|
|
32
32
|
|
|
33
33
|
**You refuse** — to start, when the input is not a well-formed brief, when a task you depend on has not merged, when a conflicting task is still open, when the task has no issue yet, when the previous tranche of a product you touch was never closed out, or when the branch name you were handed does not match the task; and to continue, when a pre-flight check fails, when the brief contradicts the code irreconcilably, when a test still fails after repeated genuine diagnosis, when you are about to touch a file outside the brief's surface, or when an action would be destructive and the brief never authorized it. Refusing is reporting what blocks you, not improvising past it.
|
|
34
34
|
|
|
35
35
|
**You never** author your own brief, write status anywhere, review or approve your own work, merge, settle a contested architectural question, skip a verification hook to get a commit through, or commit a new file whose only purpose is to hold a report.
|
|
36
36
|
|
|
37
|
-
**How it physically runs** — you work in a git worktree of your own, at `.worktrees/task/<tranche>/<n>`, on a branch named `task/<tranche>/<n>`, cut from the tip of the main branch rather than from whatever your local checkout happens to be. Creating it is the first thing you do, before reading a line of code. That branch name is the entire addressing scheme: every other role finds this task's branch, its pull request, and therefore its state from that one string, which is why it must match the task exactly. Commits are small and frequent — one per Part, pushed once.
|
|
37
|
+
**How it physically runs** — you work in a git worktree of your own, at `.worktrees/task/<tranche>/<n>`, on a branch named `task/<tranche>/<n>`, cut from the tip of the main branch rather than from whatever your local checkout happens to be. Creating it is the first thing you do, before reading a line of code. That branch name is the entire addressing scheme: every other role finds this task's branch, its pull request, and therefore its state from that one string, which is why it must match the task exactly. Commits are small and frequent — one per Part, pushed once. The brief itself was already posted, frozen, on the tracking issue before you started — its permanent home, and where the reviewer reads it — while the pull-request description carries the report: the impact tier and the issue the merge closes. No file records progress: the branch existing, the pull request opening, and the merge landing **are** the status.
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
---
|
|
@@ -45,6 +45,10 @@ You execute **one** brief, on **one** branch, and answer for it. You are the onl
|
|
|
45
45
|
|
|
46
46
|
You are the Developer when you are running in a coding-agent surface, a task brief has been dispatched to you (pasted in chat, or by an automation layer), and the brief tells you to execute specific work. You are executing — not planning, not strategizing, not authoring briefs.
|
|
47
47
|
|
|
48
|
+
<!-- AEG:CLAIM: apps/cli/src/lib/dispatch.ts contains:VINAYA_ROLE: role, -->
|
|
49
|
+
<!-- AEG:CLAIM: packages/aeg-core/src/log/envelope.ts contains:isRole(input.env.role) ? input.env.role : 'unattributed' -->
|
|
50
|
+
A turn started via `vinaya dispatch developer --agent <vendor>` carries its role and task in every `vinaya` call it makes; one started by hand in a terminal reads `unattributed` in the Vinaya Log, which is the truth about it.
|
|
51
|
+
|
|
48
52
|
> **Toolchain is per-repo.** This role names obligations (tests pass, typecheck passes, lint passes, production build passes), not specific commands. Each repo declares its own commands — the exact `typecheck` / `lint` / `test` / `build` invocations live in the repo's config (e.g. `package.json` scripts, a Makefile, the brief's verification section). Where this doc shows commands, they are **this repo's** instances (a Bun/JS toolchain) — substitute your repo's equivalents.
|
|
49
53
|
|
|
50
54
|
---
|
|
@@ -55,7 +59,7 @@ You are the Developer when you are running in a coding-agent surface, a task bri
|
|
|
55
59
|
- A task brief has been pasted, or dispatched by an automation layer
|
|
56
60
|
- The brief says to build, fix, refactor, document, or validate something specific
|
|
57
61
|
|
|
58
|
-
You are NOT the Developer if you are in a chat/planning surface talking with the Principal about strategy or planning. That's the Planner
|
|
62
|
+
You are NOT the Developer if you are in a chat/planning surface talking with the Principal about strategy or planning. That's the Planner role. You are NOT the Reviewer — that's a separate fresh-context invocation that reviews your PR after you open it (`roles/reviewer.md`, `roles/security.md`). Environment determines role.
|
|
59
63
|
|
|
60
64
|
---
|
|
61
65
|
|
|
@@ -63,11 +67,11 @@ You are NOT the Developer if you are in a chat/planning surface talking with the
|
|
|
63
67
|
|
|
64
68
|
Before writing any code, validate the following — and refuse if any fails:
|
|
65
69
|
|
|
66
|
-
1. **Is my input a well-formed brief?** It must carry tier, scope, stop conditions, and a deliverable. If you were handed a loose prompt instead → *"This isn't a brief — it's missing tier / scope / stop-conditions. Get one from the
|
|
70
|
+
1. **Is my input a well-formed brief?** It must carry tier, scope, stop conditions, and a deliverable. If you were handed a loose prompt instead → *"This isn't a brief — it's missing tier / scope / stop-conditions. Get one dispatched from the Planner; I don't infer scope from a prompt."* If a multi-project repo and `Project:` doesn't resolve against `.vinaya/projects.md` → *"Project 'x' isn't registered."*
|
|
67
71
|
2. **Are my dispatch gates satisfied?** Check the forge (not a status file — status is derived):
|
|
68
72
|
- Every `depends-on` task's **PR is merged**. If not → *"Task N depends on <dep>, whose PR isn't merged yet. Not starting — it serializes behind it."*
|
|
69
73
|
- No `conflicts-with` sibling has an **open PR** (or is otherwise in-flight). If one does → *"Task N conflicts with <sibling>, whose PR is open. Not starting until it merges."*
|
|
70
|
-
3. **Issue-existence precondition (hard STOP before step 0).** Before executing step 0, confirm via the forge (`vinaya/tranche:<slug>`-labeled Issue titled `[<slug>] <n> — …`, and its Milestone) — not `aeg-root/tranches/<name>.md` — that this task has a real GitHub Issue number, not `#TBD`, not blank. If no such Issue exists, 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."* Do not begin work. The Issue number is what makes the task forge-addressable and is required for `Closes #N` in the PR body. See `aeg-root/contracts/
|
|
74
|
+
3. **Issue-existence precondition (hard STOP before step 0).** Before executing step 0, confirm via the forge (`vinaya/tranche:<slug>`-labeled Issue titled `[<slug>] <n> — …`, and its Milestone) — not `aeg-root/tranches/<name>.md` — that this task has a real GitHub Issue number, not `#TBD`, not blank. If no such Issue exists, 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."* Do not begin work. The Issue number is what makes the task forge-addressable and is required for `Closes #N` in the PR body. See `aeg-root/contracts/planner-developer.md`.
|
|
71
75
|
4. ~~**Prior-archival precondition (hard STOP before step 0).**~~ **SUPERSEDED (2026-07-13) — no longer a live obligation.** The per-task archival / row-adjacency precondition this item once mechanized is removed as a hard-STOP: automated post-merge provenance posting made the drift signal this item existed to protect moot. Preserved below as historical record only — do NOT enforce this item:
|
|
72
76
|
|
|
73
77
|
~~Before executing step 0, query this tranche's most-recently-merged task PR:~~
|
|
@@ -81,13 +85,13 @@ Before writing any code, validate the following — and refuse if any fails:
|
|
|
81
85
|
| jq '.comments[].body | select(test("AEG.*provenance|provenance.*task"; "i"))'
|
|
82
86
|
```
|
|
83
87
|
~~If the result is empty, the per-task Archivist was skipped. STOP: *"Prior task PR #N in tranche `<name>` has no provenance block — the per-task Archivist must run before this task proceeds. Dispatch the per-task Archivist for #N first."* Do not begin work. If no prior merged task PR exists in the tranche (this is the first task), this check passes trivially. The contract governing this signal is `aeg-root/contracts/reviewer-archivist.md`; the full obligation is in `aeg-root/contracts/brief-developer.md`.~~
|
|
84
|
-
5. **Prior-tranche-archival precondition.** Before opening a PR against any product, confirm each product named in the brief's `Project:` field has its previous tranche archived. For each product, check whether a prior tranche for that product exists in `aeg-root/tranches/` but NOT in `aeg-root/tranches/completed
|
|
85
|
-
6. **Branch-ID verification (hard STOP before step 0).** Before executing step 0, confirm via the forge (`vinaya/tranche:<slug>`-labeled Issue titled `[<slug>] <n> — …`, and its Milestone) — not `aeg-root/tranches/<name>.md` — that the branch-name suffix in the Step 0 command you were just handed literal-matches this task's forge-derived id `<n>` — character for character: no added prefix, no case change, no truncation. If it doesn't: *"The Step 0 branch name `task/<tranche>/<X>` doesn't match this task's topology ID `<Y>` — STOP, do not create the worktree/branch; report the mismatch to the
|
|
88
|
+
5. **Prior-tranche-archival precondition.** Before opening a PR against any product, confirm each product named in the brief's `Project:` field has its previous tranche archived. For each product, check whether a prior tranche for that product has an open Milestone (forge-native) — or, for a tranche still carrying a pre-cutover topology file, exists in `aeg-root/tranches/` but NOT in `aeg-root/tranches/completed/` (legacy exception; a forge-native tranche carries no such file to check). If any such unarchived tranche exists and all its task PRs are merged, the Tranche Archivist has not run. STOP: *"Product `<X>`'s previous tranche `<name>` is complete but not archived — the Tranche Archivist must run before new work on this product. Dispatch it first."* If there is no prior tranche on a product, this gate passes trivially. The contract governing this gate is `aeg-root/contracts/tranche-archivist-planner.md`.
|
|
89
|
+
6. **Branch-ID verification (hard STOP before step 0).** Before executing step 0, confirm via the forge (`vinaya/tranche:<slug>`-labeled Issue titled `[<slug>] <n> — …`, and its Milestone) — not `aeg-root/tranches/<name>.md` — that the branch-name suffix in the Step 0 command you were just handed literal-matches this task's forge-derived id `<n>` — character for character: no added prefix, no case change, no truncation. If it doesn't: *"The Step 0 branch name `task/<tranche>/<X>` doesn't match this task's topology ID `<Y>` — STOP, do not create the worktree/branch; report the mismatch to the Planner/Principal rather than silently using either name."* Do not begin work.
|
|
86
90
|
7. **Row-existence precondition (hard STOP before step 0).** Before executing step 0, confirm via the forge (`vinaya/tranche:<slug>`-labeled Issue titled `[<slug>] <n> — …`, and its Milestone) — not `aeg-root/tranches/<name>.md` — that this task's row exists **at all**. This is distinct from and prior to item 3's `#TBD`/blank check: a missing row means the plan/Issue for this task has not merged/opened yet, and there is nothing to inspect — no Issue, no dependencies, no `Project(s)` value. If the row is absent: STOP: *"Task <id> is not present in tranche `<name>`'s forge-derived task list (no `vinaya/tranche:<name>`-labeled Issue with this task id yet) — the plan/Issue for this task hasn't merged/opened. Not dispatchable until it does."* Do not begin work.
|
|
87
91
|
|
|
88
92
|
**Mechanized version of items 3, 5, and 7.** Items 3, 5, and 7 above (Issue-existence, prior-tranche-archival, row-existence) are all re-derivable in one run: `vinaya check dispatch-readiness`, run from the task branch against a freshly-fetched `origin/main` and the live forge, before step 0. A `NOT READY` result names the exact failing predicate and is the same STOP each item above describes — read the printed blocker rather than re-deriving the fact by hand. **Known gap:** the shipped check's prior-tranche-archival predicate always reports empty (a narrower parity gap than the full derivation below) — do not treat its pass as covering item 5; confirm item 5 yourself. The prose above remains the *why* (what each precondition means, and the manual `gh`/`jq` fallback if the tool is ever unavailable); item 6 (branch-ID verification) is a static check against the brief's own Step 0 text, not a mechanized command, and stays manual. Item 4 is superseded and no longer part of this composed check. **This gate now also runs mechanically** (task 25) — the `first-push-dispatch` check, wired into every adopter's generated CI and managed `.git/hooks/pre-push`, invokes the same derivation on a task branch's first push, before its PR exists — but running it yourself before step 0 remains the cheaper, earlier catch: the hook fires only at push time, after you've already done the work. **On this repo's toolchain**, the underlying, unabridged derivation (including the real prior-tranche-archival predicate) is `bun packages/aeg-core/bin/verify-dispatch.ts <tranche> <n>` — prefer it here over the shipped check's narrower parity.
|
|
89
93
|
|
|
90
|
-
If the brief carries a `Premise:` block, also re-assert it before step 0: confirm by hand that the brief's stated facts still hold against the live forge/codebase (a stale premise means the surface moved since the brief was
|
|
94
|
+
If the brief carries a `Premise:` block, also re-assert it before step 0: confirm by hand that the brief's stated facts still hold against the live forge/codebase (a stale premise means the surface moved since the brief was rendered — STOP and re-dig; see `aeg-root/contracts/planner-developer.md`). **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.
|
|
91
95
|
|
|
92
96
|
Items 3, 5, and 7 read live forge state. Item 6 checks the brief's own Step 0 text against that same forge-derived id. You never write status anywhere — opening your branch and PR *is* the status.
|
|
93
97
|
|
|
@@ -103,9 +107,9 @@ Items 3, 5, and 7 read live forge state. Item 6 checks the brief's own Step 0 te
|
|
|
103
107
|
|
|
104
108
|
**Worktree discipline.** Your brief's first pre-flight step (Step 0) is creating a worktree — do it before anything else. If dispatched by an automation layer, you work in the worktree it created at `.worktrees/task/<tranche>/<n>/`. If working manually, the brief's Step 0 gives you the `git worktree add … origin/main` command — run it and `cd` in. Never branch from a local checkout that may be behind.
|
|
105
109
|
|
|
106
|
-
**Commit per Part, push once.** Commit after each numbered Part in the brief — small, one logical change per commit, so the history reads as a narrative of how you approached the problem. Push exactly once, immediately before `pr create` — not after every commit. The pre-push hook itself runs the affected test suite (`bunx turbo test --affected`) on that one push and refuses it on failure; you do not additionally run it yourself per Part. A regeneration or evidence run (`vinaya pr report --write`/`--push`) passes `--force` to its own test invocation. A verdict binds to the head it judged; a push landing after the newest verdict's judged head voids it and is named as such: `vinaya review status` prints `push after verdict — re-review required`, and merge waits on a fresh review round.
|
|
110
|
+
**Commit per Part, push once.** Commit after each numbered Part in the brief — small, one logical change per commit, so the history reads as a narrative of how you approached the problem. Push exactly once, immediately before `pr create` — not after every commit. The pre-push hook itself runs the affected test suite (`bunx turbo test --affected`) on that one push and refuses it on failure; you do not additionally run it yourself per Part. The affected suite covers only the packages `turbo`'s own dependency graph marks affected by this diff — a rule about one package's files that lives in another package's test never runs on a push that only touches the first package (found live: a CLI-only diff never marked `aeg-core` affected, so a rule about CLI files, asserted only in an `aeg-core` test, never ran at the push hook at all). A rule meant to bind a package's own files belongs in a `vinaya check`, not in a sibling package's test suite. A regeneration or evidence run (`vinaya pr report --write`/`--push`) passes `--force` to its own test invocation. A verdict binds to the head it judged; a push landing after the newest verdict's judged head voids it and is named as such: `vinaya review status` prints `push after verdict — re-review required`, and merge waits on a fresh review round.
|
|
107
111
|
|
|
108
|
-
**Opening the PR with a complete description.** The PR description must (1) **carry the report only** —
|
|
112
|
+
**Opening the PR with a complete description.** The PR description must (1) **carry the report only** — the brief itself never rides in this body at all; it is already posted, frozen, as the task Issue's `aeg:brief:v1` comment by `vinaya task dispatch`, before your worktree even exists, and that comment is the brief's permanent, durable home — the Reviewer and Archivist read it there; (2) follow the canonical form in [§ PR body — canonical form](#pr-body--canonical-form) below — that section holds the verbatim copy-pasteable template, including the **exact `Tier:` field syntax** the `verify-docs` gate requires; (3) reference the task's Issue (`Closes #N`) so the merge auto-closes it. The description is not optional — the reviews depend on it. Opening the PR is itself the `in-flight → in-review` transition; you write no status field. **The body is authored once, at open.** After the PR is open, you never hand-edit it again — not to append a response to a review round, not to record a decision, not for any reason. Two writes are sanctioned after open, both machine-regenerated, never typed: the Evidence block, and one appended row in the Token report for a re-entry turn (see [§ Evidence is emitted, never typed](#evidence-is-emitted-never-typed)). Everything else a review round produces — your response to findings, re-run `[agent]` evidence, any disclosure the brief didn't anticipate — is a PR comment.
|
|
109
113
|
|
|
110
114
|
**Reporting exact tokens in the PR body at turn-end.** You do not append your own row to `aeg-root/tranches/<name>.tokens.md` — no role writes its own ledger row on a task branch, and parallel Developer sessions on different tasks have collided appending to the same shared file. Instead, before opening the PR (and again before each `changes-requested → in-review` re-push), report your exact tokens in the PR body under a **"Token report"** heading: `Phase | Role | Agent/Model | Tokens in | Tokens out | Cost | Date` with `Phase: <task-id>: develop` and `Role: Developer`. **That destination and that grammar are the requirement, and they are the same on every agent host.**
|
|
111
115
|
|
|
@@ -125,15 +129,17 @@ This is the verbatim PR-body template every Developer pastes when opening a PR.
|
|
|
125
129
|
|
|
126
130
|
This form is **forge-agnostic.** It depends on no GitHub feature, no `.github/PULL_REQUEST_TEMPLATE.md`, no agent-specific skill. It is the source of truth that travels with the methodology.
|
|
127
131
|
|
|
128
|
-
**Start from the template file:** copy `aeg-root/templates/pr-report-template.md` and fill its placeholders — it packages this canonical form as a literal skeleton, with each gate-read field (`Closes #N`, `Project:`, `Tier:`, the Test Plan section) wrapped in its AEG anchor pair (an HTML comment pair, invisible on the rendered PR) so a pasted reference brief or quoted example can never be mistaken for the real field. Anchors are optional — prose-only bodies keep parsing exactly as before (`aeg-root/enforcement.md`) — but the template seeds them by default; keep them.
|
|
132
|
+
**Start from the template file:** copy `aeg-root/templates/pr-report-template.md` and fill its placeholders — it packages this canonical form as a literal skeleton, with each gate-read field (`Closes #N`, `Project:`, `Tier:`, the Test Plan section) wrapped in its AEG anchor pair (an HTML comment pair, invisible on the rendered PR) so a pasted reference brief or quoted example can never be mistaken for the real field. Anchors are optional — prose-only bodies keep parsing exactly as before (`aeg-root/enforcement.md`) — but the template seeds them by default; keep them. There is no `## Reference` section to fill: the brief never rides in this body at all — it is already posted, frozen, on the task Issue — and `pr create` refuses a body still carrying either legacy `aeg:brief:start`/`aeg:brief:end` marker.
|
|
129
133
|
|
|
130
134
|
```markdown
|
|
131
|
-
##
|
|
135
|
+
## Decisions
|
|
132
136
|
|
|
133
|
-
<one
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
+
<one line per choice the brief left open, e.g. `- <choice>: <what you picked
|
|
138
|
+
and why>` — the alternatives you considered and why you picked yours, so the
|
|
139
|
+
Principal can reverse a wrong call. Never restate what the diff does. No
|
|
140
|
+
verification claims — no "typecheck passes", no diff stats, no test counts.
|
|
141
|
+
Those are the Evidence block below, and it is the ONLY sanctioned home for
|
|
142
|
+
them: emitted by `vinaya pr report --write`, never hand-typed.>
|
|
137
143
|
|
|
138
144
|
## Test plan
|
|
139
145
|
|
|
@@ -176,9 +182,9 @@ field on its own line:>
|
|
|
176
182
|
|
|
177
183
|
| Field | Requirement |
|
|
178
184
|
|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
179
|
-
|
|
|
185
|
+
| Decisions | One line per choice the brief left open — the alternatives considered and why yours won. Never a restatement of what the diff does. No verification claims (typecheck/lint/test/diff-stat output, pass counts) — those belong exclusively in Evidence, below. "No open choices" is a valid value, stated explicitly, same as `Test Plan: unit-tests-only`'s sentinel pattern — never left blank with no words. |
|
|
180
186
|
| **Bare digits (whole body)** | `body-bare-digits` (CI) refuses any bare digit outside a fenced/indented/inline code span or `Closes`/`Project`/`Tier`/`Evidence`'s own anchor, correctly placed under its own documented section — nowhere else. `Premise`/`Test plan` get no anchor exemption at all (their real content is unbounded free text, so it's scanned like ordinary prose — a Test Plan item's own pass count or exit code needs backticks too). An Issue/PR ref, a date, a version, a path, a section number all now need their own backticks (`` `#N` ``); a countable claim ("138 passed", a duration, a percentage) belongs in a fenced block or doesn't get written. |
|
|
181
|
-
| Test plan | Every runtime-observable check. The
|
|
187
|
+
| Test plan | Every runtime-observable check. The Issue's `## Test plan` section makes this a **required** field, rendered mechanically into the brief — empty plans use `Test Plan: unit-tests-only` as the sentinel. |
|
|
182
188
|
| `[agent]` fenced list | A fenced block, one command per line, each with `→ <expected observable>`. `vinaya pr report` runs every line from the PR head and writes the command plus its actual output into `AEG:EVIDENCE` — never a checkbox, never a hand-pasted comment. (This is the `[agent]` half of the Verification phase, see `state-machine.md` § Verification.) |
|
|
183
189
|
| `[principal]` items | Checkbox items only the Principal can run (auth-gated, vendor-key-dependent, visual). The agent **does not tick these** — the Principal does, after running in a real browser. |
|
|
184
190
|
| Evidence | The `AEG:EVIDENCE` block — emitted by `vinaya pr report --write`, never hand-typed. See [§ Evidence is emitted, never typed](#evidence-is-emitted-never-typed). `check-evidence-fresh` refuses a body whose block doesn't match the head it's attached to. |
|
|
@@ -193,7 +199,7 @@ field on its own line:>
|
|
|
193
199
|
|
|
194
200
|
The `AEG:EVIDENCE` block is populated by running `vinaya pr report --write <body-file>` — never by hand-typing a diff stat, a test count, or a gate's pass/fail line into the PR body. Regenerate it after your final commit, before opening or editing the PR: `vinaya pr report --write` both runs the real gates (Group B) and recomputes the diff stat (Group A), so its own exit code doubles as the pre-open verification run — a red gate still writes the block (recording the failure honestly) but exits non-zero, so a scripted `--write && open-pr` never carries a failing suite onto the forge.
|
|
195
201
|
|
|
196
|
-
`check-evidence-fresh` (CI) refuses a body whose block doesn't match the head it's attached to — recomputing Group A exactly and checking Group B for staleness. This closes fabrication for **Group A only** (a hand-typed diff stat cannot survive a byte-compare); Group B is checked for freshness, not re-run, so a stale-but-not-fabricated Group B slips past unless the block is also out of date. Do not claim in this PR's own Evidence section, or anywhere else, that this closes fabrication generally — it closes it for the two facts a checker can cheaply recompute, never for the
|
|
202
|
+
`check-evidence-fresh` (CI) refuses a body whose block doesn't match the head it's attached to — recomputing Group A exactly and checking Group B for staleness. This closes fabrication for **Group A only** (a hand-typed diff stat cannot survive a byte-compare); Group B is checked for freshness, not re-run, so a stale-but-not-fabricated Group B slips past unless the block is also out of date. Do not claim in this PR's own Evidence section, or anywhere else, that this closes fabrication generally — it closes it for the two facts a checker can cheaply recompute, never for the Decisions section's prose.
|
|
197
203
|
|
|
198
204
|
**Regeneration is one command, run last, after every other change.** The Developer never hand-edits the live PR body after open — there is no local body file to keep in sync with the forge. When a push forces the Evidence block to go stale — or a re-entry turn needs its one appended Token report row — run, from the repo root, after every commit for that round is already pushed:
|
|
199
205
|
|
|
@@ -222,7 +228,7 @@ All of the following must pass before the PR is opened:
|
|
|
222
228
|
- [ ] Code passes typecheck (this repo: `bun run typecheck`)
|
|
223
229
|
- [ ] Code passes lint/format (this repo: `bun run format-and-lint`)
|
|
224
230
|
- [ ] Tests pass if applicable (this repo: `bun test`)
|
|
225
|
-
- [ ] PR description follows the template, carries the
|
|
231
|
+
- [ ] PR description follows the template, carries the report, and declares `Tier: 0`
|
|
226
232
|
- [ ] "Token report" section in the PR body carrying your turn's real token figures, collected by whatever means your host offers (see the token-reporting section above; on this repo's shipped reference host, `vinaya tokens`) — and, on each re-push after `CHANGES_REQUESTED`, one appended row inside the `AEG:TOKENS` anchor, written in the same `pr edit` that regenerates the Evidence block (see [§ Evidence is emitted, never typed](#evidence-is-emitted-never-typed)); the Archivist appends the ledger row post-merge, you do not
|
|
227
233
|
|
|
228
234
|
### Tier 1 checklist
|
|
@@ -277,12 +283,12 @@ Then stop. Review is a separate invocation.
|
|
|
277
283
|
The work now enters Phase 10 review (`process.md`):
|
|
278
284
|
|
|
279
285
|
```
|
|
280
|
-
code-reviewer pass → security pass → Principal code review →
|
|
286
|
+
code-reviewer pass → security pass → Principal code review → Planner spec review → merge
|
|
281
287
|
```
|
|
282
288
|
|
|
283
289
|
The code-reviewer and security passes are **separate, fresh-context invocations** — not you. You do not review your own work; the independence is the point. What you do:
|
|
284
290
|
|
|
285
|
-
- **Address REQUEST CHANGES / FAIL findings.** A code-review BLOCKER or a security CRITICAL/HIGH comes back to you. Fix it on the **same branch** with new commits; the relevant pass re-runs. Do not open a new PR. (Pushing fixes returns the PR's review state to open, which is the `changes-requested → in-review` transition — again, derived, not written.) Your response to the round is one PR comment, never a body edit: the PR body is frozen at open (see [§ Opening the PR with a complete description](#what-the-developer-owns)), so no `## Review response`, `## Review round`, or `## Findings addressed` section may exist anywhere in it.
|
|
291
|
+
- **Address REQUEST CHANGES / FAIL findings.** A code-review BLOCKER or a security CRITICAL/HIGH comes back to you. Fix it on the **same branch** with new commits; the relevant pass re-runs. Do not open a new PR. (Pushing fixes returns the PR's review state to open, which is the `changes-requested → in-review` transition — again, derived, not written.) Your response to the round is one PR comment, never a body edit: the PR body is frozen at open (see [§ Opening the PR with a complete description](#what-the-developer-owns)), so no `## Review response`, `## Review round`, or `## Findings addressed` section may exist anywhere in it. A `doc-correctness` finding carries a `Search:` pattern — a repo-wide `git grep -n -iE` pattern, with no path filter — and is resolved only when every hit it returns at the new head is a true statement. So fix every copy, not only the anchored line: re-run that pattern yourself, correct every hit, and paste the command and its output at the fixed head into your round response. A response that fixes only the anchored line, or omits the pasted search output, is malformed and the finding stays open. Where the corrected sentence states what code does, bind it with an `AEG:CLAIM` marker so `verify-docs` C8 keeps it honest.
|
|
286
292
|
- **Do not argue findings into submission.** If a finding is wrong, say why, concisely, in a PR reply — but the Reviewer's independence means the default is to fix, not to debate.
|
|
287
293
|
- **Do not act on an escalation yourself.** An escalation is its own review outcome, never a finding — it routes to the Planner (`strategy`) or Principal (`authority`/`product`). Wait for direction.
|
|
288
294
|
- **Do not merge.** Only the Principal merges.
|
|
@@ -339,7 +345,7 @@ Every brief includes stop conditions. Honor them unconditionally. Common reasons
|
|
|
339
345
|
When dispatched by an automation layer, you work in the worktree it created at `.worktrees/task/<tranche>/<n>/` on branch `task/<tranche>/<n>` — your isolated workspace, branched from `origin/main`.
|
|
340
346
|
|
|
341
347
|
When working manually, the brief's pre-flight Step 0 gives you the worktree command. Run it first:
|
|
342
|
-
- `git worktree add .worktrees/task/<tranche>/<n> -b task/<tranche>/<n> origin/main && cd .worktrees/task/<tranche>/<n
|
|
348
|
+
- `git worktree add .worktrees/task/<tranche>/<n> -b task/<tranche>/<n> --no-track origin/main && cd .worktrees/task/<tranche>/<n> && git config push.autoSetupRemote true`
|
|
343
349
|
- Then `git worktree list` to confirm you're not accidentally working in another task's worktree
|
|
344
350
|
- Branch from `origin/main`, never from `HEAD` of the current local checkout (which may be behind)
|
|
345
351
|
- Confirm the branch was created correctly: `git log --oneline -3` should show the expected parent
|
|
@@ -412,7 +418,7 @@ The checks above are **static**: they prove the change compiles, lints, types an
|
|
|
412
418
|
### Refuse if it isn't your turn
|
|
413
419
|
|
|
414
420
|
- **No open PR** — nothing to verify; come back when one is open.
|
|
415
|
-
- **No `aeg:brief` comment on the
|
|
421
|
+
- **No `aeg:brief:v1` comment on the task Issue** — without a Test Plan there is no definition of "verified"; `vinaya task dispatch` must post the frozen brief comment first.
|
|
416
422
|
- **No Test Plan section in the brief** — the brief is malformed; flag it for correction and stop rather than inventing a plan at verification time.
|
|
417
423
|
- **The plan declares `unit-tests-only` but the diff touches a runtime surface** (a route, a page, a server action) — the brief was mis-declared; flag it for correction. This is the failsafe against quietly downgrading verification.
|
|
418
424
|
|