session-orchestrator 3.21.0 → 3.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (345) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/.cursor/commands/autopilot-multi.md +14 -0
  5. package/.cursor/commands/autopilot.md +14 -0
  6. package/.cursor/commands/bootstrap.md +14 -0
  7. package/.cursor/commands/brainstorm.md +14 -0
  8. package/.cursor/commands/close.md +13 -0
  9. package/.cursor/commands/contract-version-bump.md +14 -0
  10. package/.cursor/commands/debug.md +14 -0
  11. package/.cursor/commands/discovery.md +14 -0
  12. package/.cursor/commands/dispatcher.md +14 -0
  13. package/.cursor/commands/eli5.md +14 -0
  14. package/.cursor/commands/eval.md +14 -0
  15. package/.cursor/commands/evolve.md +14 -0
  16. package/.cursor/commands/go.md +14 -0
  17. package/.cursor/commands/grill.md +14 -0
  18. package/.cursor/commands/harness-audit.md +13 -0
  19. package/.cursor/commands/journey-audit.md +14 -0
  20. package/.cursor/commands/memory-cleanup.md +14 -0
  21. package/.cursor/commands/persona-panel.md +14 -0
  22. package/.cursor/commands/plan.md +14 -0
  23. package/.cursor/commands/portfolio.md +14 -0
  24. package/.cursor/commands/reconcile.md +14 -0
  25. package/.cursor/commands/release.md +14 -0
  26. package/.cursor/commands/repo-audit.md +13 -0
  27. package/.cursor/commands/session.md +14 -0
  28. package/.cursor/commands/spinout.md +14 -0
  29. package/.cursor/commands/sunset-review.md +14 -0
  30. package/.cursor/commands/templates-ack.md +14 -0
  31. package/.cursor/commands/test.md +14 -0
  32. package/.cursor/hooks.json +60 -0
  33. package/.cursor/rules/000-session-orchestrator.mdc +11 -2
  34. package/.cursor/rules/010-session-workflow.mdc +9 -1
  35. package/.cursor/rules/020-quality-gates.mdc +1 -1
  36. package/.cursor/rules/030-wave-execution.mdc +1 -1
  37. package/.cursor/rules/040-discovery.mdc +6 -6
  38. package/.cursor/rules/050-plan.mdc +10 -10
  39. package/.cursor/rules/070-gitlab-ops.mdc +73 -57
  40. package/.cursor/rules/080-ecosystem-health.mdc +7 -7
  41. package/.cursor/skills/architecture/SKILL.md +13 -0
  42. package/.cursor/skills/autopilot/SKILL.md +12 -0
  43. package/.cursor/skills/bootstrap/SKILL.md +12 -0
  44. package/.cursor/skills/brainstorm/SKILL.md +13 -0
  45. package/.cursor/skills/claude-md-drift-check/SKILL.md +13 -0
  46. package/.cursor/skills/contract-version-bump/SKILL.md +12 -0
  47. package/.cursor/skills/convergence-monitoring/SKILL.md +12 -0
  48. package/.cursor/skills/daily/SKILL.md +12 -0
  49. package/.cursor/skills/debug/SKILL.md +13 -0
  50. package/.cursor/skills/discovery/SKILL.md +13 -0
  51. package/.cursor/skills/dispatcher/SKILL.md +13 -0
  52. package/.cursor/skills/docs-orchestrator/SKILL.md +13 -0
  53. package/.cursor/skills/domain-model/SKILL.md +13 -0
  54. package/.cursor/skills/ecosystem-health/SKILL.md +13 -0
  55. package/.cursor/skills/eli5/SKILL.md +13 -0
  56. package/.cursor/skills/eval/SKILL.md +12 -0
  57. package/.cursor/skills/evolve/SKILL.md +13 -0
  58. package/.cursor/skills/frontmatter-guard/SKILL.md +13 -0
  59. package/.cursor/skills/gitlab-ops/SKILL.md +13 -0
  60. package/.cursor/skills/gitlab-portfolio/SKILL.md +13 -0
  61. package/.cursor/skills/grill/SKILL.md +13 -0
  62. package/.cursor/skills/hook-development/SKILL.md +13 -0
  63. package/.cursor/skills/journey-audit/SKILL.md +13 -0
  64. package/.cursor/skills/mcp-builder/SKILL.md +13 -0
  65. package/.cursor/skills/memory-cleanup/SKILL.md +12 -0
  66. package/.cursor/skills/mode-selector/SKILL.md +13 -0
  67. package/.cursor/skills/npm-publish/SKILL.md +12 -0
  68. package/.cursor/skills/peekaboo-driver/SKILL.md +13 -0
  69. package/.cursor/skills/persona-panel/SKILL.md +12 -0
  70. package/.cursor/skills/plan/SKILL.md +13 -0
  71. package/.cursor/skills/playwright-driver/SKILL.md +13 -0
  72. package/.cursor/skills/quality-gates/SKILL.md +13 -0
  73. package/.cursor/skills/reconcile/SKILL.md +12 -0
  74. package/.cursor/skills/repo-audit/SKILL.md +13 -0
  75. package/.cursor/skills/session-end/SKILL.md +13 -0
  76. package/.cursor/skills/session-plan/SKILL.md +13 -0
  77. package/.cursor/skills/session-start/SKILL.md +13 -0
  78. package/.cursor/skills/skill-creator/SKILL.md +13 -0
  79. package/.cursor/skills/spinout/SKILL.md +12 -0
  80. package/.cursor/skills/sunset-review/SKILL.md +13 -0
  81. package/.cursor/skills/test-runner/SKILL.md +13 -0
  82. package/.cursor/skills/tmux-layout/SKILL.md +13 -0
  83. package/.cursor/skills/ubiquitous-language/SKILL.md +13 -0
  84. package/.cursor/skills/using-orchestrator/SKILL.md +13 -0
  85. package/.cursor/skills/vault-mirror/SKILL.md +13 -0
  86. package/.cursor/skills/vault-sync/SKILL.md +13 -0
  87. package/.cursor/skills/wave-executor/SKILL.md +13 -0
  88. package/.cursor/skills/write-executable-plan/SKILL.md +13 -0
  89. package/.mcp.json +4 -1
  90. package/CHANGELOG.md +269 -0
  91. package/README.md +18 -15
  92. package/agents/AGENTS.md +23 -4
  93. package/agents/code-implementer.md +2 -1
  94. package/agents/db-specialist.md +2 -1
  95. package/agents/docs-writer.md +3 -1
  96. package/agents/eval-judge.md +1 -1
  97. package/agents/memory-proposal-collector.md +6 -4
  98. package/agents/session-reviewer.md +7 -1
  99. package/agents/test-writer.md +2 -1
  100. package/agents/ui-developer.md +2 -1
  101. package/commands/bootstrap.md +2 -2
  102. package/commands/close.md +3 -1
  103. package/commands/eli5.md +33 -0
  104. package/commands/go.md +1 -1
  105. package/commands/journey-audit.md +43 -0
  106. package/commands/release.md +5 -3
  107. package/commands/test.md +2 -2
  108. package/docs/USER-GUIDE.md +2 -2
  109. package/docs/ci-setup.md +14 -0
  110. package/docs/codex-setup.md +64 -0
  111. package/docs/components.md +7 -6
  112. package/docs/cursor-setup.md +26 -47
  113. package/docs/events-schema.md +76 -4
  114. package/docs/github-mirror-protection.md +197 -0
  115. package/docs/pi-setup.md +2 -0
  116. package/docs/rule-authoring.md +3 -1
  117. package/docs/scope-collision-guard.md +52 -5
  118. package/docs/session-config-reference.md +57 -12
  119. package/docs/session-config-template.md +4 -3
  120. package/docs/telemetry.md +22 -0
  121. package/hooks/_lib/lock-bootstrap.mjs +26 -16
  122. package/hooks/_lib/vcs-create-matcher.mjs +397 -38
  123. package/hooks/enforce-scope.mjs +64 -0
  124. package/hooks/hooks-codex.json +1 -1
  125. package/hooks/hooks-cursor.json +201 -20
  126. package/hooks/hooks-pi.json +1 -1
  127. package/hooks/hooks.json +12 -2
  128. package/hooks/on-session-end.mjs +237 -104
  129. package/hooks/on-session-start.mjs +404 -110
  130. package/hooks/on-stop.mjs +48 -9
  131. package/hooks/post-subagent-discovery-validator.mjs +34 -3
  132. package/hooks/post-tool-batch-wave-signal.mjs +11 -2
  133. package/hooks/pre-auq-clarity.mjs +787 -0
  134. package/hooks/pre-bash-issue-budget.mjs +133 -21
  135. package/hooks/pre-bash-sessions-ledger-guard.mjs +159 -0
  136. package/hooks/pre-bash-staging-fence.mjs +4 -0
  137. package/hooks/pre-task-scope-disjoint.mjs +368 -35
  138. package/hooks/skill-invocation-telemetry.mjs +21 -10
  139. package/monitors/monitors.json +6 -0
  140. package/package.json +3 -1
  141. package/pi/prompts/eli5.md +12 -0
  142. package/pi/prompts/journey-audit.md +12 -0
  143. package/rules/_index.md +9 -1
  144. package/rules/always-on/ask-via-tool.md +62 -0
  145. package/rules/always-on/bash-harness-pitfalls.md +168 -0
  146. package/rules/always-on/build-value.md +47 -0
  147. package/rules/always-on/cross-session-messaging.md +59 -0
  148. package/rules/always-on/loop-and-monitor.md +221 -0
  149. package/rules/always-on/parallel-sessions.md +142 -12
  150. package/rules/always-on/receiving-review.md +108 -0
  151. package/rules/always-on/test-value.md +40 -0
  152. package/rules/always-on/verification-before-completion.md +77 -0
  153. package/scripts/archive-closed-prds.mjs +258 -18
  154. package/scripts/auq-audit.mjs +825 -0
  155. package/scripts/autopilot.mjs +12 -8
  156. package/scripts/backfill-evidence-digest.mjs +376 -0
  157. package/scripts/cursor-install.mjs +89 -48
  158. package/scripts/export-hw-learnings.mjs +143 -2
  159. package/scripts/express-path.mjs +299 -0
  160. package/scripts/generate-cursor-adapter.mjs +253 -0
  161. package/scripts/github-protection-audit.mjs +358 -0
  162. package/scripts/lib/auq/clarity.mjs +1314 -0
  163. package/scripts/lib/auq/parse.mjs +1006 -0
  164. package/scripts/lib/auq/schema.mjs +1457 -0
  165. package/scripts/lib/autopilot/worktree-pipeline.mjs +240 -16
  166. package/scripts/lib/build-live-signals.mjs +24 -5
  167. package/scripts/lib/ci-status-banner.mjs +221 -68
  168. package/scripts/lib/command-blocker.mjs +70 -0
  169. package/scripts/lib/config/dispatcher-autonomy-capture.mjs +32 -9
  170. package/scripts/lib/config/reconcile.mjs +79 -4
  171. package/scripts/lib/config/section-extractor.mjs +235 -36
  172. package/scripts/lib/config/vault-integration.mjs +12 -1
  173. package/scripts/lib/config-schema.mjs +9 -1
  174. package/scripts/lib/config.mjs +57 -6
  175. package/scripts/lib/convergence-monitor.mjs +13 -2
  176. package/scripts/lib/cursor-hook-bridge.mjs +443 -0
  177. package/scripts/lib/dispatcher/cli.mjs +2 -2
  178. package/scripts/lib/dispatcher/rank.mjs +4 -7
  179. package/scripts/lib/express-path.mjs +327 -0
  180. package/scripts/lib/file-lock.mjs +22 -4
  181. package/scripts/lib/gates/gate-full.mjs +84 -11
  182. package/scripts/lib/gates/gate-helpers.mjs +93 -21
  183. package/scripts/lib/git-config-drift.mjs +134 -5
  184. package/scripts/lib/host-identity.mjs +247 -2
  185. package/scripts/lib/instruction-budget-guard.mjs +31 -1
  186. package/scripts/lib/io.mjs +239 -0
  187. package/scripts/lib/issue-budget.mjs +284 -31
  188. package/scripts/lib/learnings/io.mjs +55 -10
  189. package/scripts/lib/learnings/schema.mjs +95 -28
  190. package/scripts/lib/lock-reaper.mjs +7 -1
  191. package/scripts/lib/locks/staging-fence-lock.mjs +5 -1
  192. package/scripts/lib/locks/state-md-lock.mjs +8 -1
  193. package/scripts/lib/memory-banner.mjs +5 -2
  194. package/scripts/lib/memory-paths.mjs +15 -6
  195. package/scripts/lib/mode-selector/scoring.mjs +53 -6
  196. package/scripts/lib/owner-interview.mjs +78 -32
  197. package/scripts/lib/peer-discovery.mjs +73 -22
  198. package/scripts/lib/platform.mjs +72 -9
  199. package/scripts/lib/plugin-root.mjs +143 -19
  200. package/scripts/lib/project-hygiene.mjs +104 -4
  201. package/scripts/lib/quality-gate.mjs +271 -13
  202. package/scripts/lib/reconcile/emitter.mjs +87 -19
  203. package/scripts/lib/reconcile/engine.mjs +281 -13
  204. package/scripts/lib/reconcile/idempotency.mjs +102 -1
  205. package/scripts/lib/reconcile/renderer.mjs +165 -7
  206. package/scripts/lib/reconcile/sanitize.mjs +40 -17
  207. package/scripts/lib/reconcile/writer.mjs +415 -84
  208. package/scripts/lib/resource-probe/evaluate.mjs +330 -149
  209. package/scripts/lib/resource-probe/probe-platform.mjs +35 -0
  210. package/scripts/lib/resource-probe.mjs +18 -2
  211. package/scripts/lib/rule-loader.mjs +37 -2
  212. package/scripts/lib/rules-sync.mjs +51 -8
  213. package/scripts/lib/scope-gate.mjs +90 -0
  214. package/scripts/lib/session-close-backfill.mjs +369 -28
  215. package/scripts/lib/session-discovery.mjs +13 -3
  216. package/scripts/lib/session-end/phase-skip.mjs +37 -4
  217. package/scripts/lib/session-end/worktree-cleanup.mjs +154 -7
  218. package/scripts/lib/session-id.mjs +30 -14
  219. package/scripts/lib/session-identity/own-session.mjs +159 -0
  220. package/scripts/lib/session-lock.mjs +85 -30
  221. package/scripts/lib/session-schema/normalizer.mjs +70 -3
  222. package/scripts/lib/session-schema/validator.mjs +40 -0
  223. package/scripts/lib/session-start-probes.mjs +608 -0
  224. package/scripts/lib/session-transition.mjs +277 -0
  225. package/scripts/lib/sessions-staleness-banner.mjs +124 -57
  226. package/scripts/lib/spiral-carryover.mjs +111 -9
  227. package/scripts/lib/state-md/frontmatter-mutators.mjs +41 -8
  228. package/scripts/lib/state-md/mission-status.mjs +467 -72
  229. package/scripts/lib/state-md/yaml-parser.mjs +145 -16
  230. package/scripts/lib/state-md.mjs +12 -2
  231. package/scripts/lib/telemetry/sync.mjs +46 -8
  232. package/scripts/lib/validate/check-agents.mjs +66 -0
  233. package/scripts/lib/validate/check-auq-clarity.mjs +274 -0
  234. package/scripts/lib/validate/check-cursor-adapter.mjs +102 -0
  235. package/scripts/lib/validate/check-dead-bridge.mjs +24 -2
  236. package/scripts/lib/validate/check-doc-cli-commands.mjs +16 -32
  237. package/scripts/lib/validate/check-hooks-symmetry.mjs +59 -63
  238. package/scripts/lib/validate/check-playwright-mcp-canary.mjs +13 -22
  239. package/scripts/lib/validate/check-plugin-monitors.mjs +10 -4
  240. package/scripts/lib/validate/check-rules.mjs +153 -9
  241. package/scripts/lib/validate/check-test-value-bans.mjs +165 -17
  242. package/scripts/lib/validate/check-unwired-features.mjs +340 -32
  243. package/scripts/lib/validate/repo-files.mjs +275 -0
  244. package/scripts/lib/validate-vendored-rules.mjs +229 -7
  245. package/scripts/lib/vault-backfill/glab.mjs +91 -58
  246. package/scripts/lib/vault-backfill/manifest.mjs +28 -8
  247. package/scripts/lib/vault-mirror/process.mjs +99 -43
  248. package/scripts/lib/vault-mirror/telemetry.mjs +210 -0
  249. package/scripts/lib/vault-staleness-banner.mjs +76 -6
  250. package/scripts/lib/vault-status/board-writer.mjs +211 -10
  251. package/scripts/lib/vault-status/narrative-mirror.mjs +188 -8
  252. package/scripts/lib/vcs-repo-spec.mjs +182 -13
  253. package/scripts/lib/wave-executor/foreign-dispatch.mjs +832 -0
  254. package/scripts/lib/wave-resource-gate.mjs +67 -73
  255. package/scripts/lib/wave-transcript-tail.mjs +869 -0
  256. package/scripts/materialize-wave-scope.mjs +478 -0
  257. package/scripts/mcp-server.sh +11 -2
  258. package/scripts/parse-config.mjs +65 -0
  259. package/scripts/release.mjs +443 -122
  260. package/scripts/run-quality-gate.mjs +14 -0
  261. package/scripts/token-audit.sh +9 -2
  262. package/scripts/validate-plugin.mjs +6 -0
  263. package/scripts/validate-wave-scope.mjs +73 -1
  264. package/scripts/vault-backfill.mjs +32 -5
  265. package/scripts/vault-mirror.mjs +203 -34
  266. package/skills/_shared/monitor-patterns.md +31 -5
  267. package/skills/_shared/parallel-aware-auq.md +31 -25
  268. package/skills/_shared/parallel-aware-preamble.md +35 -4
  269. package/skills/_shared/platform-tools.md +11 -5
  270. package/skills/_shared/state-ownership.md +61 -8
  271. package/skills/autopilot/SKILL.md +5 -1
  272. package/skills/bootstrap/SKILL.md +5 -4
  273. package/skills/bootstrap/_shared-template.md +18 -10
  274. package/skills/bootstrap/deep-template.md +10 -6
  275. package/skills/bootstrap/fast-template.md +15 -8
  276. package/skills/bootstrap/standard-template.md +10 -6
  277. package/skills/brainstorm/SKILL.md +18 -18
  278. package/skills/brainstorm/soul.md +12 -0
  279. package/skills/claude-md-drift-check/checker.mjs +39 -11
  280. package/skills/discovery/SKILL.md +28 -24
  281. package/skills/dispatcher/SKILL.md +1 -1
  282. package/skills/eli5/SKILL.md +43 -0
  283. package/skills/evolve/SKILL.md +8 -9
  284. package/skills/gitlab-ops/SKILL.md +30 -26
  285. package/skills/grill/SKILL.md +6 -6
  286. package/skills/grill/soul.md +16 -0
  287. package/skills/journey-audit/SKILL.md +269 -0
  288. package/skills/memory-cleanup/SKILL.md +2 -2
  289. package/skills/npm-publish/SKILL.md +4 -4
  290. package/skills/peekaboo-driver/SKILL.md +18 -6
  291. package/skills/persona-panel/SKILL.md +1 -1
  292. package/skills/plan/SKILL.md +18 -16
  293. package/skills/plan/mode-feature.md +1 -1
  294. package/skills/plan/mode-new.md +35 -23
  295. package/skills/plan/soul.md +12 -0
  296. package/skills/reconcile/SKILL.md +44 -4
  297. package/skills/session-end/SKILL.md +70 -24
  298. package/skills/session-end/metrics-collection.md +7 -4
  299. package/skills/session-end/phase-3-6-tail.md +48 -5
  300. package/skills/session-end/phase-3-7a-recommendations.md +16 -2
  301. package/skills/session-plan/SKILL.md +6 -1
  302. package/skills/session-plan/wave-template.md +1 -0
  303. package/skills/session-start/SKILL.md +96 -48
  304. package/skills/session-start/phase-2-5-docs-planning.md +8 -8
  305. package/skills/session-start/phase-4-5-resource-health.md +82 -19
  306. package/skills/session-start/phase-7-5-mode-selector.md +15 -3
  307. package/skills/session-start/phase-8-5-express-path.md +77 -12
  308. package/skills/session-start/soul.md +110 -0
  309. package/skills/test-runner/SKILL.md +2 -2
  310. package/skills/using-orchestrator/SKILL.md +1 -1
  311. package/skills/vault-sync/validator.mjs +31 -0
  312. package/skills/wave-executor/SKILL.md +4 -2
  313. package/skills/wave-executor/circuit-breaker.md +34 -9
  314. package/skills/wave-executor/wave-loop.md +129 -24
  315. package/skills/write-executable-plan/SKILL.md +6 -6
  316. package/templates/_shared/journey-manifest.md +110 -0
  317. package/scripts/tests/fixtures/fetch-baseline/sample-rule.md +0 -8
  318. package/skills/vault-sync/tests/fixtures/archive-test-vault/90-archive/bad-archived.md +0 -8
  319. package/skills/vault-sync/tests/fixtures/archive-test-vault/_meta/.gitkeep +0 -0
  320. package/skills/vault-sync/tests/fixtures/archive-test-vault/live-note.md +0 -8
  321. package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/_meta/.gitkeep +0 -0
  322. package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/bad-type.md +0 -8
  323. package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/good-note.md +0 -8
  324. package/skills/vault-sync/tests/fixtures/clean-vault/.obsidian/config.md +0 -8
  325. package/skills/vault-sync/tests/fixtures/clean-vault/01-projects/foo/projects-baseline.md +0 -10
  326. package/skills/vault-sync/tests/fixtures/clean-vault/03-daily/daily-2026-04-13.md +0 -8
  327. package/skills/vault-sync/tests/fixtures/clean-vault/README.md +0 -3
  328. package/skills/vault-sync/tests/fixtures/clean-vault/hello-world.md +0 -11
  329. package/skills/vault-sync/tests/fixtures/dangling-link-vault/_meta/.gitkeep +0 -0
  330. package/skills/vault-sync/tests/fixtures/dangling-link-vault/has-dangling.md +0 -9
  331. package/skills/vault-sync/tests/fixtures/dangling-link-vault/real-target.md +0 -8
  332. package/skills/vault-sync/tests/fixtures/empty-vault/_meta/.gitkeep +0 -0
  333. package/skills/vault-sync/tests/fixtures/missing-field-vault/_meta/.gitkeep +0 -0
  334. package/skills/vault-sync/tests/fixtures/missing-field-vault/missing-id.md +0 -7
  335. package/skills/vault-sync/tests/fixtures/nested-tag-vault/03-daily/daily-2026-04-13.md +0 -9
  336. package/skills/vault-sync/tests/fixtures/nested-tag-vault/_meta/.gitkeep +0 -0
  337. package/skills/vault-sync/tests/fixtures/nested-tag-vault/nested-tags-note.md +0 -11
  338. package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/README.md +0 -3
  339. package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/_MOC.md +0 -3
  340. package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/_meta/.gitkeep +0 -0
  341. package/skills/vault-sync/tests/fixtures/with-moc-vault/_MOC.md +0 -11
  342. package/skills/vault-sync/tests/fixtures/with-moc-vault/_meta/.gitkeep +0 -0
  343. package/skills/vault-sync/tests/fixtures/with-moc-vault/hello-world.md +0 -11
  344. package/skills/vault-sync/tests/schema-drift.test.mjs +0 -133
  345. package/templates/_shared/rules/parallel-sessions.md +0 -77
