session-orchestrator 4.1.0 → 5.0.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 (230) hide show
  1. package/.agents/skills/session-plan/SKILL.md +1 -1
  2. package/.agents/skills/session-start/SKILL.md +1 -1
  3. package/.agents/skills/ux-grill/SKILL.md +22 -0
  4. package/.claude-plugin/marketplace.json +1 -1
  5. package/.claude-plugin/plugin.json +3 -2
  6. package/.codex-plugin/plugin.json +1 -1
  7. package/.codex-plugin/skills/session-plan/SKILL.md +1 -1
  8. package/.codex-plugin/skills/session-start/SKILL.md +1 -1
  9. package/.codex-plugin/skills/ux-grill/SKILL.md +21 -0
  10. package/.codex-plugin/skills/ux-grill/agents/openai.yaml +5 -0
  11. package/.cursor/commands/ux-grill.md +14 -0
  12. package/.cursor/skills/session-plan/SKILL.md +1 -1
  13. package/.cursor/skills/session-start/SKILL.md +1 -1
  14. package/.cursor/skills/ux-grill/SKILL.md +13 -0
  15. package/.cursor-plugin/plugin.json +1 -1
  16. package/AGENTS.md +2 -1
  17. package/CHANGELOG.md +128 -1
  18. package/README.md +98 -86
  19. package/agents/dialectic-deriver.md +11 -0
  20. package/agents/ux-evaluator.md +1 -1
  21. package/commands/close.md +3 -3
  22. package/commands/go.md +2 -0
  23. package/commands/memory-cleanup.md +4 -3
  24. package/commands/persona-panel.md +1 -1
  25. package/commands/session.md +3 -2
  26. package/commands/ux-grill.md +51 -0
  27. package/docs/README.md +4 -4
  28. package/docs/USER-GUIDE.md +117 -50
  29. package/docs/agent-authoring.md +2 -2
  30. package/docs/baseline.md +55 -1
  31. package/docs/ci-setup.md +1 -1
  32. package/docs/codex-setup.md +9 -0
  33. package/docs/components.md +9 -9
  34. package/docs/cursor-setup.md +1 -0
  35. package/docs/events-schema.md +13 -6
  36. package/docs/github-mirror-protection.md +61 -20
  37. package/docs/instruction-delivery.md +1 -1
  38. package/docs/memory-proposal-flow.md +3 -3
  39. package/docs/migration-v4.md +2 -2
  40. package/docs/migration-v5.md +62 -0
  41. package/docs/owner-config-schema.md +74 -90
  42. package/docs/persona-panel.md +4 -4
  43. package/docs/pi-setup.md +1 -0
  44. package/docs/rule-authoring.md +13 -6
  45. package/docs/scope-collision-guard.md +16 -0
  46. package/docs/session-config-reference.md +55 -22
  47. package/docs/session-config-template.md +9 -5
  48. package/docs/vault-docs-architecture.md +4 -2
  49. package/hooks/_lib/hook-import-set.json +70 -3
  50. package/hooks/_lib/lock-bootstrap.mjs +84 -1
  51. package/hooks/_lib/vcs-create-matcher.mjs +401 -16
  52. package/hooks/enforce-scope.mjs +201 -0
  53. package/hooks/hooks-codex.json +1 -1
  54. package/hooks/hooks-cursor.json +5 -0
  55. package/hooks/hooks.json +7 -2
  56. package/hooks/on-session-start.mjs +171 -49
  57. package/hooks/post-bash-issue-budget-refund.mjs +375 -0
  58. package/hooks/pre-auq-clarity.mjs +70 -18
  59. package/hooks/pre-bash-issue-budget.mjs +170 -26
  60. package/hooks/subagent-telemetry.mjs +106 -20
  61. package/package.json +5 -4
  62. package/pi/prompts/ux-grill.md +12 -0
  63. package/scripts/baseline-archetypes.mjs +28 -0
  64. package/scripts/ci/assert-vitest-green.mjs +4 -2
  65. package/scripts/dialectic-deriver.mjs +32 -8
  66. package/scripts/emit-session.mjs +72 -1
  67. package/scripts/lib/agent-status.mjs +441 -9
  68. package/scripts/lib/auq/schema.mjs +10 -3
  69. package/scripts/lib/auto-dialectic.mjs +0 -68
  70. package/scripts/lib/baseline-archetypes.mjs +439 -0
  71. package/scripts/lib/build-live-signals.mjs +5 -6
  72. package/scripts/lib/ci-status-banner.mjs +29 -6
  73. package/scripts/lib/claude-md-budget-lint.mjs +52 -2
  74. package/scripts/lib/config/issue-budget.mjs +68 -8
  75. package/scripts/lib/config/private-config-dir.mjs +3 -2
  76. package/scripts/lib/config/remote-hosts.mjs +2 -2
  77. package/scripts/lib/config-schema.mjs +79 -0
  78. package/scripts/lib/config.mjs +12 -1
  79. package/scripts/lib/eval/engine.mjs +7 -1
  80. package/scripts/lib/file-lock.mjs +151 -8
  81. package/scripts/lib/git-porcelain.mjs +113 -0
  82. package/scripts/lib/instruction-budget-guard.mjs +415 -47
  83. package/scripts/lib/io.mjs +29 -4
  84. package/scripts/lib/issue-budget-reconcile.mjs +392 -0
  85. package/scripts/lib/issue-budget.mjs +412 -9
  86. package/scripts/lib/learnings/evolve-telemetry.mjs +1 -2
  87. package/scripts/lib/learnings/sizing-subject.mjs +44 -0
  88. package/scripts/lib/locks/staging-fence-lock.mjs +19 -38
  89. package/scripts/lib/locks/state-md-lock.mjs +19 -41
  90. package/scripts/lib/maintenance-due-banner.mjs +450 -0
  91. package/scripts/lib/owner-config.example.yaml +29 -46
  92. package/scripts/lib/owner-yaml.mjs +14 -13
  93. package/scripts/lib/peer-cards/merger.mjs +143 -0
  94. package/scripts/lib/pre-dispatch-check.mjs +20 -14
  95. package/scripts/lib/project-hygiene.mjs +81 -30
  96. package/scripts/lib/quality-gate.mjs +27 -71
  97. package/scripts/lib/reconcile/engine.mjs +19 -1
  98. package/scripts/lib/reconcile/writer.mjs +278 -11
  99. package/scripts/lib/resource-probe/evaluate.mjs +19 -21
  100. package/scripts/lib/rules-sync.mjs +34 -4
  101. package/scripts/lib/scope-echo.mjs +346 -0
  102. package/scripts/lib/session-close-backfill.mjs +182 -40
  103. package/scripts/lib/session-end/phase-skip.mjs +85 -86
  104. package/scripts/lib/session-end/tail-runner.mjs +178 -0
  105. package/scripts/lib/session-lock.mjs +62 -2
  106. package/scripts/lib/session-record-repair.mjs +91 -0
  107. package/scripts/lib/session-schema/constants.mjs +6 -0
  108. package/scripts/lib/session-schema/filters.mjs +26 -1
  109. package/scripts/lib/session-schema/validator.mjs +20 -0
  110. package/scripts/lib/session-shape.mjs +558 -0
  111. package/scripts/lib/session-start-probes.mjs +429 -56
  112. package/scripts/lib/session-token-rollup.mjs +95 -10
  113. package/scripts/lib/state-md/frontmatter-mutators.mjs +22 -34
  114. package/scripts/lib/state-md.mjs +1 -0
  115. package/scripts/lib/subagents-schema.mjs +77 -9
  116. package/scripts/lib/telemetry/pricing.mjs +197 -0
  117. package/scripts/lib/telemetry/sync.mjs +50 -1
  118. package/scripts/lib/test-runner/artifact-paths.mjs +30 -5
  119. package/scripts/lib/test-runner/issue-reconcile.mjs +45 -8
  120. package/scripts/lib/tmux-layout/layouts.mjs +62 -4
  121. package/scripts/lib/ux-grill/collect.mjs +1163 -0
  122. package/scripts/lib/ux-grill/compare.mjs +285 -0
  123. package/scripts/lib/ux-grill/manifest.mjs +618 -0
  124. package/scripts/lib/ux-grill/measures.mjs +431 -0
  125. package/scripts/lib/ux-grill/paths.mjs +224 -0
  126. package/scripts/lib/ux-grill/pencil-coverage.mjs +284 -0
  127. package/scripts/lib/ux-grill/reconcile.mjs +344 -0
  128. package/scripts/lib/ux-grill/run-record.mjs +316 -0
  129. package/scripts/lib/ux-grill/schema.mjs +321 -0
  130. package/scripts/lib/validate/check-skill-script-paths.mjs +33 -10
  131. package/scripts/lib/validate/check-untracked-test-deps.mjs +33 -19
  132. package/scripts/lib/validate/check-unwired-features.mjs +56 -27
  133. package/scripts/lib/vault-mirror/process.mjs +2 -1
  134. package/scripts/lib/vault-status/board-lock.mjs +18 -0
  135. package/scripts/lib/vault-status/board-writer.mjs +8 -0
  136. package/scripts/lib/vault-status/narrative-mirror.mjs +4 -4
  137. package/scripts/lib/wave-resource-gate.mjs +23 -27
  138. package/scripts/lib/wave-sizing.mjs +10 -3
  139. package/scripts/materialize-wave-scope.mjs +68 -14
  140. package/scripts/mcp-server.sh +16 -1
  141. package/scripts/print-applicable-rules.mjs +7 -6
  142. package/scripts/print-learnings-index.mjs +3 -2
  143. package/scripts/release.mjs +7 -2
  144. package/scripts/session-shape.mjs +266 -0
  145. package/skills/_shared/config-reading.md +15 -9
  146. package/skills/_shared/private-capability-context.md +89 -0
  147. package/skills/bootstrap/SKILL.md +60 -209
  148. package/skills/bootstrap/_shared-template.md +99 -14
  149. package/skills/bootstrap/deep-template.md +36 -26
  150. package/skills/bootstrap/fast-template.md +44 -8
  151. package/skills/bootstrap/intensity-heuristic.md +10 -4
  152. package/skills/bootstrap/private-contract.md +119 -0
  153. package/skills/bootstrap/public-fallback.md +30 -18
  154. package/skills/bootstrap/references/bootstrap-ecosystem-health-flow.md +48 -0
  155. package/skills/bootstrap/references/bootstrap-refresh-lock-flow.md +37 -0
  156. package/skills/bootstrap/references/bootstrap-retroactive-flow.md +108 -0
  157. package/skills/bootstrap/references/bootstrap-rules-fetch-bridge.md +64 -0
  158. package/skills/bootstrap/standard-template.md +39 -24
  159. package/skills/claude-md-drift-check/SKILL.md +9 -2
  160. package/skills/claude-md-drift-check/checker.mjs +213 -21
  161. package/skills/discovery/SKILL.md +6 -173
  162. package/skills/discovery/probes/vault-staleness.mjs +35 -5
  163. package/skills/discovery/probes-docs.md +8 -4
  164. package/skills/discovery/probes-supply-chain.md +4 -2
  165. package/skills/discovery/probes-ui.md +8 -4
  166. package/skills/discovery/probes-vault.md +12 -4
  167. package/skills/discovery/references/discovery-interactive-triage.md +139 -0
  168. package/skills/discovery/references/discovery-triage-state.md +54 -0
  169. package/skills/docs-orchestrator/audience-mapping.md +1 -1
  170. package/skills/eval/rubric-v1.md +13 -0
  171. package/skills/evolve/SKILL.md +2 -458
  172. package/skills/evolve/references/evolve-analyze-mode.md +360 -0
  173. package/skills/evolve/references/evolve-dialectic-mode.md +139 -0
  174. package/skills/gitlab-ops/SKILL.md +3 -3
  175. package/skills/grill/SKILL.md +1 -1
  176. package/skills/memory-cleanup/SKILL.md +2 -2
  177. package/skills/plan/mode-new.md +9 -0
  178. package/skills/plan/mode-retro.md +4 -3
  179. package/skills/reconcile/SKILL.md +11 -1
  180. package/skills/session-end/SKILL.md +3 -2
  181. package/skills/session-end/drift-operations.md +20 -5
  182. package/skills/session-end/metrics-collection.md +1 -0
  183. package/skills/session-end/phase-3-2-docs-verification.md +1 -1
  184. package/skills/session-end/phase-3-6-tail.md +27 -67
  185. package/skills/session-end/phase-3-7a-recommendations.md +2 -2
  186. package/skills/session-end/references/phase-2-quality-gate.md +3 -3
  187. package/skills/session-end/references/phase-3-documentation-updates.md +8 -6
  188. package/skills/session-end/references/phase-5-issue-cleanup.md +32 -1
  189. package/skills/session-end/session-metrics-write.md +33 -12
  190. package/skills/session-plan/SKILL.md +46 -180
  191. package/skills/session-plan/references/session-plan-task-classification.md +152 -0
  192. package/skills/session-plan/wave-template.md +8 -15
  193. package/skills/session-start/SKILL.md +41 -7
  194. package/skills/session-start/phase-2-5-docs-planning.md +1 -1
  195. package/skills/session-start/phase-8-5-express-path.md +12 -9
  196. package/skills/session-start/references/operations-contract.md +114 -0
  197. package/skills/session-start/references/phase-1-5-session-continuity.md +2 -0
  198. package/skills/session-start/references/phase-4-ssot-environment-check.md +42 -24
  199. package/skills/session-start/references/phase-6-7-memory-banner-telemetry-consent.md +3 -1
  200. package/skills/session-start/soul.md +2 -2
  201. package/skills/test-runner/SKILL.md +1 -1
  202. package/skills/test-runner/rubric-v1.md +2 -2
  203. package/skills/tmux-layout/SKILL.md +3 -1
  204. package/skills/ux-grill/SKILL.md +211 -0
  205. package/skills/ux-grill/rubric-v2.md +201 -0
  206. package/skills/ux-grill/soul.md +76 -0
  207. package/skills/wave-executor/SKILL.md +32 -127
  208. package/skills/wave-executor/circuit-breaker.md +3 -1
  209. package/skills/wave-executor/references/wave-executor-quality-gate.md +61 -0
  210. package/skills/wave-executor/references/wave-executor-state-init.md +86 -0
  211. package/skills/wave-executor/references/wave-loop-dispatch.md +12 -2
  212. package/skills/wave-executor/references/wave-loop-review.md +19 -6
  213. package/skills/wave-executor/references/wave-loop-scope-manifest.md +6 -2
  214. package/templates/_shared/ux-manifest.template.md +149 -0
  215. package/templates/nextjs-minimal/package.json +1 -1
  216. package/templates/node-minimal/package.json +1 -1
  217. package/scripts/lib/multi-provider-build/providers.mjs +0 -64
  218. package/scripts/lib/multi-provider-build/templating.mjs +0 -130
  219. package/scripts/lib/owner-config/coerce.mjs +0 -29
  220. package/scripts/lib/owner-config/constants.mjs +0 -21
  221. package/scripts/lib/owner-config/defaults.mjs +0 -50
  222. package/scripts/lib/owner-config/error.mjs +0 -19
  223. package/scripts/lib/owner-config/index.mjs +0 -13
  224. package/scripts/lib/owner-config/merge.mjs +0 -52
  225. package/scripts/lib/owner-config/validate.mjs +0 -259
  226. package/scripts/lib/owner-config-loader.mjs +0 -170
  227. package/scripts/lib/owner-config.mjs +0 -28
  228. package/scripts/lib/soul-resolve.mjs +0 -130
  229. package/scripts/lib/vault-mirror/render.mjs +0 -8
  230. package/templates/_shared/journey-manifest.md +0 -114