@@ -4,13 +4,57 @@
4
4
 
5
5
  After the user confirms the session type and scope via the Q&A above, evaluate whether the **Express Path** applies before handing off to session-plan. The express path collapses the full 5-wave plan into a single coordinator-direct phase for lightweight sessions.
6
6
 
7
- **Activation conditions (ALL three must be true):**
7
+ **Do not evaluate these conditions by hand run the CLI (#1119, #1146).**
8
+
9
+ ```bash
10
+ node scripts/express-path.mjs \
11
+ --repo-root "$PWD" \
12
+ --session-type <housekeeping|feature|deep> \
13
+ --task-count <N> \
14
+ --parallel-agents <true|false>
15
+ ```
16
+
17
+ stdout is one JSON line — `{"activated":<bool>,"reasons":[…]}`. The activation banner and every
18
+ diagnostic go to stderr. Exit `0` means the evaluation COMPLETED, activation and refusal alike:
19
+ branch on the `activated` field, never on the exit code. Exit `1` is an input error (a missing or
20
+ invalid `--session-type` / `--task-count` / `--repo-root`), exit `2` an unreadable config file.
21
+ `--parallel-agents` is optional and tri-state — omitting it asserts nothing and leaves the field
22
+ out of the record, which is NOT the same claim as `false`.
23
+
24
+ `--repo-root` is required and is never defaulted from `SO_PROJECT_DIR` (#941): an ambient
25
+ destination once put a synthetic record into the operator's real fleet ledger.
26
+
27
+ Until #1146 this block was a fenced `js` snippet with an `import` — prose no process runs. Measured
28
+ at HEAD `01eb35d`: `rg -n "evaluateExpressPath" scripts hooks` returned the definition and nothing
29
+ else, so the module had ZERO production callers. A hook cannot close that gap either — `sessionType`
30
+ and `taskCount` exist only AFTER the Phase 8 Q&A, and no hook event fires there. The caller has to
31
+ be something the coordinator RUNS at this point in the flow, which is what `scripts/express-path.mjs`
32
+ is.
33
+
34
+ `evaluateExpressPath` (behind the CLI) makes the decision AND records it as `orchestrator.express_path.evaluated`
35
+ — on **every** evaluation, activation and refusal alike. That is the whole point: until #1119 the
36
+ conditions below were prose only, `scripts/lib/config.mjs` discarded `express-path` **even when the
37
+ block was present** (measured: 88 keys emitted, none of them this one), and the ledger held **0**
38
+ express-path events across its entire history. Whether the path ever fired was unanswerable.
39
+ Re-deriving the conditions in a coordinator turn re-opens exactly that hole; the conditions below
40
+ are the specification the module implements, not a second implementation.
41
+
42
+ `reasons` carries the blocking codes when `activated: false` and the satisfied ones when `true`.
43
+ Nothing short-circuits, so a refusal names **every** blocker — a reader can see whether trimming
44
+ the issue list alone would have helped. Unmeasured inputs are omitted from the payload, never
45
+ written as `0`/`false`, and an unmeasured `sessionType`/`taskCount` fails CLOSED.
46
+
47
+ **Activation conditions (the module's specification):**
8
48
 
9
49
  1. `express-path.enabled` is `true` in Session Config (default: `true` — opt-in by default, opt-out via `express-path.enabled: false`).
10
50
  2. Session type is `housekeeping` (the user confirmed `housekeeping` in Phase 8).
11
51
  3. Agreed issue scope is ≤ 3 issues AND no parallel agents are required (i.e., tasks are sequential, no wave decomposition needed).
12
52
 
13
- **Backward compat:** when `express-path.enabled: false`, this evaluation is skipped entirely and the normal 5-wave session-plan flow runs as before.
53
+ > Condition 3 carries **two** clauses, so the module takes **four** inputs, not three. The
54
+ > condition matrix below and `docs/session-config-reference.md` both list a `housekeeping` / 1–3 /
55
+ > `enabled: true` row that still does NOT activate, because parallel agents are required.
56
+
57
+ **Backward compat:** when `express-path.enabled: false`, the normal 5-wave session-plan flow runs as before. Note that the EVALUATION itself is not skipped — run the CLI regardless, and it returns `{"activated":false,"reasons":["disabled-by-config"]}` and records that refusal. An opt-out that leaves no record is indistinguishable in the ledger from an evaluation that never happened, which is the #1119 hole.
14
58
 
15
59
  **Historical context:** The 13 prior coordinator-direct sessions documented in `CLAUDE.md` (or `AGENTS.md` on Codex CLI; 2026-04 series — vault-mirror GH#31, phased-rollout #307, v3.2.0 release, etc.) were all running this pattern implicitly: no wave decomposition, coordinator executes tasks directly in sequence. This phase codifies what was already proven to work.
16
60
 
@@ -22,23 +66,42 @@ Emit the following banner immediately after the Phase 8 Q&A resolves:
22
66
  Express path activated — <N> tasks, coordinator-direct, no inter-wave checks.
23
67
  ```
24
68
 
25
- Then **skip the handoff to session-plan entirely**. Instead, execute the agreed tasks directly as the coordinator:
26
-
27
- 1. For each agreed task (in dependency order): execute as a direct coordinator action — read files, make changes, run quality checks inline.
28
- 2. After all tasks complete, invoke `skills/session-end/SKILL.md` directly (bypass session-plan and wave-executor).
29
- 3. Log the express-path activation in STATE.md `## Deviations` section: `Express path: N tasks executed coord-direct (express-path.enabled: true, session-type: housekeeping, scope: N issues)`.
69
+ > **RESOLVED (#1146, operator decision) session-plan RUNS, in shortened form.** Five documents
70
+ > described the post-activation routing and two of them said session-plan was skipped entirely.
71
+ > That reading cannot work: `commands/go.md` gates on a 1-wave Express Path plan, which under a
72
+ > skipped session-plan would never have been produced — `/go` would look for a plan that does not
73
+ > exist. The routing is now one sentence everywhere:
74
+ >
75
+ > **Phase 8.5 evaluates via `scripts/express-path.mjs`, prints the banner, then hands off NORMALLY
76
+ > to Phase 9 → session-plan.** session-plan detects the banner and its
77
+ > `## Express Path Short-Circuit (#214)` section emits a minimal 1-wave `coordinator-direct` plan
78
+ > (0 agents dispatched, no role decomposition, no wave splitting). `/go` detects that plan per
79
+ > `commands/go.md` § Express Path Detection and routes to coord-direct execution plus
80
+ > session-end auto-invocation — never to wave-executor.
81
+ >
82
+ > What activation skips is the WAVE MACHINERY (subagent dispatch, role decomposition, inter-wave
83
+ > checkpoints), not the planning handoff. The two sites that said otherwise —
84
+ > this file and `skills/session-start/SKILL.md` — were corrected in the same pass;
85
+ > `docs/session-config-reference.md`, `skills/session-plan/SKILL.md` and `commands/go.md`
86
+ > already carried the surviving reading.
87
+
88
+ Hand off to Phase 9 as usual. The coordinator then executes the 1-wave plan session-plan emits directly, without dispatching subagents:
89
+
90
+ 1. Proceed to Phase 9 (session-plan handoff) carrying the banner. session-plan short-circuits to the 1-wave `coordinator-direct` plan; `/go` detects it and does NOT invoke wave-executor.
91
+ 2. For each agreed task (in dependency order): execute as a direct coordinator action — read files, make changes, run quality checks inline. No subagents, no inter-wave checkpoints.
92
+ 3. Log the express-path activation in STATE.md `## Deviations` section: `Express path: N tasks executed coord-direct (express-path.enabled: true, session-type: housekeeping, scope: N issues)` — written BEFORE session-end is invoked. Then invoke `skills/session-end/SKILL.md` directly.
30
93
  4. After session-end completes successfully: verify STATE.md `status` is `completed` and `## Deviations` contains the express-path entry from step 3. If either is missing, warn the user with a one-line note and instructions to re-run `/close` manually. Then return the final session summary to the user.
31
94
 
32
95
  **Persistence contract:**
33
96
 
34
- The four steps above MUST all happen within a single coordinator turn. Specifically:
97
+ Step 1 is the Phase 9 handoff and ends the session-start turn — the operator types `/go` next, exactly as on the normal path. Steps 2–4 then MUST all happen within a SINGLE coordinator turn, the one `/go` opens. Specifically:
35
98
 
36
- - Step 1 (execute tasks) happens first in the coordinator's main flow.
37
- - Step 2 (deviations log) is written BEFORE session-end is invoked. The coordinator calls `appendDeviation()` from `scripts/lib/state-md.mjs` to append the `Express path:` bullet to the `## Deviations` section while STATE.md is still `status: active`.
38
- - Step 3 (invoke session-end) flips `status` to `completed`, writes the metrics record to `.orchestrator/metrics/sessions.jsonl`, and runs the standard close flow. Session-end has no Express Path-specific logic — it treats this run identically to any other completed session.
99
+ - Step 2 (execute tasks) happens first in that turn's main flow.
100
+ - Step 3a (deviations log) is written BEFORE session-end is invoked. The coordinator calls `appendDeviation()` from `scripts/lib/state-md.mjs` to append the `Express path:` bullet to the `## Deviations` section while STATE.md is still `status: active`.
101
+ - Step 3b (invoke session-end) flips `status` to `completed`, writes the metrics record to `.orchestrator/metrics/sessions.jsonl`, and runs the standard close flow. Session-end has no Express Path-specific logic — it treats this run identically to any other completed session.
39
102
  - Step 4 (verification) is the coordinator's final action before returning control. The verification check uses `parseStateMd()` from `scripts/lib/state-md.mjs` to read the file and check `frontmatter.status === 'completed'` and that the body contains the literal string `Express path:`.
40
103
 
41
- If `/go` is invoked but the session-plan emitted a 1-wave Express Path plan (per `skills/session-plan/SKILL.md` § "Express Path Short-Circuit"), the `/go` command MUST detect this and route to coord-direct execution + session-end auto-invocation, NOT to wave-executor. See `commands/go.md` for the detection branch.
104
+ When `/go` is invoked and session-plan emitted a 1-wave Express Path plan (per `skills/session-plan/SKILL.md` § "Express Path Short-Circuit"), the `/go` command MUST detect this and route to coord-direct execution + session-end auto-invocation, NOT to wave-executor. See `commands/go.md` for the detection branch — that plan is the artifact `/go` keys on, which is why Phase 8.5 hands off to session-plan rather than skipping it.
42
105
 
43
106
  **When Express Path does NOT activate** (conditions not met):
44
107
 
@@ -56,6 +119,8 @@ Proceed normally to Phase 9 (session-plan handoff). The express-path evaluation
56
119
 
57
120
  ## See Also
58
121
 
122
+ - `scripts/express-path.mjs` — the CLI this phase runs; `scripts/lib/express-path.mjs` holds the decision + its `orchestrator.express_path.evaluated` record
123
+ - `skills/session-plan/SKILL.md` § "Express Path Short-Circuit (#214)" — the 1-wave plan Phase 9 emits when the banner is present
59
124
  - `commands/go.md` — Express Path detection and auto-invocation of session-end after coord-direct tasks
60
125
  - `skills/session-end/SKILL.md` — Phase 1 pre-check (Rule 2) blocks `/close` when STATE.md `status: completed`; auto-invocation from express-path bypasses this
61
126
  - `commands/close.md` — Rule 2 wording the user sees if express-path persistence breaks
@@ -64,6 +64,116 @@ The active level is `efficiency.output-level` in `~/.config/session-orchestrator
64
64
  - Shape: explain the WHY behind each recommendation, name the alternatives you rejected and why, spell out unfamiliar terms on first use.
65
65
  - Escalation: `expand <topic>` — see § Escalation above.
66
66
 
67
+ ### Register — how a sentence reads
68
+
69
+ The budgets above set *how much* you say. This sets *how*. It binds at every
70
+ level and is not itself a budget: applying it changes word order and word
71
+ choice, not line count. It is the canonical statement for this repo — the
72
+ other three souls (`plan`, `brainstorm`, `grill`) point here rather than
73
+ copying it.
74
+
75
+ **Write for someone who knows this project but has not seen what you just saw.**
76
+ What he needs to decide stands in the text, not in the file it points at — in
77
+ the AUQ payload and in every finding you post.
78
+
79
+ This is not "explain it like he is five". The operator owns this repo. He is
80
+ not missing knowledge, he is missing **observation** — he did not watch the
81
+ command you just ran or read the file you just opened. A knowledge framing
82
+ would be factually wrong and condescending at the same time. Write across, not
83
+ down: same expertise as yours, minus your last ten minutes.
84
+
85
+ #### Plain words, real things
86
+
87
+ > **Say more simply what actually happens — and introduce nothing that does not exist.**
88
+ >
89
+ > **The test:** delete every noun the system does not contain. If the sentence
90
+ > is still true and complete, it was no analogy. If it collapses, the analogy
91
+ > was load-bearing — replace it with a description of what actually happens.
92
+
93
+ Five worked cases, in rising difficulty:
94
+
95
+ 1. "Waiting means the other session finishes first." — **allowed.** Sessions
96
+ and waiting both exist; nothing foreign was introduced.
97
+ 2. "Think of the session as a level crossing." — **forbidden.** Delete "level
98
+ crossing" and nothing is left. Say what happens instead: one session holds
99
+ `.orchestrator/session.lock`, the other waits for it.
100
+ 3. "The token budget is used up." — **allowed.** `TOKEN_BUDGET_EXCEEDED` is a
101
+ real identifier and "budget" is the system's own word. Adding "…like a tank
102
+ of fuel" would be forbidden — the tank does not exist.
103
+ 4. "Think of the kill-switches as a fuse box." — **forbidden, and wrong on the
104
+ facts.** Fuses trip on overload; the kill-switches also test elapsed time and
105
+ confidence. The image sounds helpful and is not. A wrong picture costs more
106
+ than no picture, because the operator reasons from it.
107
+ 5. **Dead metaphors.** A proper name may itself be a metaphor —
108
+ `pre-bash-destructive-guard` is called a guard — and you use the name as
109
+ given. Reviving the image is the violation: "the guard will not let it
110
+ through" invites the operator to picture a guard and then reason from the
111
+ picture instead of from the hook. Name the identifier, then say what it
112
+ does: the hook denies the Bash call.
113
+
114
+ #### Precedence over § "Never traded for brevity"
115
+
116
+ There is a real collision above: "say it more simply" can water down a precise
117
+ error message. Resolve it in three steps.
118
+
119
+ 1. **Simplifying removes words, never facts.** If a path, a number, an error
120
+ code, an identifier, or an instruction to act disappears, that is data loss,
121
+ not simplification — and § "Never traded for brevity" already forbids it.
122
+ 2. **When both will not fit in one sentence: precision in the sentence,
123
+ plainness in the one beside it.** The exact term is never replaced, only
124
+ accompanied. It is what the operator greps, quotes, and pastes into an issue.
125
+ 3. **The mechanical tie-breaker:** could the token you are about to cut ever
126
+ appear in a `grep`? Then it stays.
127
+
128
+ Measured 2026-08-22 at `a4f93cf`: of 191 option descriptions in this repo, the
129
+ 20 that match the safety lexicon (`SAFETY_PATTERN` in
130
+ `scripts/lib/auq/schema.mjs`) run 26–108 codepoints — all of them under both K6
131
+ length thresholds (`descriptionCharsWarn` 120, `descriptionCharsFail` 150). The
132
+ collision therefore does not occur today. This precedence rule is a precaution,
133
+ not a repair.
134
+
135
+ #### Worked example — an operator-visible message
136
+
137
+ `formatBlockReason()` in `scripts/lib/issue-budget.mjs` is what the operator
138
+ sees when the issue cap blocks a creation. Rendered with the collector-issue
139
+ sink, before:
140
+
141
+ ```
142
+ issue-budget: session cap reached — 12/12 issues already created.
143
+ This request was NOT created. It is parked as overflow entry #3 in:
144
+ .orchestrator/runtime/issue-budget-overflow.jsonl
145
+ session-end Phase 5 will fold all overflow entries into ONE collector issue `[Backlog-Sammel] <session-id>, N zurückgestellte Punkte`. Nothing is lost.
146
+ Exempt from the cap: priority::critical, the carryover class (SPIRAL/FAILED, [Carryover]),
147
+ and broken-window closure issues — those are never deferred.
148
+ To raise the cap for this repo, edit `issue-budget.max-per-session` in the Session Config;
149
+ `mode: warn` reports without blocking, `mode: off` disables the gate.
150
+ ```
151
+
152
+ After:
153
+
154
+ ```
155
+ Nothing is lost — the issue is parked, and nothing needs doing right now.
156
+ issue-budget: session cap reached — 12/12 issues already created, so this one was NOT created.
157
+ It is parked as overflow entry #3 in:
158
+ .orchestrator/runtime/issue-budget-overflow.jsonl
159
+ session-end Phase 5 folds all overflow entries into ONE collector issue `[Backlog-Sammel] <session-id>, N zurückgestellte Punkte`.
160
+ Exempt from the cap: priority::critical, the carryover class (SPIRAL/FAILED, [Carryover]),
161
+ and broken-window closure issues — those are never deferred.
162
+ To raise the cap for this repo, edit `issue-budget.max-per-session` in the Session Config; `mode: warn` reports without blocking, `mode: off` disables the gate.
163
+ ```
164
+
165
+ Three changes, and only these three: the operator's own question — *must I do
166
+ something?* — moved to line 1, carrying "Nothing is lost" up from line 4 where
167
+ he used to reach it last; `will fold` became the active `folds`; and the first
168
+ two lines merged on a causal `so`, which is why "This request" is now "this
169
+ one" — the same subject, already named in the sentence.
170
+
171
+ The whole word-level diff is four dropped tokens: `This`, `request`, `will`,
172
+ `fold`. Not one of them is a path, a count, a label, a config key, or a mode
173
+ value; every one of those survives character for character. Eight lines before,
174
+ eight lines after — **this register is not a diet.** It is the same facts, in
175
+ the order the reader needs them.
176
+
67
177
  ### Companion dials
68
178
 
69
179
  Same file, same lookup, same fallback-to-default rule:
@@ -216,11 +216,11 @@ Group `medium` and `low` findings and present via a single `AskUserQuestion` cal
216
216
  AskUserQuestion({
217
217
  questions: [{
218
218
  question: `<N> medium/low findings to triage. How to handle?`,
219
- header: "Test-runner triage",
219
+ header: "Triage",
220
220
  options: [
221
221
  {
222
222
  label: "Create all (Recommended)",
223
- description: "File <N> new issues, all with label from:test-runner"
223
+ description: "Files <N> new issues at once, all with label from:test-runner — fastest, and you can still close any of them afterwards."
224
224
  },
225
225
  {
226
226
  label: "Review each",
@@ -67,7 +67,7 @@ When two or more candidates score ≥ 0.85 with delta < 0.15, call `AskUserQuest
67
67
  AskUserQuestion({
68
68
  questions: [{
69
69
  question: "Your message matches multiple workflows. Which one did you mean?",
70
- header: "Skill Dispatch",
70
+ header: "Dispatch",
71
71
  multiSelect: false,
72
72
  options: [
73
73
  { label: "<top-skill display name> (Recommended)", description: "<one-line description of what it does>" },
@@ -92,6 +92,26 @@ const vaultNoteTypeSchema = z.enum([
92
92
  'board',
93
93
  ]);
94
94
 
95
+ // VENDORED COPY. SSOT: projects-baseline/packages/zod-schemas/src/vault-frontmatter.ts
96
+ // (`vaultNoteStatusSchema`). This file is a standalone CLI with no exports, so the
97
+ // values cannot be imported — they are hand-kept in sync, and that is the known cost.
98
+ //
99
+ // Measured 2026-08-23: FOUR hand-maintained copies of this enum exist —
100
+ // 1. the SSOT above
101
+ // 2. this file
102
+ // 3. sven-infra `02-cron/vault-overview-sync.sh:216`
103
+ // 4. `tests/lib/vault-mirror/render-sessions.test.mjs:490`, whose own comment names
104
+ // this file as its source and then transcribes it
105
+ // Copy 4 is deliberately NOT widened: it asserts membership for a mapper that emits
106
+ // only `verified`/`draft`, so adding values it cannot produce would weaken it.
107
+ //
108
+ // A drift test reading the SSOT directly was considered and REJECTED: the SSOT lives
109
+ // in a sibling repo resolved host-locally, so such a test passes on this machine and
110
+ // fails in CI, where projects-baseline is not checked out. The durable fix is
111
+ // generation from the SSOT at build time, not a test that reads across a repo
112
+ // boundary. Revisit trigger: a fifth copy, or the first CI-visible drift.
113
+ //
114
+ // Order below mirrors the SSOT exactly, so a diff of the two lists is readable.
95
115
  const vaultNoteStatusSchema = z.enum([
96
116
  'draft',
97
117
  'active',
@@ -100,6 +120,17 @@ const vaultNoteStatusSchema = z.enum([
100
120
  'production',
101
121
  'mvp',
102
122
  'idea',
123
+ // Added 2026-08-23 (baseline MR !27, merge 6f38aeb). sven renders these into
124
+ // `01-projects/*/_overview.md`; measured the same day, SIX of them already carried
125
+ // one of these values (4x dead, 1x paused, 1x maintenance). Falsified rather than
126
+ // assumed: removing the four again produced exactly 6 `status` errors, re-adding
127
+ // them produced 0. Without them the strict gate blocks every vault session-close.
128
+ // Slugs deliberately not listed here — the scanner treats them as private
129
+ // (`check-owner-leakage` CP6), and the count is the load-bearing part anyway.
130
+ 'maintenance',
131
+ 'planned',
132
+ 'paused',
133
+ 'dead',
103
134
  ]);
104
135
 
105
136
  const vaultFrontmatterSchema = z
@@ -44,7 +44,7 @@ Every harness creates friction. The goal is not minimum friction — it is usefu
44
44
  - Silent partial completion (STATUS line requirement forces explicit reporting)
45
45
  - Untracked carryover work (session-end plan verification catches unresolved tasks)
46
46
 
47
- The harness does not hope agents self-correct. It detects stagnation patterns — pagination-spiral, turn-key-repetition, error-echo — classifies them into the Error-Class Taxonomy defined in `circuit-breaker.md`, and re-scopes mechanically. Review logic lives in `wave-loop.md` § "Review Agent Outputs".
47
+ The harness does not hope agents self-correct. It detects stagnation patterns — pagination-spiral, turn-key-repetition, error-echo (read by the coordinator during post-wave review), plus psa007-git-write and status-partial (detected live by the transcript tailer, recorded with `source: "tail"`) — classifies error-echo into the Error-Class Taxonomy defined in `circuit-breaker.md`, and re-scopes mechanically. Review logic lives in `wave-loop.md` § "Review Agent Outputs"; the tailer's start and its silence-is-not-success caveat live in the same file, step 2.0-bis.
48
48
 
49
49
  ## Platform Note
50
50
 
@@ -192,6 +192,8 @@ Read and follow `wave-loop.md` in this skill directory for the complete wave exe
192
192
 
193
193
  The coordinator (you) is responsible for updating per-task mission status in STATE.md as tasks progress through the wave. Use `setMissionStatus(stateContent, taskId, status)` from `scripts/lib/state-md.mjs` and write the result back to STATE.md immediately.
194
194
 
195
+ **`taskId` grammar (enforced).** `setMissionStatus` refuses any `taskId` outside `[a-z][a-z0-9]*(?:-[a-z0-9]+)*-\d+` — lowercase segments joined by single hyphens, ending in a bare digit run. Accepted: `m-1`, `docs-2`, `w2-1`, `w2-a-10`. Refused (`refused: 'id-grammar'`): `w2-a10` (digits fused onto a letter segment), `w3-p2` (no trailing bare-digit segment), `W3-I1` (uppercase), `Docs_2` (underscore). A refused write returns `{ written: false, reason: 'id-grammar' }` from `setMissionStatusOnDisk` and logs a stderr WARN naming the rejected id — nothing is written to STATE.md on refusal, so mint ids matching this grammar from the start rather than relying on the refusal to catch a typo.
196
+
195
197
  **Per-task transition rules (coordinator fires these, NOT wave-loop.md):**
196
198
 
197
199
  | Transition | When to fire |
@@ -479,7 +481,7 @@ An opt-in bounded-concurrency cursor-based pull loop that replaces the default P
479
481
 
480
482
  ## Anti-Patterns
481
483
 
482
- - **NEVER** run `run_in_background: true` during wavesyou lose coordination ability
484
+ - **NEVER** count launch acks as completions — verify the started set against `agent-<id>.meta.json` sidecars and completions against task-notifications (`wave-loop.md § Started-Set Verification`). `run_in_background: true` is ALLOWED and RECOMMENDED for wave dispatch: measured 2026-08-22 (v2.1.239), under blocking dispatch the coordinator was 143 s incapable of acting between an agent's mid-run escalation and its own next turn escalation latency equals the batch's remaining runtime. Background dispatch returns turns to the coordinator between agent completions; a running agent received a queued message mid-run and answered ~9 min before its final report.
483
485
  - **NEVER** skip inter-wave review — quality degrades exponentially
484
486
  - **NEVER** let agents commit independently — coordinator commits at session end
485
487
  - **NEVER** continue to next wave if previous wave has unresolved failures
@@ -103,12 +103,14 @@ The function never throws — it always returns a result object. Treat `skipped:
103
103
  description: "...",
104
104
  prompt: "...",
105
105
  subagent_type: "general-purpose",
106
- run_in_background: false,
106
+ run_in_background: true,
107
107
  isolation: "worktree"
108
108
  })
109
109
  ```
110
110
  When resolved isolation is `none`, omit the `isolation` parameter (agents run in the coordinator's working tree).
111
111
 
112
+ `isolation` and `run_in_background` are orthogonal: worktree isolation partitions the filesystem, backgrounding decides when the coordinator's turn returns. A backgrounded worktree agent still merges back on completion — but do NOT read the immediate launch ack as "the worktree merged". Wait for the agent's task-notification before step 4 below (`wave-loop.md § Started-Set Verification`).
113
+
112
114
  4. **Post-wave merge**: After wave completes, worktree changes are automatically available. If agents made changes in worktrees:
113
115
  - Review each agent's changes for conflicts using `git diff` between worktree branches
114
116
  - **Merge strategy**: Apply agent changes sequentially (by agent number). For each agent:
@@ -120,7 +122,11 @@ The function never throws — it always returns a result object. Treat `skipped:
120
122
 
121
123
  ## Stagnation Patterns
122
124
 
123
- > Detection rules for the coordinator to apply during post-wave review (step 2 of `wave-loop.md`). All three patterns are LLM heuristics, not executable code — the coordinator interprets them contextually based on agent output and tool-call history.
125
+ > Detection rules applied at two different moments, by two different producers of the SAME `stagnation_detected` record (`wave-loop.md` § "Review Agent Outputs" carries the schema; `source` says which).
126
+ >
127
+ > - **Coordinator heuristics (3):** Pagination Spiral, Turn-Key Repetition, Error Echo. LLM heuristics, not executable code — the coordinator interprets them contextually from agent output and tool-call history during post-wave review (step 2 of `wave-loop.md`). Recorded with `source: "coordinator"`.
128
+ > - **Tail-mechanical (2):** PSA-007 Git-Write and Status-Partial (§ 4 / § 5 below). Executable regexes run live by `scripts/lib/wave-transcript-tail.mjs` against the session's subagent transcripts — no model call, no judgement. Recorded with `source: "tail"`.
129
+ > - **Error Echo is BOTH.** The coordinator's contextual reading of it is unchanged, and the tailer additionally matches its repeated-failure signature mechanically. One wave can therefore produce an error-echo record from either producer; the records are otherwise identical and are told apart only by `source`.
124
130
 
125
131
  ### 1. Pagination Spiral
126
132
 
@@ -153,19 +159,38 @@ Same error message returned 3 times, with the agent attempting the same fix (or
153
159
  - `command-blocked` — denial from `enforce-commands.sh` (blocked command list).
154
160
  - `other` — fallback when none of the above match.
155
161
 
156
- The `error_class` value is used by the stagnation event-write rule in `wave-loop.md` § "Review Agent Outputs".
162
+ The `error_class` value is used by the stagnation event-write rule in `wave-loop.md` § "Review Agent Outputs". The taxonomy belongs to Error Echo **alone** — the four patterns below and above it omit the field entirely rather than falling back to `other`.
163
+
164
+ ### 4. PSA-007 Git-Write (source: tail)
165
+
166
+ **Indicator:** a subagent's Bash call runs a git-write command — `git add`, `git commit`, `git stash`, `git push`, and equally `git mv` / `git rm` / `git reset` / `git checkout -- <file>`. `.claude/rules/parallel-sessions.md` § PSA-007 forbids all of them for dispatched agents: the git index and stash are shared resources of the working copy, not a per-agent workspace. Fleet evidence (2 repos, 2026-07, conf ≥ 0.9) records `index.lock` collisions and stash operations that silently discarded a sibling agent's work-in-progress.
167
+
168
+ **Detected by:** the tailer, mechanically, on the FIRST occurrence — not by post-wave review, and not on a repetition threshold. Today the coordinator learns of a subagent git-write only when the agent volunteers it in its own report.
169
+
170
+ **Action:** surface it in the wave progress update at once and inspect the shared index (`git status --porcelain`, `git stash list`) before the next dispatch. Do NOT re-dispatch into the same shared tree until the index state is understood — a stash the agent created is one the sibling cannot find. No `error_class`; `occurrences: 1` is the normal value.
171
+
172
+ ### 5. Status-Partial (source: tail)
173
+
174
+ **Indicator:** the agent's own transcript contains `STATUS: partial` (or `STATUS: failed`) — a **self-reported** failure, not an inferred one, so there is nothing to interpret.
175
+
176
+ **Detected by:** the tailer, mechanically. The value here is **durability, not earliness**: when maxTurns kills an agent after it wrote the line but before its final report reaches the coordinator, the finding is lost today. The `events.jsonl` record survives that kill.
177
+
178
+ **Action:** treat exactly as the § Status Detection Protocol `partial` / `failed` branch above — carry forward the remaining work, or re-dispatch with narrower scope. A tail record is a **backstop for** the agent's report, never a replacement: when the report does arrive, the report wins and the tail record is corroboration (do not double-count one failure as two). No `error_class`; `occurrences: 1`.
157
179
 
158
180
  ### Decision Table
159
181
 
160
- | Pattern | Indicator | Action | Error Class |
161
- |---------|-----------|--------|-------------|
162
- | Pagination Spiral | 3+ Read/Grep on same file with only pagination args, no Edit between | STAGNANT — re-dispatch with line-range scope | N/A |
163
- | Turn-Key Repetition | 3 identical consecutive turn keys (pagination-stripped) | SPIRAL — revert, narrow, re-dispatch | N/A |
164
- | Error Echo | Same error 3x, same fix attempted | FAILED — escalate with error context | see taxonomy above |
182
+ | Pattern | Indicator | Action | Error Class | Source |
183
+ |---------|-----------|--------|-------------|--------|
184
+ | Pagination Spiral | 3+ Read/Grep on same file with only pagination args, no Edit between | STAGNANT — re-dispatch with line-range scope | N/A | coordinator |
185
+ | Turn-Key Repetition | 3 identical consecutive turn keys (pagination-stripped) | SPIRAL — revert, narrow, re-dispatch | N/A | coordinator |
186
+ | Error Echo | Same error 3x, same fix attempted | FAILED — escalate with error context | see taxonomy above | coordinator **and** tail |
187
+ | PSA-007 Git-Write | Subagent Bash runs `git add`/`commit`/`stash`/`push` (or `mv`/`rm`/`reset`/`checkout --`) | Surface immediately; inspect shared index before next dispatch | N/A | tail |
188
+ | Status-Partial | Agent transcript carries `STATUS: partial` / `STATUS: failed` | Same as the Status Detection Protocol `partial`/`failed` branch; backstop for a lost report | N/A | tail |
165
189
 
166
190
  ### Detection Discipline
167
191
 
168
- - These checks run during step 2 of `wave-loop.md` ("Review Agent Outputs"), per agent, after the wave completes — not during the agent's execution.
192
+ - The three **coordinator** checks run during step 2 of `wave-loop.md` ("Review Agent Outputs"), per agent, after the wave completes — not during the agent's execution. The two **tail** checks (§ 4 / § 5) run live and are the exception to that timing, which is exactly why they survive a maxTurns kill.
193
+ - **Tail silence is not a clean wave.** Transcripts flush per turn, so an agent inside one long tool call is unobservable for that call's duration (`.claude/rules/loop-and-monitor.md` § LM-002). Absence of tail records never substitutes for the post-wave review.
169
194
  - Two different agents reading the same file is **not** a spiral. That is coordination across agents, not stagnation within an agent.
170
195
  - A legitimate sequential read of a large file (e.g., reading lines 1-200, then 200-400 to gather full context for an upcoming edit) is **not** a pagination spiral if the agent eventually edits the file. The pattern triggers only when paging continues without ever producing an edit.
171
196
  - These patterns are heuristics. When in doubt, prefer false negatives (let the agent finish) over false positives (kill productive work).