@@ -8,7 +8,7 @@ model-preference-codex: gpt-5.4
8
8
  model-preference-cursor: claude-opus-4-6
9
9
  description: >
10
10
  Creates a structured wave execution plan with role-based assignment after user alignment.
11
- Decomposes agreed tasks into configurable waves (default 5) with optimal agent assignment,
11
+ Decomposes agreed tasks into waves resolved from the session mode by `scripts/session-shape.mjs`, with optimal agent assignment,
12
12
  dependency ordering, and inter-wave checkpoints. Activated by session-start after Q&A phase completes.
13
13
  ---
14
14
 
@@ -48,6 +48,18 @@ This skill receives the agreed session scope from session-start. The scope inclu
48
48
 
49
49
  These are passed via the conversation context (not a file). Parse the preceding session-start output to extract the agreed scope.
50
50
 
51
+ ## Optional private capability context
52
+
53
+ Before either the express path or task decomposition, apply
54
+ [Private capability context](../_shared/private-capability-context.md) when the
55
+ owner explicitly supplies or authorizes a local catalog lookup for a known
56
+ private/internal planning audience. Reuse the bounded findings already supplied
57
+ by `/plan new` when applicable; do not repeat the same lookup. This step does not
58
+ require persistence. With no authorized context, or a public/unknown audience,
59
+ skip it without a prompt or lookup and continue the existing flow. Eligible
60
+ source references inform reuse alternatives and verification tasks; a catalog
61
+ match does not expand the agreed implementation scope or disable the express path.
62
+
51
63
  ## Express Path Short-Circuit (#214)
52
64
 
53
65
  > Check this **before Step 0**. If the express path is active, this skill emits a minimal 1-wave plan and exits — no role decomposition, no wave splitting, no agent count computation.
@@ -81,6 +93,8 @@ Emit this 1-wave plan and exit the skill immediately (do not continue to Step 1
81
93
  Express path — no inter-wave checks. Use /go to begin.
82
94
  ```
83
95
 
96
+ > The express path's 1-wave plan is the same shape housekeeping resolves to — one wave with `coordinatorDirect: true` and no dispatched agents (`scripts/session-shape.mjs --session-type housekeeping`). The express path stays as written above; it does not need to call the shape resolver to know that.
97
+
84
98
  **When express-path banner is absent or `express-path.enabled: false`:** Proceed to Step 0 and the full planning flow as normal.
85
99
 
86
100
  ## Step 0: Read Session Config
@@ -88,11 +102,11 @@ Express path — no inter-wave checks. Use /go to begin.
88
102
  Read and parse Session Config per `skills/_shared/config-reading.md`. Store result as `$CONFIG`.
89
103
 
90
104
  Extract these fields for planning:
91
- - `waves` (default: 5) — number of execution waves
92
- - `agents-per-wave` (default: 6, may have session-type overrides per `config-reading.md`) — max parallel agents per wave
93
- - `isolation` (default: auto) `worktree` / `none` / `auto` (auto = worktree for feature/deep, none for housekeeping)
94
- - `enforcement` (default: warn) — `strict` / `warn` / `off`
95
- - `max-turns` (default: auto) — agent turn budget (auto = housekeeping: 8, feature: 15, deep: 25)
105
+ - `waves` — number of execution waves; resolved by `scripts/session-shape.mjs` (`totalWaves`), do not compute by hand. The shape reports in `wavesConfigHonored` whether the configured value was used at all, and says why in `notes`.
106
+ - `agents-per-wave` (may have session-type overrides per `config-reading.md`) — the operator's ceiling; the per-wave cap that actually binds is resolved by `scripts/session-shape.mjs` (`waves[].agentCap`), do not compute by hand.
107
+ - `isolation` Session Config input (`worktree` / `none` / `auto`) that feeds `configIsolation` into the graduated per-wave rule (`resolveIsolation`, issue #194, in `scripts/lib/wave-sizing.mjs`: an explicit config value always wins; otherwise ≤2 agents → `none`, ≥5 agents → `worktree`, 3-4 agents → `none` for housekeeping else `worktree`). The RESOLVED value for a given wave is `waves[].isolation` in the shape's JSON output (`scripts/session-shape.mjs`) — a wave with `coordinatorDirect: true`, or a read-only wave, resolves `none` without calling `resolveIsolation` at all. Do not compute by hand; the plan header's `Isolation:` line is copied straight from that wave entry.
108
+ - `enforcement` (default: warn) — Session Config input (`strict` / `warn` / `off`) that feeds `configEnforcement` into `resolveEnforcement` (same module); the resolved per-wave value is `waves[].enforcement`. Isolation `none` auto-promotes `warn` to `strict`, since the scope-enforcement hook is then the only barrier left.
109
+ - `max-turns` — agent turn budget; resolved by `scripts/session-shape.mjs` (`waves[].maxTurns`), do not compute by hand.
96
110
  - `agent-mapping` (optional) — explicit role-to-agent bindings
97
111
  - `persistence` (default: true) — whether to use STATE.md and learnings
98
112
 
@@ -171,147 +185,11 @@ Before assigning tasks to waves, discover available agents for this session:
171
185
 
172
186
  ## Step 1.8: Task-to-Role Classification
173
187
 
174
- For each task from Step 1, assign exactly one role. Use these signal-to-role mappings:
175
-
176
- | Signal in task | Role | Examples |
177
- |---|---|---|
178
- | Needs codebase understanding before changes; audit, explore, verify assumptions, check existing coverage | **Discovery** | "Audit auth flow", "Check test coverage for module X", "Identify affected modules" |
179
- | New feature code, new API endpoints, DB schema changes, primary UI components, new modules | **Impl-Core** | "Add /api/users endpoint", "Create migration for invoices table", "Implement auth middleware" |
180
- | Bug fixes from prior waves, secondary features, integration work, edge cases, polish of existing code | **Impl-Polish** | "Fix pagination edge case", "Integrate payment with billing", "Handle error states in form" |
181
- | Documentation updates — new/changed README sections, CLAUDE.md (or AGENTS.md on Codex CLI) updates, vault context.md/decisions.md narratives, ADR edits. Audience-aware (User/Dev/Vault). Gated on `docs-orchestrator.enabled` | **Docs** | "Update README for new --no-vault flag", "Write CLAUDE.md section for new hook (or AGENTS.md on Codex CLI)", "Append vault decisions.md entry for architecture change" |
182
- | Write/update tests, lint fixes, security review, code simplification, type errors | **Quality** | "Add tests for auth module", "Fix TypeScript errors", "Security audit of new API" |
183
- | Documentation updates, issue cleanup, commit preparation, SSOT refresh, changelog | **Finalization** | "Update README", "Close resolved issues", "Write session handover notes" |
184
-
185
- **Disambiguation rules:**
186
- - If a task involves BOTH exploration AND implementation → split it: Discovery agent reads/validates, Impl-Core agent implements. Create two separate task entries.
187
- - If a task is "fix something from a previous session" (not from this session's Impl-Core) → classify as **Impl-Core** (it is new work for this session).
188
- - A "write tests for new feature code being built this session" task is created ONLY when Discovery or a qa-strategist run reported a **named gap** — a concrete bug or regression the current suite would let through, stated as such. When that gap exists, classify the task as **Quality** (not Impl-Core); tests run after implementation. "Feature X was built" is NOT by itself evidence of test demand: with no named gap, no Quality task is created — do not synthesize one to give the role something to do. A dispatched `test-writer` may correspondingly report `no-tests-needed` as a SUCCESS status, not a failure.
189
- - If unsure between Impl-Core and Impl-Polish → if the task is on the critical path (other tasks depend on it), it is **Impl-Core**. If independent polish, it is **Impl-Polish**.
190
- - **Docs role** is only active when `docs-orchestrator.enabled: true` in Session Config. When disabled (default), documentation-update tasks fall into **Impl-Polish** (inline doc changes alongside code) or **Finalization** (standalone doc/SSOT updates) as today.
191
-
192
- #### Step 1.8 Docs-role: Consuming the Phase 2.5 Emission Block
193
-
194
- When `docs-orchestrator.enabled: true`, session-start Phase 2.5 emits a delimited block in the conversation context. Read and parse it before synthesizing Docs-role tasks:
195
-
196
- **Locating the block:** Search the conversation context for the header `### Docs Planning Result (Phase 2.5)`. If the header is absent, Phase 2.5 was skipped — emit **0 Docs tasks** and do not fabricate any.
197
-
198
- **Parsing rules (apply in document order):**
199
- - `Audiences:` — comma-separated list of active audience identifiers (e.g., `user, dev`). Trim whitespace around each value.
200
- - `Mode:` — single enum value: `warn`, `strict`, or `off`. Store as `$docs_mode`.
201
- - `Docs-tasks-seed:` — multi-entry bullet list. Each top-level `- audience:` bullet is **one seed task**. Parse in document order; do not merge entries. Each seed task has:
202
- - `audience:` — target audience (`user`, `dev`, or `vault`)
203
- - `rationale:` — free-text description of what needs documenting
204
-
205
- **Synthesizing Docs-role tasks:** For each seed task entry (in document order):
206
- 1. Set `role: Docs`.
207
- 2. Set `description` derived from the `rationale` field (paraphrase as an actionable imperative, e.g., "Document the new `--no-vault` flag in user-facing README").
208
- 3. Set `audience` from the `audience` field.
209
- 4. Set `target-pattern` by looking up the audience in the `Audiences & File Patterns` table in `skills/docs-orchestrator/audience-mapping.md`. Use the glob pattern listed there for the matched audience row.
210
- 5. Resolve `subagent_type` per the Docs-role fast path in Step 1.5 point 4 above.
211
-
212
- **If the block is absent:** Do not fabricate Docs tasks. The Docs role remains empty; apply the empty-role rule from Step 2.
213
-
214
- - Housekeeping sessions: skip Steps 1.8, 2, and 3 — all tasks go into a single consolidated wave:
215
- - No role classification — all tasks treated as generic housekeeping work
216
- - Agent count: fixed at 1-2 per task (from wave-template.md housekeeping row), capped by `agents-per-wave`
217
- - File-scope deconfliction (Step 3.5) still applies within the single wave
218
- - Wave plan output uses: `### Wave 1: Housekeeping ([N agents])`
219
-
220
- Record the assigned role next to each task before proceeding to Step 2.
221
-
222
- ### Docs-tasks persistence (for session-end Phase 3.2)
223
-
224
- When `docs-orchestrator.enabled: true` AND the plan contains 1+ Docs tasks, session-plan MUST emit a machine-readable block **at the end of its plan output** (after the wave plan, before `Ready to execute?`). This block is the single source of truth (SSOT) consumed downstream:
225
-
226
- - **wave-executor Pre-Wave 1b (STATE.md init):** reads this block and persists `docs-tasks: [...]` into STATE.md frontmatter.
227
- - **session-end Phase 3.2 (docs verification):** reads `docs-tasks` back from STATE.md to verify each task produced a diff.
228
-
229
- **Emit format:**
230
-
231
- ```yaml
232
- ### Docs Tasks (machine-readable)
233
- docs-tasks:
234
- - id: docs-1
235
- audience: <user|dev|vault>
236
- target-pattern: <glob from skills/docs-orchestrator/audience-mapping.md>
237
- rationale: <verbatim rationale from Phase 2.5 seed>
238
- wave: <wave number where this docs-writer agent is dispatched>
239
- status: planned
240
- - id: docs-2
241
- ...
242
- ```
243
-
244
- **Field rules:**
245
- - `id`: sequential index-based identifier (`docs-1`, `docs-2`, …). No UUID generation required.
246
- - `audience`: one of `user`, `dev`, `vault`.
247
- - `target-pattern`: the glob from `skills/docs-orchestrator/audience-mapping.md` for this audience row — do not invent patterns.
248
- - `rationale`: copy the `rationale` text from the Phase 2.5 seed entry verbatim (do not paraphrase here).
249
- - `wave`: the actual wave number assigned in Step 2 where the `docs-writer` agent for this task is dispatched.
250
- - `status`: always `planned` at plan time. Terminal values are set by session-end Phase 3.2 per-task verification loop: `ok` (diff substantive), `partial` (diff has `<!-- REVIEW: source needed -->` markers), or `gap` (no matching diff). wave-executor does NOT perform intermediate status updates — `status: planned` remains until session-end writes the terminal value.
251
-
252
- **Omission rule:** When `docs-orchestrator.enabled: false` OR there are 0 Docs tasks, do NOT emit the `### Docs Tasks (machine-readable)` block. Absence of the block signals to wave-executor and session-end that no docs verification is needed for this session.
253
-
254
- ### Wave-Plan Mission Status (machine-readable)
255
-
256
- When the wave plan contains 1 or more wave-plan items (i.e., for all non-empty plans), session-plan MUST emit a machine-readable mission-status block **at the end of its plan output** (after the Docs Tasks block if present, before `Ready to execute?`). This block is the SSOT consumed by wave-executor (for STATE.md persistence) and session-end Phase 1.9 (for enum-based classification).
257
-
258
- - **wave-executor Pre-Wave 1b (STATE.md init):** reads this block and persists `mission-status: [...]` into STATE.md frontmatter via `writeMissionStatus` from `scripts/lib/state-md.mjs`.
259
- - **session-end Phase 1.9:** reads `mission-status` back from STATE.md frontmatter via `parseMissionStatus` to classify items into the 1.1–1.4 buckets using enum values.
260
-
261
- **Emit format:**
262
-
263
- ```yaml
264
- ### Wave-Plan Mission Status (machine-readable)
265
- mission-status:
266
- - id: m-1
267
- task: <task description from wave-plan item>
268
- wave: <N>
269
- status: brainstormed
270
- - id: m-2
271
- task: <task description from wave-plan item>
272
- wave: <N>
273
- status: brainstormed
274
- ```
275
-
276
- **Field rules:**
277
- - `id`: sequential `m-N` identifier. No UUID generation required.
278
- - `task`: verbatim task description from the wave-plan item (do not paraphrase).
279
- - `wave`: the wave number where this task is dispatched.
280
- - `status`: always `brainstormed` at plan emission. Terminal values are updated at gate transitions by wave-executor: `brainstormed` → `validated` (user confirms via `/go`) → `in-dev` (agent dispatched) → `testing` (Quality wave) → `completed` (Quality gate green). session-end Phase 1.9 reads the current value to classify the item.
281
-
282
- **Transition gates (summary):**
283
- At plan time, all items start at `brainstormed`. When the user runs `/go` to approve the plan, wave-executor updates each item to `validated`. When an agent for a wave-plan item is dispatched, wave-executor updates that item to `in-dev`. When the Quality wave begins, items from prior waves move to `testing`. When the Quality gate passes, items finalize at `completed`. Rollback to `brainstormed` is permitted from any state. This ordering is **coordinator convention, not a mechanical gate** — nothing validates a transition before it is written (see "Default and transitions" below).
284
-
285
- **Omission rule:** When the plan has 0 wave-plan items (e.g., pure express-path coord-direct with no sub-agent tasks), do NOT emit the `### Wave-Plan Mission Status (machine-readable)` block.
286
-
287
- ### Mission-Status Enum (#340)
288
-
289
- Every wave-plan item carries a `status` field drawn from a 5-value enum. The field is always present on items emitted in the `### Wave-Plan Mission Status (machine-readable)` block (see below). It is also the value persisted in STATE.md frontmatter and read back by session-end Phase 1.9 for enum-based classification.
290
-
291
- #### Enum values
292
-
293
- | Status | Meaning | Set when |
294
- |---|---|---|
295
- | `brainstormed` | Draft item from `/plan`, not yet user-confirmed | Plan emitted by session-plan (all items start here) |
296
- | `validated` | User confirmed via AUQ in session-plan (`/go` approval) | wave-executor: user runs `/go` to approve the wave plan |
297
- | `in-dev` | Agent picked up the task this wave | wave-executor: agent dispatched for this item |
298
- | `testing` | Implementation done, tests passing for this task | wave-executor: Quality wave begins for this item's work |
299
- | `completed` | Quality-Lite green for this task's wave | wave-executor: Quality gate passes for this item |
300
-
301
- #### Default and transitions
302
-
303
- - **Default at plan creation:** `brainstormed` — all items start here.
304
- - **Transitions are coordinator-level orchestration** (not inside individual agent prompts). See `skills/wave-executor/SKILL.md` "Mission-Status Updates (#340)" for when each transition fires.
305
- - **Rollback:** any item may return to `brainstormed` from any state (e.g. if work is discarded or re-planned).
306
- - **No mechanical validation — by design.** The `status` values come from the 5-value enum in the table above, but nothing checks a transition before it is written. `setMissionStatus` (`scripts/lib/state-md/mission-status.mjs`) mirrors whatever string it is handed onto BOTH the body section and the frontmatter array, deliberately without an enum gate: gating it would reintroduce the exact body-says-X/frontmatter-says-Y divergence that sync exists to remove. An out-of-enum value therefore lands visibly on both surfaces instead of being silently rejected on one. Keeping the enum honest is the coordinator's job.
307
-
308
- #### Status field in wave-plan items
309
-
310
- Every item in the wave plan output carries an implicit `status: brainstormed` at plan time. The `### Wave-Plan Mission Status (machine-readable)` block below (emitted at the end of the plan output) is the machine-readable form that wave-executor and session-end Phase 1.9 consume. session-plan does NOT write STATUS transitions — it only emits the initial `brainstormed` values.
188
+ Assigns exactly one role (Discovery/Impl-Core/Impl-Polish/Docs/Quality/Finalization) to each Step 1 task via the signal-to-role mapping table, the disambiguation rules, the Docs-role Phase 2.5 emission-block parsing, and the housekeeping short-circuit. Also emits the Docs Tasks and Wave-Plan Mission Status machine-readable blocks (SSOT for wave-executor + session-end) and the Mission-Status Enum (#340). See [references/session-plan-task-classification.md](references/session-plan-task-classification.md). **Read WHEN:** after Step 1.5, before Step 2.
311
189
 
312
190
  ## Step 2: Wave Assignment
313
191
 
314
- Distribute tasks across waves using 5 named roles. Read `waves` from Session Config (default: 5) and map roles to wave numbers.
192
+ Distribute tasks across the waves the session shape returned; each wave carries its own `role`. Which roles exist, and how many waves there are, is resolved by `scripts/session-shape.mjs` see § Role-to-Wave Mapping below.
315
193
 
316
194
  ### Wave Roles
317
195
 
@@ -325,33 +203,30 @@ Distribute tasks across waves using 5 named roles. Read `waves` from Session Con
325
203
 
326
204
  ### Role-to-Wave Mapping
327
205
 
328
- Map roles to the configured wave count:
206
+ The wave list is not derived here. Resolve it ONCE at plan time from the session mode:
207
+
208
+ ```bash
209
+ node scripts/session-shape.mjs --repo-root "$PWD" --session-type <housekeeping|feature|deep> \
210
+ [--profile ultradeep] [--known-scope true|false] --task-count <N>
211
+ ```
212
+
213
+ Run it **with** event emission (no `--no-event`) — that record (`orchestrator.session.shape_resolved` in `.orchestrator/metrics/events.jsonl`) is the canonical record of this session's shape. Use `--no-event` only for a throwaway planning dry-run.
329
214
 
330
- | `waves` | Mapping |
331
- |---------|---------|
332
- | 3 | W1=Discovery+Impl-Core, W2=Impl-Polish+Quality, W3=Finalization |
333
- | 4 | W1=Discovery, W2=Impl-Core+Impl-Polish, W3=Quality, W4=Finalization |
334
- | 5 | W1=Discovery, W2=Impl-Core, W3=Impl-Polish, W4=Quality, W5=Finalization |
335
- | 6+ | W1=Discovery, W2-W3=Impl-Core (split), W4-W5=Impl-Polish (split), W6=Quality+Finalization |
336
- | 7 + `session-profile: ultradeep` | W1=Research+Code-Discovery, W2=Synthesis-Gate (`coordinator-direct: true`, `agents: 0`), W3=Impl-Core, W4=Impl-Polish, W5=Review-Panel, W6=Quality, W7=Release/Finalization |
215
+ It prints one JSON line carrying:
337
216
 
338
- The last row applies ONLY when STATE.md frontmatter carries `session-profile: ultradeep` (written by the `/session ultradeep` argument alias see `commands/session.md`). `session-type` stays `deep`; the profile changes the wave SHAPE, nothing else. Without the profile, `waves: 7` falls back to the `6+` row. Spec: `docs/prd/2026-09-06-ultradeep-session-profile.md` § 5.
217
+ - `totalWaves` — the wave count
218
+ - `waves[]` — one record per wave: `n`, `role`, `agentCap`, `agentCapRaw`, `coordinatorDirect`, `writes`, `maxTurns`, `verification`, `qualityEarned`, `allowedPaths`
219
+ - `discovery` — whether a Discovery wave is part of the shape
220
+ - `wavesConfigHonored` — whether the Session Config `waves` value was used
221
+ - `notes` — human-readable reasons for any of the above
339
222
 
340
- **Ultradeep agent counts per wave** (caps, not targets — the Quality cap is still EARNED per the Step 3 rule):
223
+ **The plan's wave list IS that output.** The coordinator fills tasks into the returned waves and NEVER adds, removes, or renumbers a wave — the sole exception is the empty-role rule below (and its coordinator-direct carve-out). `--known-scope true` is what drops the Discovery wave on a deep session; `--profile ultradeep` is what selects the ultradeep shape, and it applies ONLY when STATE.md frontmatter carries `session-profile: ultradeep` (written by the `/session ultradeep` argument alias see `commands/session.md`). `session-type` stays `deep`; the profile changes the wave SHAPE, nothing else, and it ignores the Session Config `waves` value (the shape says so in `wavesConfigHonored` / `notes`). Spec: `docs/prd/2026-09-06-ultradeep-session-profile.md` § 5.
341
224
 
342
- | W | Role | Agents | Writes? |
343
- |---|------|--------|---------|
344
- | 1 | Research + Code-Discovery | ≤ 18 (separately scoped) | No (read-only) |
345
- | 2 | Synthesis-Gate | 0 (coordinator-direct) | Coordinator only: audit report, STATE.md, plan |
346
- | 3 | Impl-Core | ≤ 8 | Yes |
347
- | 4 | Impl-Polish | ≤ 8 | Yes |
348
- | 5 | Review-Panel | 3 (read-only) | No |
349
- | 6 | Quality | `min(cap, ceil((HIGH+MED)/3))` | Tests only |
350
- | 7 | Release/Finalization | ≤ 4 | Yes |
225
+ **Ultradeep agent counts per wave:** take each wave's cap from that wave's `agentCap` in the shape — there is no second table here to disagree with it. The caps are ceilings, not targets, and the Quality wave's cap is still EARNED per the Step 3 rule (the shape marks it `qualityEarned: true`); Research and Code-Discovery share wave 1's cap across their two separately-scoped groups; the Synthesis-Gate wave carries `agentCap: 0` with `coordinatorDirect: true` and writes only the coordinator's own artifacts (audit report, STATE.md, plan).
351
226
 
352
227
  Wave 1 splits into two disjointly-scoped groups: **Research** agents (web-enabled, see `skills/wave-executor/SKILL.md` § Ultradeep Profile) and **Code-Discovery** agents (repo-only). Both are read-only. Wave 2 dispatches NO agents — the coordinator consolidates wave 1, writes `docs/audits/<YYYY-MM-DD>-<slug>.md`, and asks ONE blocking `AskUserQuestion` before wave 3.
353
228
 
354
- When roles are combined into a single wave, agents from both roles execute in that wave. The combined wave inherits the more restrictive verification level.
229
+ When roles are combined into a single wave, agents from both roles execute in that wave.
355
230
 
356
231
  **Docs role dispatch rule (conditional — `docs-orchestrator.enabled: true` only):**
357
232
 
@@ -365,13 +240,11 @@ When `docs-orchestrator.enabled: true`, apply the following concrete dispatch ru
365
240
  - **NEVER add a 6th wave** for Docs. Docs always occupies an existing wave slot.
366
241
  - When `docs-orchestrator.enabled` is `false` (default), this rule has no effect — the Docs role does not exist.
367
242
 
368
- **Cross-role constraint in combined waves:** Tasks from different roles within a combined wave CANNOT be merged into a single agent (different scope permissions e.g., Discovery is read-only, Impl-Core has write access). If the combined wave exceeds `agents-per-wave`, defer the lower-priority role's tasks: in W1=Discovery+Impl-Core, defer Impl-Core tasks to the next applicable wave. In W2=Impl-Polish+Quality, defer Quality tasks to a separate phase within the same wave.
369
-
370
- > Example: When Discovery+Impl-Core are combined (3-wave config), the wave runs Incremental quality checks (Impl-Core's level) rather than no verification (Discovery's level).
243
+ **Cross-role constraint in combined waves:** Tasks from different roles within a combined wave (the feature shape's `Impl-Polish+Quality` is the one today) CANNOT be merged into a single agent — the roles carry different scope permissions. If the combined wave's tasks exceed its `agentCap`, defer the lower-priority role's tasks: in `Impl-Polish+Quality`, defer Quality tasks to a separate phase within the same wave.
371
244
 
372
- **Splitting criteria for 6+ waves**: When Impl-Core or Impl-Polish span multiple waves, split by module or dependency boundary. Tasks with shared file dependencies go in the same wave; tasks touching independent modules go in separate waves. If no clear boundary exists, split by task count (distribute evenly).
245
+ > A combined wave's `verification` field in the shape already carries the more restrictive of its two roles' levels read it, do not re-derive it.
373
246
 
374
- **Empty roles:** If a role has 0 tasks, skip its wave entirely. Do NOT dispatch an empty wave. Remaining waves retain their original role names but are renumbered sequentially (e.g., if Discovery has 0 tasks and waves=5: W1=Impl-Core, W2=Impl-Polish, W3=Quality, W4=Finalization). Update `total-waves` in the plan output to reflect the actual wave count.
247
+ **Empty roles:** If a role has 0 tasks, skip its wave entirely. Do NOT dispatch an empty wave. Remaining waves retain their original role names but are renumbered sequentially, and `total-waves` in the plan output is updated to reflect the actual wave count. **This rule never applies to Discovery.** Discovery is dropped exactly once, at shape-resolution time, by passing `--known-scope true` to `scripts/session-shape.mjs` Role-to-Wave Mapping above) — the shape itself renumbers the remaining waves and reports the new count as `totalWaves` in its JSON output, before the coordinator ever sees a wave list to assign tasks into. Applying this rule to Discovery by hand, after the fact, would be a second, competing renumbering of a decision the shape already made. The empty-role rule below is for the roles that stay ON the wave list after the shape is fixed (e.g., Docs, Quality) and whose task count can still fall to 0 during Step 1/1.8 classification.
375
248
 
376
249
  **Exception — a wave declared `coordinator-direct: true` is NEVER removed by the empty-role rule.** The rule's premise is "0 tasks means nothing to dispatch, so the wave is dead weight". For a coordinator-direct wave that premise is inverted: dispatching zero agents is the wave's PURPOSE, not evidence of its emptiness. Its plan item therefore carries BOTH markers and is emitted verbatim:
377
250
 
@@ -446,17 +319,9 @@ Score the session scope to determine optimal agent counts per wave. Skip for hou
446
319
 
447
320
  ### Agent Count by Tier
448
321
 
449
- | Session Type | Tier | Discovery | Impl-Core | Impl-Polish | Quality | Finalization |
450
- |-------------|------|-----------|-----------|-------------|---------|-------------|
451
- | feature | simple | 2-3 | 3-4 | 2-3 | 2 | 1 |
452
- | feature | moderate | 4-5 | 5-6 | 4-5 | 3-4 | 2 |
453
- | feature | complex | 5-6 | 6 | 5-6 | 4 | 2 |
454
- | deep | simple | 3-4 | 4-6 | 3-4 | 3 | 2 |
455
- | deep | moderate | 5-6 | 6-8 | 5-6 | 4-5 | 2-3 |
456
- | deep | complex | 6-8 | 8-10 | 6-8 | 6 | 3-4 |
457
- | housekeeping | (fixed) | — | 2 | 1 | 1 | 1 |
322
+ The caps themselves are **not** derived from the tier: each wave's ceiling is `waves[].agentCap` from the shape (`scripts/session-shape.mjs`, § Role-to-Wave Mapping above), and `agentCapRaw` is that cap before the Session Config `agents-per-wave` ceiling was applied.
458
323
 
459
- > Housekeeping sessions skip Discovery (tasks are predefined) and use fixed agent counts regardless of complexity.
324
+ What the tier score decides is **relaxation DOWNWARD only**: a simple-tier session may plan fewer agents than the wave's `agentCap` where the briefed work does not fill it. It may never plan more — the cap is a hard ceiling, and a moderate or complex tier does not raise it.
460
325
 
461
326
  > **The Quality column is a CAP, not a target.** Every other column sizes to briefed work; the Quality column historically sized to the tier alone, so capacity went looking for work (tests written because a slot existed, not because a gap was measured). Quality capacity must be EARNED by measured demand. Compute the effective count as `min(<tier cap>, ceil((HIGH + MED gaps from the most recent qa-strategist run) / 3))`.
462
327
  > - **0 HIGH and 0 MED gaps → the Quality role has 0 test-writing tasks**, and its wave is skipped by the Step 2 empty-role rule. This does NOT touch the read-only review panel (security-reviewer / qa-strategist / architect-reviewer) — that panel reviews, it does not write tests, and it keeps running as configured.
@@ -491,7 +356,7 @@ For each role's wave, distribute its classified tasks across the allocated agent
491
356
 
492
357
  > **Template Reference:** See `wave-template.md` in this skill directory for the agent specification format, isolation settings, and count tables.
493
358
 
494
- For each wave, define agents using the template format in `wave-template.md`. Apply the agent count table based on session type, capped by `agents-per-wave` from Session Config.
359
+ For each wave, define agents using the template format in `wave-template.md`. The per-wave ceiling is that wave's `agentCap` from the shape Role-to-Wave Mapping) it already carries the `agents-per-wave` Session Config ceiling.
495
360
 
496
361
  If project intelligence (learnings) suggests different sizing based on historical data, prefer the historical recommendation over the formula.
497
362
 
@@ -593,6 +458,7 @@ If the user requests changes:
593
458
  | File | Purpose |
594
459
  |------|---------|
595
460
  | `wave-template.md` | Step 4 agent specification format and count tables |
461
+ | `references/session-plan-task-classification.md` | Step 1.8: task-to-role classification, Docs-tasks + Wave-Plan Mission Status emission blocks, Mission-Status Enum (#340) |
596
462
 
597
463
  ## Anti-Patterns
598
464
 
@@ -0,0 +1,152 @@
1
+ # Session Plan — Step 1.8: Task-to-Role Classification
2
+
3
+ > Reference of the session-plan skill, split out of `SKILL.md` (#1246). Body moved **byte-identical**; only this header is new.
4
+ > **Sibling-file paths inside this body are relative to the parent directory, not to `references/`** — none needed rewriting: the moved body carries no relative markdown links, only backticked file mentions, which were deliberately left untouched so the bytes stay verifiable against the pre-split file.
5
+ > **Read after Step 1.5 (Agent Discovery) and before Step 2 (Wave Assignment) in `../SKILL.md`.** Covers the signal-to-role mapping table, disambiguation rules, the Docs-role Phase 2.5 emission block, the housekeeping short-circuit, the Docs-tasks and Wave-Plan Mission Status machine-readable emission blocks, and the Mission-Status Enum (#340).
6
+
7
+ ## Step 1.8: Task-to-Role Classification
8
+
9
+ For each task from Step 1, assign exactly one role. Use these signal-to-role mappings:
10
+
11
+ | Signal in task | Role | Examples |
12
+ |---|---|---|
13
+ | Needs codebase understanding before changes; audit, explore, verify assumptions, check existing coverage | **Discovery** | "Audit auth flow", "Check test coverage for module X", "Identify affected modules" |
14
+ | New feature code, new API endpoints, DB schema changes, primary UI components, new modules | **Impl-Core** | "Add /api/users endpoint", "Create migration for invoices table", "Implement auth middleware" |
15
+ | Bug fixes from prior waves, secondary features, integration work, edge cases, polish of existing code | **Impl-Polish** | "Fix pagination edge case", "Integrate payment with billing", "Handle error states in form" |
16
+ | Documentation updates — new/changed README sections, CLAUDE.md (or AGENTS.md on Codex CLI) updates, vault context.md/decisions.md narratives, ADR edits. Audience-aware (User/Dev/Vault). Gated on `docs-orchestrator.enabled` | **Docs** | "Update README for new --no-vault flag", "Write CLAUDE.md section for new hook (or AGENTS.md on Codex CLI)", "Append vault decisions.md entry for architecture change" |
17
+ | Write/update tests, lint fixes, security review, code simplification, type errors | **Quality** | "Add tests for auth module", "Fix TypeScript errors", "Security audit of new API" |
18
+ | Documentation updates, issue cleanup, commit preparation, SSOT refresh, changelog | **Finalization** | "Update README", "Close resolved issues", "Write session handover notes" |
19
+
20
+ **Disambiguation rules:**
21
+ - If a task involves BOTH exploration AND implementation → split it: Discovery agent reads/validates, Impl-Core agent implements. Create two separate task entries.
22
+ - If a task is "fix something from a previous session" (not from this session's Impl-Core) → classify as **Impl-Core** (it is new work for this session).
23
+ - A "write tests for new feature code being built this session" task is created ONLY when Discovery or a qa-strategist run reported a **named gap** — a concrete bug or regression the current suite would let through, stated as such. When that gap exists, classify the task as **Quality** (not Impl-Core); tests run after implementation. "Feature X was built" is NOT by itself evidence of test demand: with no named gap, no Quality task is created — do not synthesize one to give the role something to do. A dispatched `test-writer` may correspondingly report `no-tests-needed` as a SUCCESS status, not a failure.
24
+ - If unsure between Impl-Core and Impl-Polish → if the task is on the critical path (other tasks depend on it), it is **Impl-Core**. If independent polish, it is **Impl-Polish**.
25
+ - **Docs role** is only active when `docs-orchestrator.enabled: true` in Session Config. When disabled (default), documentation-update tasks fall into **Impl-Polish** (inline doc changes alongside code) or **Finalization** (standalone doc/SSOT updates) as today.
26
+
27
+ #### Step 1.8 Docs-role: Consuming the Phase 2.5 Emission Block
28
+
29
+ When `docs-orchestrator.enabled: true`, session-start Phase 2.5 emits a delimited block in the conversation context. Read and parse it before synthesizing Docs-role tasks:
30
+
31
+ **Locating the block:** Search the conversation context for the header `### Docs Planning Result (Phase 2.5)`. If the header is absent, Phase 2.5 was skipped — emit **0 Docs tasks** and do not fabricate any.
32
+
33
+ **Parsing rules (apply in document order):**
34
+ - `Audiences:` — comma-separated list of active audience identifiers (e.g., `user, dev`). Trim whitespace around each value.
35
+ - `Mode:` — single enum value: `warn`, `strict`, or `off`. Store as `$docs_mode`.
36
+ - `Docs-tasks-seed:` — multi-entry bullet list. Each top-level `- audience:` bullet is **one seed task**. Parse in document order; do not merge entries. Each seed task has:
37
+ - `audience:` — target audience (`user`, `dev`, or `vault`)
38
+ - `rationale:` — free-text description of what needs documenting
39
+
40
+ **Synthesizing Docs-role tasks:** For each seed task entry (in document order):
41
+ 1. Set `role: Docs`.
42
+ 2. Set `description` derived from the `rationale` field (paraphrase as an actionable imperative, e.g., "Document the new `--no-vault` flag in user-facing README").
43
+ 3. Set `audience` from the `audience` field.
44
+ 4. Set `target-pattern` by looking up the audience in the `Audiences & File Patterns` table in `skills/docs-orchestrator/audience-mapping.md`. Use the glob pattern listed there for the matched audience row.
45
+ 5. Resolve `subagent_type` per the Docs-role fast path in Step 1.5 point 4 above.
46
+
47
+ **If the block is absent:** Do not fabricate Docs tasks. The Docs role remains empty; apply the empty-role rule from Step 2.
48
+
49
+ - Housekeeping sessions: skip Steps 1.8, 2, and 3 — housekeeping is the **maintenance loop**, one coordinator-direct wave. `total-waves: 1` and the wave's `coordinatorDirect: true` come from the shape (`scripts/session-shape.mjs --session-type housekeeping`), not from this prose.
50
+ - No role classification — no wave-executor dispatch, no per-role agent sizing.
51
+ - **Default scope, in this order:**
52
+ 1. drift-check — `node skills/claude-md-drift-check/checker.mjs --mode warn`
53
+ 2. expired-learnings sweep — `node scripts/sweep-expired-learnings.mjs --json`, then `--apply --json` when the dry run reports `archived > 0`
54
+ 3. `/evolve analyze`
55
+ 4. `/reconcile`
56
+ 5. `/evolve dialectic` — dry-run first, then `--apply`
57
+ 6. `/memory-cleanup`
58
+ - Operator-selected housekeeping issues are appended AFTER the six maintenance items, in the order the operator picked them.
59
+ - **Why coordinator-direct:** four of the six are AUQ-gated, and `AskUserQuestion` does not exist inside a dispatched agent (`.claude/rules/ask-via-tool.md` AUQ-004) — a wave-executor dispatch would strand the decision. "Coordinator-direct" means no wave-executor, NOT zero subagents: item 5 dispatches the read-only `dialectic-deriver` subagent directly.
60
+ - Wave plan output uses: `### Wave 1: Housekeeping (coordinator-direct, 0 agents)`
61
+
62
+ Record the assigned role next to each task before proceeding to Step 2.
63
+
64
+ ### Docs-tasks persistence (for session-end Phase 3.2)
65
+
66
+ When `docs-orchestrator.enabled: true` AND the plan contains 1+ Docs tasks, session-plan MUST emit a machine-readable block **at the end of its plan output** (after the wave plan, before `Ready to execute?`). This block is the single source of truth (SSOT) consumed downstream:
67
+
68
+ - **wave-executor Pre-Wave 1b (STATE.md init):** reads this block and persists `docs-tasks: [...]` into STATE.md frontmatter.
69
+ - **session-end Phase 3.2 (docs verification):** reads `docs-tasks` back from STATE.md to verify each task produced a diff.
70
+
71
+ **Emit format:**
72
+
73
+ ```yaml
74
+ ### Docs Tasks (machine-readable)
75
+ docs-tasks:
76
+ - id: docs-1
77
+ audience: <user|dev|vault>
78
+ target-pattern: <glob from skills/docs-orchestrator/audience-mapping.md>
79
+ rationale: <verbatim rationale from Phase 2.5 seed>
80
+ wave: <wave number where this docs-writer agent is dispatched>
81
+ status: planned
82
+ - id: docs-2
83
+ ...
84
+ ```
85
+
86
+ **Field rules:**
87
+ - `id`: sequential index-based identifier (`docs-1`, `docs-2`, …). No UUID generation required.
88
+ - `audience`: one of `user`, `dev`, `vault`.
89
+ - `target-pattern`: the glob from `skills/docs-orchestrator/audience-mapping.md` for this audience row — do not invent patterns.
90
+ - `rationale`: copy the `rationale` text from the Phase 2.5 seed entry verbatim (do not paraphrase here).
91
+ - `wave`: the actual wave number assigned in Step 2 where the `docs-writer` agent for this task is dispatched.
92
+ - `status`: always `planned` at plan time. Terminal values are set by session-end Phase 3.2 per-task verification loop: `ok` (diff substantive), `partial` (diff has `<!-- REVIEW: source needed -->` markers), or `gap` (no matching diff). wave-executor does NOT perform intermediate status updates — `status: planned` remains until session-end writes the terminal value.
93
+
94
+ **Omission rule:** When `docs-orchestrator.enabled: false` OR there are 0 Docs tasks, do NOT emit the `### Docs Tasks (machine-readable)` block. Absence of the block signals to wave-executor and session-end that no docs verification is needed for this session.
95
+
96
+ ### Wave-Plan Mission Status (machine-readable)
97
+
98
+ When the wave plan contains 1 or more wave-plan items (i.e., for all non-empty plans), session-plan MUST emit a machine-readable mission-status block **at the end of its plan output** (after the Docs Tasks block if present, before `Ready to execute?`). This block is the SSOT consumed by wave-executor (for STATE.md persistence) and session-end Phase 1.9 (for enum-based classification).
99
+
100
+ - **wave-executor Pre-Wave 1b (STATE.md init):** reads this block and persists `mission-status: [...]` into STATE.md frontmatter via `writeMissionStatus` from `scripts/lib/state-md.mjs`.
101
+ - **session-end Phase 1.9:** reads `mission-status` back from STATE.md frontmatter via `parseMissionStatus` to classify items into the 1.1–1.4 buckets using enum values.
102
+
103
+ **Emit format:**
104
+
105
+ ```yaml
106
+ ### Wave-Plan Mission Status (machine-readable)
107
+ mission-status:
108
+ - id: m-1
109
+ task: <task description from wave-plan item>
110
+ wave: <N>
111
+ status: brainstormed
112
+ - id: m-2
113
+ task: <task description from wave-plan item>
114
+ wave: <N>
115
+ status: brainstormed
116
+ ```
117
+
118
+ **Field rules:**
119
+ - `id`: sequential `m-N` identifier. No UUID generation required.
120
+ - `task`: verbatim task description from the wave-plan item (do not paraphrase).
121
+ - `wave`: the wave number where this task is dispatched.
122
+ - `status`: always `brainstormed` at plan emission. Terminal values are updated at gate transitions by wave-executor: `brainstormed` → `validated` (user confirms via `/go`) → `in-dev` (agent dispatched) → `testing` (Quality wave) → `completed` (Quality gate green). session-end Phase 1.9 reads the current value to classify the item.
123
+
124
+ **Transition gates (summary):**
125
+ At plan time, all items start at `brainstormed`. When the user runs `/go` to approve the plan, wave-executor updates each item to `validated`. When an agent for a wave-plan item is dispatched, wave-executor updates that item to `in-dev`. When the Quality wave begins, items from prior waves move to `testing`. When the Quality gate passes, items finalize at `completed`. Rollback to `brainstormed` is permitted from any state. This ordering is **coordinator convention, not a mechanical gate** — nothing validates a transition before it is written (see "Default and transitions" below).
126
+
127
+ **Omission rule:** When the plan has 0 wave-plan items (e.g., pure express-path coord-direct with no sub-agent tasks), do NOT emit the `### Wave-Plan Mission Status (machine-readable)` block.
128
+
129
+ ### Mission-Status Enum (#340)
130
+
131
+ Every wave-plan item carries a `status` field drawn from a 5-value enum. The field is always present on items emitted in the `### Wave-Plan Mission Status (machine-readable)` block (see below). It is also the value persisted in STATE.md frontmatter and read back by session-end Phase 1.9 for enum-based classification.
132
+
133
+ #### Enum values
134
+
135
+ | Status | Meaning | Set when |
136
+ |---|---|---|
137
+ | `brainstormed` | Draft item from `/plan`, not yet user-confirmed | Plan emitted by session-plan (all items start here) |
138
+ | `validated` | User confirmed via AUQ in session-plan (`/go` approval) | wave-executor: user runs `/go` to approve the wave plan |
139
+ | `in-dev` | Agent picked up the task this wave | wave-executor: agent dispatched for this item |
140
+ | `testing` | Implementation done, tests passing for this task | wave-executor: Quality wave begins for this item's work |
141
+ | `completed` | Quality-Lite green for this task's wave | wave-executor: Quality gate passes for this item |
142
+
143
+ #### Default and transitions
144
+
145
+ - **Default at plan creation:** `brainstormed` — all items start here.
146
+ - **Transitions are coordinator-level orchestration** (not inside individual agent prompts). See `skills/wave-executor/SKILL.md` "Mission-Status Updates (#340)" for when each transition fires.
147
+ - **Rollback:** any item may return to `brainstormed` from any state (e.g. if work is discarded or re-planned).
148
+ - **No mechanical validation — by design.** The `status` values come from the 5-value enum in the table above, but nothing checks a transition before it is written. `setMissionStatus` (`scripts/lib/state-md/mission-status.mjs`) mirrors whatever string it is handed onto BOTH the body section and the frontmatter array, deliberately without an enum gate: gating it would reintroduce the exact body-says-X/frontmatter-says-Y divergence that sync exists to remove. An out-of-enum value therefore lands visibly on both surfaces instead of being silently rejected on one. Keeping the enum honest is the coordinator's job.
149
+
150
+ #### Status field in wave-plan items
151
+
152
+ Every item in the wave plan output carries an implicit `status: brainstormed` at plan time. The `### Wave-Plan Mission Status (machine-readable)` block below (emitted at the end of the plan output) is the machine-readable form that wave-executor and session-end Phase 1.9 consume. session-plan does NOT write STATUS transitions — it only emits the initial `brainstormed` values.
@@ -11,30 +11,23 @@ For each wave, define agents with:
11
11
  Acceptance: [what "done" looks like — measurable]
12
12
  Tools needed: [Read, Write, Edit, Bash, Grep, Glob, etc.]
13
13
  Dependencies: [output from which prior role/agent]
14
- Isolation: [worktree|none — read from Session Config, default: worktree for feature/deep, none for housekeeping]
15
- MaxTurns: [read from Session Config max-turns, default: housekeeping=8, feature=15, deep=25]
14
+ Isolation: [worktree|none — copied verbatim from this wave's `waves[].isolation` entry in the shape output (`scripts/session-shape.mjs`); do not compute by hand]
15
+ MaxTurns: [this wave's `maxTurns` from `scripts/session-shape.mjs`; do not compute by hand]
16
16
  status: brainstormed
17
17
  ```
18
18
 
19
- - `Isolation: worktree` means the wave-executor will pass `isolation: "worktree"` to the Agent tool, giving each agent its own git worktree copy
19
+ - `Isolation: worktree` means the wave-executor will pass `isolation: "worktree"` to the Agent tool, giving each agent its own git worktree copy. Each wave's `isolation` (`worktree`/`none`) AND its paired `enforcement` (`strict`/`warn`/`off`) are computed per-wave from that wave's `agentCap` and the session type — the graduated rule (`resolveIsolation`/`resolveEnforcement`, issue #194: ≤2 agents → `none`, ≥5 agents → `worktree`, 3-4 agents → `none` for housekeeping else `worktree`, an explicit Session Config `isolation` value always wins) lives in `scripts/lib/wave-sizing.mjs`, not in `session-shape.mjs` itself — `session-shape.mjs` only calls it once per wave row and copies the two results onto that wave's record.
20
20
  - `MaxTurns` is enforced via the agent prompt — wave-executor includes a turn limit instruction in each agent's prompt
21
21
  - `status` is the mission-status enum value for this wave-plan item (#340). Always `brainstormed` in the initial plan. Wave-executor updates it at gate transitions (validated → in-dev → testing → completed). Rollback to `brainstormed` is allowed from any state. The five values are listed in `SKILL.md` § Mission-Status Enum; nothing validates them mechanically — `setMissionStatus` writes the string it is given to both STATE.md surfaces on purpose, so keeping the value in-enum is the coordinator's job.
22
22
  - The wave-plan item's `id` becomes the `taskId` every `setMissionStatus` call for this item uses, and `setMissionStatus` REFUSES ids outside `[a-z][a-z0-9]*(?:-[a-z0-9]+)*-\d+` (lowercase segments, single hyphens, trailing bare digits) with `refused: 'id-grammar'` and a stderr WARN — nothing is written. Mint ids matching it: `m-1`, `docs-2`, `w2-1`, `w2-a-10` all accepted; `w2-a10`, `w3-p2`, `W3-I1`, `Docs_2` all refused.
23
23
 
24
24
  > **Deconfliction rule:** Before finalizing agent specs for a wave, verify that no two agents in the same wave list overlapping `Files:` paths. If overlap is found, either merge the agents into one or move one task to a later wave. Two agents editing the same file in parallel causes merge conflicts that require manual resolution.
25
25
 
26
- ## Agent Count by Session Type
26
+ ## Agent Count and Turn Budget per Wave
27
27
 
28
- | Session Type | Discovery | Impl-Core | Impl-Polish | Quality | Finalization |
29
- |-------------|-----------|-----------|-------------|---------|-------------|
30
- | housekeeping | — | 1-6* | — | — | — |
31
- | feature | 4-6 | 6 | 4-6 | 4 | 2 |
32
- | deep | 6-8 | 6-10 | 6-8 | 6 | 2-4 |
28
+ There is no count table here. Both numbers come from the session shape resolved once at plan time (`SKILL.md` § Role-to-Wave Mapping):
33
29
 
34
- Read `agents-per-wave` from Session Config to cap the maximum.
30
+ - **Agent ceiling** — that wave's `agentCap` (already capped by the Session Config `agents-per-wave` value; `agentCapRaw` is the value before that ceiling).
31
+ - **Turn budget** — that wave's `maxTurns` (`null` on a `coordinatorDirect: true` wave, which dispatches no agents).
35
32
 
36
- > **The Quality column is a CAP, not a target.** Quality capacity is need-gated: the effective count is `min(<column cap>, ceil((HIGH + MED gaps from the most recent qa-strategist run) / 3))`. 0 gaps → 0 test-writing tasks and the wave is skipped (the read-only review panel is unaffected); no qa-strategist signal at all → a conservative 1-2, never the blind cap. Full rule: `SKILL.md` § Agent Count by Tier footnote.
37
-
38
- > **Note:** For feature and deep sessions, prefer the complexity-based agent counts from Step 3. This table provides defaults when complexity scoring is skipped (housekeeping) or as a fallback.
39
-
40
- > \* Housekeeping sessions use single-wave serial execution (see wave-executor). Agent counts are for the single consolidated wave, not per-role.
33
+ > **The Quality wave's cap is a CAP, not a target.** Quality capacity is need-gated: the effective count is `min(<the wave's agentCap>, ceil((HIGH + MED gaps from the most recent qa-strategist run) / 3))`. 0 gaps → 0 test-writing tasks and the wave is skipped (the read-only review panel is unaffected); no qa-strategist signal at all → a conservative 1-2, never the blind cap. The shape marks this wave `qualityEarned: true`. Full rule: `SKILL.md` § Agent Count by Tier footnote.