session-orchestrator 5.3.0 → 5.5.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 (260) hide show
  1. package/.agents/skills/claude-md-drift-check/SKILL.md +1 -1
  2. package/.agents/skills/test-audit/SKILL.md +21 -0
  3. package/.agents/skills/test-audit/agents/openai.yaml +5 -0
  4. package/.claude-plugin/marketplace.json +1 -1
  5. package/.claude-plugin/plugin.json +1 -1
  6. package/.codex-plugin/plugin.json +1 -1
  7. package/.codex-plugin/skills/claude-md-drift-check/SKILL.md +1 -1
  8. package/.codex-plugin/skills/test-audit/SKILL.md +21 -0
  9. package/.codex-plugin/skills/test-audit/agents/openai.yaml +5 -0
  10. package/.cursor/commands/test-audit.md +14 -0
  11. package/.cursor/rules/060-evolve.mdc +28 -13
  12. package/.cursor/skills/claude-md-drift-check/SKILL.md +1 -1
  13. package/.cursor/skills/test-audit/SKILL.md +12 -0
  14. package/.cursor-plugin/plugin.json +1 -1
  15. package/.orchestrator/policy/blocked-commands.json +1 -1
  16. package/AGENTS.md +9 -31
  17. package/CHANGELOG.md +162 -0
  18. package/README.md +14 -10
  19. package/docs/agent-authoring.md +2 -2
  20. package/docs/baseline.md +10 -1
  21. package/docs/ci-setup.md +154 -4
  22. package/docs/components.md +11 -11
  23. package/docs/events-schema.md +25 -19
  24. package/docs/install.md +14 -2
  25. package/docs/migration-v4.md +24 -17
  26. package/docs/persona-panel.md +5 -4
  27. package/docs/plugin-architecture-v3.md +1 -1
  28. package/docs/rule-authoring.md +27 -12
  29. package/docs/scope-collision-guard.md +40 -16
  30. package/docs/session-config-reference.md +61 -12
  31. package/docs/session-config-template.md +11 -2
  32. package/docs/vault-docs-architecture.md +8 -4
  33. package/hooks/_lib/hook-import-set.json +42 -29
  34. package/hooks/_lib/lock-bootstrap.mjs +118 -26
  35. package/hooks/config-protection.mjs +1 -1
  36. package/hooks/enforce-commands.mjs +28 -13
  37. package/hooks/enforce-scope.mjs +201 -23
  38. package/hooks/hooks-codex.json +1 -1
  39. package/hooks/hooks-cursor.json +5 -0
  40. package/hooks/hooks-pi.json +5 -0
  41. package/hooks/hooks.json +6 -1
  42. package/hooks/on-session-start.mjs +57 -2
  43. package/hooks/on-stop.mjs +70 -168
  44. package/hooks/post-bash-write-verify.mjs +98 -17
  45. package/hooks/post-edit-validate.mjs +15 -5
  46. package/hooks/post-tool-batch-wave-signal.mjs +32 -152
  47. package/hooks/pre-bash-memory-propose-audit.mjs +71 -10
  48. package/hooks/pre-bash-sessions-ledger-guard.mjs +28 -2
  49. package/hooks/pre-bash-staging-fence.mjs +29 -8
  50. package/hooks/pre-edit-sessions-ledger-guard.mjs +162 -0
  51. package/hooks/pre-task-scope-disjoint.mjs +1143 -279
  52. package/hooks/subagent-telemetry.mjs +96 -19
  53. package/hooks/wave-scope-commit-guard.mjs +168 -72
  54. package/package.json +2 -6
  55. package/pi/prompts/test-audit.md +12 -0
  56. package/rules/README.md +6 -1
  57. package/rules/_index.md +3 -3
  58. package/rules/always-on/bash-harness-pitfalls.md +7 -1
  59. package/rules/opt-in-domain/prompt-caching.md +5 -1
  60. package/rules/opt-in-stack/backend-data.md +9 -1
  61. package/rules/opt-in-stack/backend.md +7 -1
  62. package/rules/opt-in-stack/frontend.md +6 -1
  63. package/rules/opt-in-stack/security-web.md +7 -1
  64. package/rules/opt-in-stack/swift.md +5 -1
  65. package/scripts/apply-session-learnings.mjs +513 -0
  66. package/scripts/archive-closed-prds.mjs +40 -12
  67. package/scripts/autopilot.mjs +57 -54
  68. package/scripts/backfill-abandoned-sessions.mjs +81 -6
  69. package/scripts/backfill-learnings-from-vault.mjs +49 -22
  70. package/scripts/baseline-archetypes.mjs +1 -1
  71. package/scripts/check-package-manager.mjs +62 -5
  72. package/scripts/codex-install.mjs +3 -0
  73. package/scripts/cursor-install.mjs +47 -6
  74. package/scripts/emit-session.mjs +298 -2
  75. package/scripts/export-hw-learnings.mjs +40 -10
  76. package/scripts/fleet-checkin.mjs +170 -0
  77. package/scripts/lib/agent-frontmatter.mjs +3 -3
  78. package/scripts/lib/auto-dream.mjs +7 -6
  79. package/scripts/lib/autopilot/flags.mjs +6 -1
  80. package/scripts/lib/autopilot/loop.mjs +32 -13
  81. package/scripts/lib/autopilot/stall-sampler.mjs +13 -9
  82. package/scripts/lib/baseline-archetypes.mjs +41 -22
  83. package/scripts/lib/blocked-commands-policy.mjs +40 -0
  84. package/scripts/lib/common.mjs +41 -0
  85. package/scripts/lib/config/host-paths.mjs +79 -0
  86. package/scripts/lib/config/persona-gate-wave.mjs +3 -3
  87. package/scripts/lib/config/reaper.mjs +7 -6
  88. package/scripts/lib/config/vault-integration.mjs +151 -16
  89. package/scripts/lib/config-schema.mjs +13 -0
  90. package/scripts/lib/config.mjs +75 -10
  91. package/scripts/lib/eval/engine.mjs +13 -0
  92. package/scripts/lib/events-retention-banner.mjs +393 -0
  93. package/scripts/lib/events-rotation.mjs +21 -6
  94. package/scripts/lib/events.mjs +72 -5
  95. package/scripts/lib/fleet-protocol.mjs +288 -0
  96. package/scripts/lib/gates/gate-baseline.mjs +13 -3
  97. package/scripts/lib/gates/gate-full.mjs +7 -2
  98. package/scripts/lib/gates/gate-helpers.mjs +93 -2
  99. package/scripts/lib/gates/gate-incremental.mjs +23 -22
  100. package/scripts/lib/gates/gate-per-file.mjs +16 -7
  101. package/scripts/lib/hardening.mjs +1 -0
  102. package/scripts/lib/harness-audit/categories/category4.mjs +8 -6
  103. package/scripts/lib/instruction-budget-guard.mjs +77 -11
  104. package/scripts/lib/learnings/expiry-sweep.mjs +420 -22
  105. package/scripts/lib/learnings/io.mjs +274 -37
  106. package/scripts/lib/learnings/schema.mjs +163 -15
  107. package/scripts/lib/learnings/sizing-subject.mjs +2 -2
  108. package/scripts/lib/lock-reaper.mjs +38 -14
  109. package/scripts/lib/maintenance-due-banner.mjs +23 -8
  110. package/scripts/lib/memory-proposals/schema.mjs +11 -5
  111. package/scripts/lib/named-baseline-resolver.mjs +53 -28
  112. package/scripts/lib/named-vault-resolver.mjs +147 -5
  113. package/scripts/lib/orphan-reaper/defaults.mjs +41 -0
  114. package/scripts/lib/orphan-reaper/no-follow-append.mjs +87 -0
  115. package/scripts/lib/orphan-reaper/ps-snapshot.mjs +181 -0
  116. package/scripts/lib/orphan-reaper/reaper-audit.mjs +323 -0
  117. package/scripts/lib/orphan-reaper/reaper-decide.mjs +395 -0
  118. package/scripts/lib/orphan-reaper/scan-throttle.mjs +144 -0
  119. package/scripts/lib/orphan-reaper/scan.mjs +510 -0
  120. package/scripts/lib/orphan-reaper/trigger.mjs +173 -0
  121. package/scripts/lib/orphan-reaper.mjs +47 -1315
  122. package/scripts/lib/owner-yaml.mjs +104 -6
  123. package/scripts/lib/persona-panel/catalog-loader.mjs +1 -1
  124. package/scripts/lib/platform.mjs +206 -2
  125. package/scripts/lib/plugin-update-banner.mjs +3 -1
  126. package/scripts/lib/process-group.mjs +134 -22
  127. package/scripts/lib/project-hygiene.mjs +21 -1
  128. package/scripts/lib/quality-gate.mjs +45 -5
  129. package/scripts/lib/resource-probe.mjs +1 -1
  130. package/scripts/lib/rule-loader.mjs +100 -62
  131. package/scripts/lib/rules-sync.mjs +27 -12
  132. package/scripts/lib/scope-baseline.mjs +119 -29
  133. package/scripts/lib/scope-echo.mjs +7 -0
  134. package/scripts/lib/scope-gate.mjs +194 -27
  135. package/scripts/lib/session-close-backfill.mjs +129 -4
  136. package/scripts/lib/session-end/tail-runner.mjs +10 -5
  137. package/scripts/lib/session-lock-shape.mjs +6 -3
  138. package/scripts/lib/session-lock.mjs +320 -67
  139. package/scripts/lib/session-record-repair.mjs +183 -26
  140. package/scripts/lib/session-registry.mjs +67 -17
  141. package/scripts/lib/session-schema/constants.mjs +30 -4
  142. package/scripts/lib/session-schema/validator.mjs +28 -1
  143. package/scripts/lib/session-start-probes.mjs +242 -68
  144. package/scripts/lib/session-token-rollup.mjs +252 -54
  145. package/scripts/lib/sessions-canonical.mjs +100 -9
  146. package/scripts/lib/sessions-staleness-banner.mjs +3 -1
  147. package/scripts/lib/sh-quote.mjs +29 -0
  148. package/scripts/lib/subagents-schema.mjs +30 -3
  149. package/scripts/lib/tail-window.mjs +27 -3
  150. package/scripts/lib/telemetry/pricing.mjs +121 -71
  151. package/scripts/lib/telemetry/sync.mjs +17 -0
  152. package/scripts/lib/tests-src-ratio.mjs +215 -23
  153. package/scripts/lib/tmux-layout/layouts.mjs +1 -11
  154. package/scripts/lib/tmux-layout/telemetry-stats.mjs +12 -0
  155. package/scripts/lib/tmux-layout/tmux-shell.mjs +2 -11
  156. package/scripts/lib/ux-grill/reconcile.mjs +1 -1
  157. package/scripts/lib/validate/check-agents.mjs +1 -1
  158. package/scripts/lib/validate/check-hooks-symmetry.mjs +5 -0
  159. package/scripts/lib/validate/check-learnings-shell-writes.mjs +214 -0
  160. package/scripts/lib/validate/check-test-value-bans.mjs +388 -27
  161. package/scripts/lib/validate/check-unicode-safety.mjs +1 -0
  162. package/scripts/lib/validate/check-unwired-features.mjs +1 -1
  163. package/scripts/lib/validate/check-vcs-repo-flag.mjs +1 -1
  164. package/scripts/lib/validate-vendored-rules.mjs +206 -81
  165. package/scripts/lib/vault-mirror/auto-commit.mjs +5 -3
  166. package/scripts/lib/vault-mirror/namespace.mjs +47 -26
  167. package/scripts/lib/vault-mirror/process.mjs +350 -62
  168. package/scripts/lib/vault-mirror/pseudonym-map.mjs +14 -5
  169. package/scripts/lib/vault-mirror/render-learnings.mjs +66 -3
  170. package/scripts/lib/vault-mirror/render-sessions.mjs +28 -4
  171. package/scripts/lib/vault-mirror/telemetry.mjs +25 -11
  172. package/scripts/lib/vault-status/board-writer.mjs +53 -12
  173. package/scripts/lib/vault-status/narrative-mirror.mjs +40 -9
  174. package/scripts/lib/vcs-repo-spec.mjs +8 -0
  175. package/scripts/lib/wave-executor/dispatch-common.mjs +10 -18
  176. package/scripts/lib/wave-executor/foreign-dispatch.mjs +1 -1
  177. package/scripts/lib/wave-executor/remote-dispatch.mjs +1 -1
  178. package/scripts/lib/wave-resource-gate.mjs +34 -8
  179. package/scripts/materialize-wave-scope.mjs +7 -4
  180. package/scripts/memory-propose.mjs +18 -5
  181. package/scripts/release-session-lock.mjs +2 -1
  182. package/scripts/release.mjs +11 -3
  183. package/scripts/repair-invalid-sessions.mjs +37 -4
  184. package/scripts/run-migrate-v2-cross-repo.mjs +171 -31
  185. package/scripts/run-quality-gate.mjs +331 -307
  186. package/scripts/self-update.mjs +229 -0
  187. package/scripts/site-numbers.mjs +163 -5
  188. package/scripts/sweep-expired-learnings.mjs +603 -20
  189. package/scripts/sweep-expired-rules.mjs +2 -1
  190. package/scripts/validate-plugin.mjs +7 -0
  191. package/scripts/validate-wave-scope.mjs +21 -2
  192. package/scripts/vault-backfill.mjs +50 -37
  193. package/scripts/vault-integration-watcher.mjs +2 -1
  194. package/scripts/vault-mirror.mjs +238 -75
  195. package/scripts/wave-scope-binding.mjs +2 -1
  196. package/skills/_shared/config-reading.md +3 -3
  197. package/skills/_shared/fleet-protocol.md +134 -0
  198. package/skills/_shared/state-ownership.md +41 -12
  199. package/skills/autopilot/SKILL.md +25 -11
  200. package/skills/bootstrap/SKILL.md +6 -4
  201. package/skills/bootstrap/_shared-template.md +97 -2
  202. package/skills/bootstrap/fast-template.md +4 -1
  203. package/skills/bootstrap/private-contract.md +2 -1
  204. package/skills/bootstrap/public-fallback.md +6 -3
  205. package/skills/bootstrap/references/bootstrap-refresh-lock-flow.md +5 -3
  206. package/skills/bootstrap/references/bootstrap-retroactive-flow.md +2 -1
  207. package/skills/bootstrap/standard-template.md +2 -0
  208. package/skills/claude-md-drift-check/SKILL.md +10 -10
  209. package/skills/claude-md-drift-check/checker.mjs +26 -18
  210. package/skills/discovery/probes/ssot-code-diff.mjs +12 -6
  211. package/skills/discovery/probes/vault-narrative-staleness.mjs +6 -2
  212. package/skills/discovery/probes/vault-staleness.mjs +9 -3
  213. package/skills/docs-orchestrator/SKILL.md +12 -5
  214. package/skills/docs-orchestrator/audience-mapping.md +5 -3
  215. package/skills/evolve/SKILL.md +13 -4
  216. package/skills/evolve/references/evolve-analyze-mode.md +42 -18
  217. package/skills/memory-cleanup/SKILL.md +1 -1
  218. package/skills/persona-panel/SKILL.md +2 -2
  219. package/skills/persona-panel/persona-format.md +2 -2
  220. package/skills/persona-panel/presets/designer-lens.md +1 -1
  221. package/skills/persona-panel/presets/engineer-lens.md +1 -1
  222. package/skills/persona-panel/presets/pm-lens.md +1 -1
  223. package/skills/plan/mode-retro.md +19 -4
  224. package/skills/quality-gates/SKILL.md +6 -4
  225. package/skills/remote-offload/SKILL.md +4 -2
  226. package/skills/session-end/learning-patterns.md +23 -13
  227. package/skills/session-end/metrics-collection.md +6 -7
  228. package/skills/session-end/phase-3-2-docs-verification.md +7 -6
  229. package/skills/session-end/plan-verification.md +25 -9
  230. package/skills/session-end/references/phase-3-documentation-updates.md +13 -3
  231. package/skills/session-end/references/phase-4a-worktree-cleanup.md +2 -0
  232. package/skills/session-end/references/session-summary-template.md +1 -1
  233. package/skills/session-end/session-metrics-write.md +65 -68
  234. package/skills/session-plan/SKILL.md +0 -3
  235. package/skills/session-start/SKILL.md +8 -2
  236. package/skills/session-start/references/operations-contract.md +6 -0
  237. package/skills/session-start/references/phase-1-2-session-lock.md +32 -7
  238. package/skills/session-start/references/phase-1-7-vault-status-board.md +1 -1
  239. package/skills/session-start/references/phase-4-ssot-environment-check.md +10 -3
  240. package/skills/test-audit/SKILL.md +152 -0
  241. package/skills/test-audit/references/campaign.md +111 -0
  242. package/skills/test-audit/references/mutate.sh +50 -0
  243. package/skills/vault-mirror/SKILL.md +21 -11
  244. package/skills/wave-executor/SKILL.md +2 -2
  245. package/skills/wave-executor/circuit-breaker.md +1 -1
  246. package/skills/wave-executor/references/wave-executor-state-init.md +3 -0
  247. package/skills/wave-executor/references/wave-loop-dispatch.md +11 -1
  248. package/skills/wave-executor/references/wave-loop-review.md +4 -6
  249. package/skills/wave-executor/references/wave-loop-scope-manifest.md +13 -5
  250. package/templates/personas/README.md +5 -5
  251. package/templates/personas/accounting-compliance.v1.md +1 -1
  252. package/templates/personas/accounting-tax-advisor.v1.md +1 -1
  253. package/templates/personas/buyer-p1-cto.v1.md +1 -1
  254. package/templates/personas/buyer-p2-kanzlei.v1.md +1 -1
  255. package/templates/personas/buyer-p3-build.v1.md +1 -1
  256. package/templates/personas/buyer-p4-tech-veto.v1.md +1 -1
  257. package/templates/personas/buyer-p5-solo.v1.md +1 -1
  258. package/templates/personas/buyer-p6-ld.v1.md +1 -1
  259. package/templates/personas/klima-ai-expert.v1.md +1 -1
  260. package/templates/personas/klima-physicist.v1.md +1 -1
@@ -373,8 +373,6 @@ If the commit itself fails (e.g., nothing to commit, pre-commit hook rejects), d
373
373
  - `agent_count_completed`: distinct agents whose task-notification (`<status>completed</status>`) arrived (#1115). A gap `agent_count_started > agent_count_completed` at wave end is an agent that started and never returned — the started-but-never-returned state, not a silent drop.
374
374
  - Per-agent results: `{description, status: done|partial|failed, files_changed_count}`
375
375
  - `files_changed`: total unique files changed this wave (from `git diff --stat --name-only`)
376
- - `planned_files_count`: size of this wave's Planned set (union of agent file scopes) as computed in step 3c File-level grounding above. Reuse that value — do not recompute.
377
- - `over_delivery_ratio`: files_changed / max(planned_files_count, 1), rounded to 2 decimals. > 1 = agents touched more files than briefed (under-sizing signal, #730/H4). Omit both fields when `grounding-check: false`.
378
376
  - `quality_check`: incremental check result (pass/fail/skipped)
379
377
  - `suite_passed` / `suite_failed` (+ optional `suite_platform`): the full-suite counts feeding the § 3a Wave History header `— suite <passed>/<failed> on <platform>`. `quality_check` is a traffic light; these are the number the light was derived from, and unlike STATE.md (gitignored, demoted to `## Previous Session` and then overwritten) the metrics record survives the session.
380
378
  **Copy the two counts off the gate's own event — do not re-read them from the terminal (#966 step 3).** `scripts/run-quality-gate.mjs`, the wrapper that fires between waves, emits `orchestrator.quality_gate.{passed,failed}` carrying a machine-measured `counts: {passed, failed, total}` (admitted by `admitSuiteCounts()`) plus the `wave_number` it resolved from `wave-scope.json`. Payload fields are flat at the record's top level:
@@ -391,7 +389,7 @@ If the commit itself fails (e.g., nothing to commit, pre-commit hook rejects), d
391
389
  > **What is NOT on the event, and stays hand-written:** `suite_platform` — the payload has no platform field, so keep writing it from the § 3a header as before. Likewise, the auto-fix-loop producer (`scripts/lib/quality-gate.mjs`, active only under `verification-auto-fix.enabled: true`) emits `counts` WITHOUT `wave_number`, so its retry records correctly never match the selector above; they are mid-wave attempts, not the wave's verdict. If the wave's gate ran outside `run-quality-gate.mjs` entirely, no event exists — fall back to the gate output you read, and say so in the progress update. The reader side (`skills/session-end/metrics-collection.md` § 1.7) reads the event first and this hand-written trio second, so keep writing the trio: it is the compatibility path for those two cases and for sessions already in flight.
392
390
  Append this wave record to the session metrics `waves` array.
393
391
 
394
- 7a. **Scope drift tripwire (S2 — #896, warn-only)**: distinct from `over_delivery_ratio` above — that metric is per-wave and unfiltered; this one is session-cumulative (since `session-start-ref`) and filtered through `DRIFT_EXCLUDE_PATTERNS`, so the two numbers are NOT expected to agree. Call `computeDrift()` from the same `scripts/lib/scope-baseline.mjs` module as `wave-loop-dispatch.md` § 0a Scope Baseline Freeze. Never blocks — exit code stays 0 and the next wave is dispatched regardless of the result.
392
+ 7a. **Scope drift tripwire (S2 — #896, warn-only)**: session-cumulative and filtered through `DRIFT_EXCLUDE_PATTERNS`, so its `filesRatio` is NOT expected to agree with this wave's unfiltered `files_changed` from step 7. Only the committed part of its numerator starts at `session-start-ref`; the uncommitted and untracked parts read the checkout as it is now, so files already dirty at session start and a same-checkout peer's files count too (an over-report, named as a ceiling in `computeDrift()`'s JSDoc). Call `computeDrift()` from the same `scripts/lib/scope-baseline.mjs` module as `wave-loop-dispatch.md` § 0a Scope Baseline Freeze. Never blocks — exit code stays 0 and the next wave is dispatched regardless of the result.
395
393
 
396
394
  ```js
397
395
  import { computeDrift } from '$PLUGIN_ROOT/scripts/lib/scope-baseline.mjs';
@@ -405,7 +403,7 @@ If the commit itself fails (e.g., nothing to commit, pre-commit hook rejects), d
405
403
  }
406
404
  ```
407
405
 
408
- Include the WARN line verbatim in the wave progress update when `breached` is true — name `filesRatio`, `plannedFiles`, `actualFiles`, and the configured `threshold`, not merely the word "drift". `drift.skipped === true` (`no-state-md`, `unreadable-state-md`, `no-baseline`, `stale-baseline`, or `unresolvable-ref` — see `computeDrift()`'s JSDoc for the precedence order) is silent: no WARN, no progress-update line. `persistence: false` implies `no-state-md`, so this step degrades to a silent no-op in that mode without a separate gate check.
406
+ Include the WARN line verbatim in the wave progress update when `breached` is true — name `filesRatio`, `plannedFiles`, `actualFiles`, and the configured `threshold`, not merely the word "drift". `drift.skipped === true` (`no-state-md`, `unreadable-state-md`, `no-baseline`, `stale-baseline`, `no-baseline-ref`, or `unresolvable-ref` — see `computeDrift()`'s JSDoc for the precedence order) is silent: no WARN, no progress-update line. `persistence: false` implies `no-state-md`, so this step degrades to a silent no-op in that mode without a separate gate check.
409
407
 
410
408
  ### 3. Adapt Plan (if needed)
411
409
 
@@ -446,13 +444,13 @@ After each wave completes and before the progress update, update `<state-dir>/ST
446
444
 
447
445
  1. **Frontmatter**: set `current-wave` to the just-completed wave number; set `status` to `active` (or `paused` if waiting on user input). Readers that need the RUNNING wave (e.g. `scripts/memory-propose.mjs`) read `<state-dir>/wave-scope.json` `wave` (only when the manifest is bound to this session via `semantic_session_id`; an unbound manifest is ignored — it may be a peer's, #1123) and fall back to `current-wave + 1` (#1166) — do not change this field's meaning.
448
446
  2. **`## Current Wave`**: replace contents with next wave info — wave number, role, agents to dispatch and count
449
- 3. **`## Wave History`**: append an entry for the completed wave (the `(planned … → actual …, over-delivery …)` parenthetical is omitted when `grounding-check: false`, since the counts are unavailable):
447
+ 3. **`## Wave History`**: append an entry for the completed wave:
450
448
  > **Record the SUITE COUNT, not just "gates green" — and name the platform (#944).** The wave line MUST carry the full-suite pass/fail count from the gate that just ran (`<passed>/<failed>`), not merely that typecheck and lint were clean. A deep session on 2026-07-30 logged typecheck/lint/validate-plugin for every wave and no suite count; a test that had been vacuous for its entire life sat red on HEAD through three waves and was found only by the review panel — in a session whose own premise was turning CI from red to green.
451
449
  >
452
450
  > **A green gate on one platform is not evidence for another.** That same session's local gate reported 541/541 three times on a tree CI could not build: two tests encoded macOS assumptions (a `TMPDIR` that carries a trailing slash; an `ARG_MAX` that tolerates a 200 KB argv entry). Both passed locally and failed on the Linux runner. When the wave touched anything platform-sensitive — spawn/argv shapes, `os.tmpdir()`, path separators, file modes, `$PATH` lookups of external binaries — say so in the wave line, and treat CI, not the local run, as the verdict.
453
451
 
454
452
  ```
455
- ### Wave N — <Role> (planned <P> files → actual <A>, over-delivery <R>) — suite <passed>/<failed> on <platform>
453
+ ### Wave N — <Role> — suite <passed>/<failed> on <platform>
456
454
  - Agent "<description>": <done|partial|failed> — <files changed> — <1-line note>
457
455
  - Agent "<description>": <done|partial|failed> — <files changed> — <1-line note>
458
456
  ```
@@ -16,12 +16,12 @@ Before each wave dispatch:
16
16
  **Deriving `blockedCommands` (effective floor∪overlay policy, #155/#972):** Before writing `wave-scope.json`, derive the blocked patterns from the EFFECTIVE policy via the shared merge module — the plugin's floor policy united with the repo's overlay policy. (A bare `jq` over the repo-local policy file alone under-counts the merged result since #972.)
17
17
  ```bash
18
18
  BLOCKED=$(node --input-type=module -e "
19
- import { loadEffectivePolicy } from '$PLUGIN_ROOT/scripts/lib/blocked-commands-policy.mjs';
19
+ import { loadEffectivePolicy, blockedCommandPatterns } from '$PLUGIN_ROOT/scripts/lib/blocked-commands-policy.mjs';
20
20
  const { rules } = await loadEffectivePolicy({ cwd: process.cwd(), projectDir: process.env.CLAUDE_PROJECT_DIR ?? null, pluginRoot: '$PLUGIN_ROOT' });
21
- console.log(JSON.stringify((rules ?? []).filter(r => r.severity === 'block').map(r => r.pattern)));
21
+ console.log(JSON.stringify(blockedCommandPatterns(rules)));
22
22
  ")
23
23
  ```
24
- Use `$BLOCKED` as the `blockedCommands` value in `wave-scope.json`. Since #972 this is the effective floor∪overlay policy — identical to what the destructive-guard hook enforces.
24
+ Use `$BLOCKED` as the `blockedCommands` value in `wave-scope.json`. Since #972 the rules come from the effective floor∪overlay policy the destructive-guard hook enforces. `blockedCommandPatterns()` keeps only the UNTYPED `block` rules (#1509): a typed rule (`redirect-truncate`, `path-delete`) carries a target-decided `pattern` (`">"`, a free-text label) that `hooks/enforce-commands.mjs` would misread as a command pattern. The destructive guard still enforces the typed rules on every Bash call — do not re-inline the filter here.
25
25
 
26
26
  **Fallback:** If the command fails or prints `[]` (neither the plugin's floor policy nor a repo policy resolvable — pre-#155 setup), use the legacy hardcoded array and log a warning in the wave progress update:
27
27
  ```bash
@@ -49,7 +49,7 @@ Before each wave dispatch:
49
49
  "session_id": "<raw session id from attributionForRecord(); OMIT the key if unavailable>",
50
50
  "semantic_session_id": "<semantic_session_id from the same call; OMIT if unavailable>",
51
51
  "allowedPaths": ["<from agent specs in session plan>"],
52
- "blockedCommands": "<derived dynamically from the effective floor∪overlay policy via loadEffectivePolicy (severity: block rules, #972); falls back to legacy 5-element array if no policy resolves>",
52
+ "blockedCommands": "<derived dynamically from the effective floor∪overlay policy via loadEffectivePolicy + blockedCommandPatterns (untyped severity: block rules, #972/#1509); falls back to legacy 5-element array if no policy resolves>",
53
53
  "gates": "<copy of enforcement-gates from Session Config, or omit if unset>"
54
54
  }
55
55
  ```
@@ -163,4 +163,12 @@ Before each wave dispatch:
163
163
  5. Delete `<state-dir>/wave-scope.json`
164
164
  6. Write Phase 2 wave-scope.json with test file allowedPaths (`**/*.test.*`, `**/*.spec.*`, `**/__tests__/**`)
165
165
  7. Dispatch test/review agents
166
- 7. After the final wave completes, delete `<state-dir>/wave-scope.json` (cleanup). Delete `<state-dir>/filescopes/` in the same step — the per-agent scope files (§ 3.1) are wave-local working state, and a stale `wave-<N>/` directory left behind is a scope claim nobody re-verified.
166
+ 7. After the final wave completes, delete `<state-dir>/wave-scope.json` (cleanup). Delete `<state-dir>/filescopes/` in the same step — the per-agent scope files (§ 3.1) are wave-local working state, and a stale `wave-<N>/` directory left behind is a scope claim nobody re-verified. Delete THIS session's dispatch ledger in the same step too — `hooks/pre-task-scope-disjoint.mjs` keeps one file per session since #1493, `.orchestrator/wave-dispatch-scopes.<session-id>.json` plus its `.lock`, under the session root (the repo root, or the worktree the session entered). Only your own: a file beside it named after another id holds a peer session's live claims. Delete only an id that is already path-safe (the hook names the file after it unchanged); anything else is left behind, inert, because no other session reads it:
167
+
168
+ ```bash
169
+ SID="${CLAUDE_CODE_SESSION_ID:-}"
170
+ case "$SID" in
171
+ ''|*[!A-Za-z0-9._-]*) ;; # no id on this harness, or not path-safe: leave the file
172
+ *) rm -f ".orchestrator/wave-dispatch-scopes.$SID.json" ".orchestrator/wave-dispatch-scopes.$SID.lock" ;;
173
+ esac
174
+ ```
@@ -39,7 +39,7 @@ Subject-matter experts (SMEs) reviewing outputs for technical correctness — ac
39
39
 
40
40
  **Exemplars:** `accounting-tax-advisor.v1.md`, `klima-ai-expert.v1.md`, `klima-physicist.v1.md`
41
41
 
42
- **Recommended model:** `claude-opus-4-7` — Opus surfaces nuances Sonnet misses (vault learning `[[persona-opus-finds-real-failing-cibadge]]`).
42
+ **Recommended model:** the Opus tier via alias `opus` — Opus surfaces nuances Sonnet misses (vault learning `[[persona-opus-finds-real-failing-cibadge]]`); the alias tracks the current Opus; pin a full model ID only for a named reproducibility need.
43
43
 
44
44
  #### `buyer-persona`
45
45
 
@@ -47,7 +47,7 @@ Synthetic archetype of a target customer reviewing for market fit, pain-point re
47
47
 
48
48
  **Exemplars:** `buyer-p1-cto.v1.md` through `buyer-p6-ld.v1.md` (6-persona set covering CTO, Kanzlei, Build-buyer, Tech-veto, Solopreneur, L&D).
49
49
 
50
- **Recommended model:** `claude-opus-4-7` for high-stakes go/no-go reviews; Sonnet acceptable for lower-stakes copy tests.
50
+ **Recommended model:** alias `opus` (tracks the current Opus) for high-stakes go/no-go reviews; Sonnet acceptable for lower-stakes copy tests.
51
51
 
52
52
  #### `compliance`
53
53
 
@@ -55,7 +55,7 @@ Compliance officers auditing outputs against regulation (GDPR/DSGVO, tax law, se
55
55
 
56
56
  **Exemplar:** `accounting-compliance.v1.md` (DSGVO Art. 5/17/20 audit trail).
57
57
 
58
- **Recommended model:** `claude-opus-4-7` — false negatives in compliance reviews are expensive.
58
+ **Recommended model:** alias `opus` (tracks the current Opus) — false negatives in compliance reviews are expensive.
59
59
 
60
60
  #### `auditor`
61
61
 
@@ -63,7 +63,7 @@ Independent auditor checking that outputs match a stated standard, framework, or
63
63
 
64
64
  **No exemplar yet — first author should propose a starter template.**
65
65
 
66
- **Recommended model:** `claude-opus-4-7` for high-stakes audits; Sonnet for routine standard-conformance checks.
66
+ **Recommended model:** alias `opus` (tracks the current Opus) for high-stakes audits; Sonnet for routine standard-conformance checks.
67
67
 
68
68
  #### `reviewer`
69
69
 
@@ -119,7 +119,7 @@ name: tax-law-reviewer
119
119
  schema_version: 1
120
120
  version: "1"
121
121
  role: "Austrian tax accountant reviewing accounting AI outputs for UStG/BAO law compliance"
122
- model: claude-opus-4-7
122
+ model: opus
123
123
  tier: domain-expert
124
124
  evaluation_criteria:
125
125
  - "UStG compliance: VAT rate and reverse-charge correctly applied to outputs"
@@ -3,7 +3,7 @@ name: accounting-compliance
3
3
  schema_version: 1
4
4
  version: "1"
5
5
  role: "DSGVO/GDPR Compliance Officer — audits AI-accountant outputs for privacy and audit-trail conformance"
6
- model: claude-opus-4-7
6
+ model: opus
7
7
  tier: compliance
8
8
  evaluation_criteria:
9
9
  - "Keine PII im Output: kein Klarname, E-Mail, IBAN ausserhalb des eigenen Mandanten-Kontexts"
@@ -3,7 +3,7 @@ name: accounting-tax-advisor
3
3
  schema_version: 1
4
4
  version: "1"
5
5
  role: "Austrian Steuerberater (StBKO §47) — reviews AI-accountant outputs for AT tax-law compliance"
6
- model: claude-opus-4-7
6
+ model: opus
7
7
  tier: domain-expert
8
8
  evaluation_criteria:
9
9
  - "UStG-Konformität: correct VAT rate applied; exemptions follow §6 UStG; Reverse-Charge correctly identified"
@@ -3,7 +3,7 @@ name: buyer-p1-cto
3
3
  schema_version: 1
4
4
  version: "1"
5
5
  role: "CTO, Mittelstand-Maschinenbau (~180 FTE) — bewertet B2B-AI-Produkt aus technischer Einkäuferperspektive"
6
- model: claude-opus-4-7
6
+ model: opus
7
7
  tier: buyer-persona
8
8
  evaluation_criteria:
9
9
  - "Tech-Stack-Fit: kompatibel mit Microsoft 365, on-prem AD, kein erzwungener Cloud-Lock-in"
@@ -3,7 +3,7 @@ name: buyer-p2-kanzlei
3
3
  schema_version: 1
4
4
  version: "1"
5
5
  role: "Kanzleipartnerin, AT-Steuerkanzlei (~75 FTE) — bewertet AI-Buchhaltungstool aus Kanzlei-Perspektive"
6
- model: claude-opus-4-7
6
+ model: opus
7
7
  tier: buyer-persona
8
8
  evaluation_criteria:
9
9
  - "BMD/RZL/DATEV-Kompatibilität: Import/Export ohne manuelle Nachbearbeitung in bestehende Kanzlei-Software"
@@ -3,7 +3,7 @@ name: buyer-p3-build
3
3
  schema_version: 1
4
4
  version: "1"
5
5
  role: "Procurement Manager im Tier-2-Mittelstand — bewertet B2B-Software-Anbieter aus Beschaffungsperspektive (TCO, Vendor-Lock-In, Exit-Klauseln)"
6
- model: claude-opus-4-7
6
+ model: opus
7
7
  tier: buyer-persona
8
8
  evaluation_criteria:
9
9
  - "TCO-Transparenz: aufgeschlüsselte Gesamtkosten über 3–5 Jahre inkl. Lizenz, Integration, Schulung und Support — kein 'Kontaktieren Sie uns für Enterprise-Preise'"
@@ -3,7 +3,7 @@ name: buyer-p4-tech-veto
3
3
  schema_version: 1
4
4
  version: "1"
5
5
  role: "Engineering Manager, B2B-SaaS (~120 Entwickler) — bewertet Tool-Adoptionen mit Veto-Recht aus Dev-Ops-Perspektive"
6
- model: claude-opus-4-7
6
+ model: opus
7
7
  tier: buyer-persona
8
8
  evaluation_criteria:
9
9
  - "Developer-Experience-Impact: messbare Velocity-Steigerung (Deploy-Zeit, Incident-Rate) ohne Setup-Overhead, der das Team ausbremst"
@@ -3,7 +3,7 @@ name: buyer-p5-solo
3
3
  schema_version: 1
4
4
  version: "1"
5
5
  role: "Solo-Gründer, 1-Person-SaaS/Beratung (1–10 FTE, bootstrapped) — bewertet Tools aus frugal-pragmatischer Gründerperspektive"
6
- model: claude-opus-4-7
6
+ model: opus
7
7
  tier: buyer-persona
8
8
  evaluation_criteria:
9
9
  - "Time-to-Revenue: Tool zahlt sich in unter 30 Tagen aus — messbarer Umsatz-Impact ab Monat 1, kein 'investiere jetzt für späteren Wert'"
@@ -3,7 +3,7 @@ name: buyer-p6-ld
3
3
  schema_version: 1
4
4
  version: "1"
5
5
  role: "Learning & Development Managerin, Konzern (~1500 MA) — bewertet Lernplattformen aus L&D-Perspektive (ROI, LMS-Integration, Completion-Rates)"
6
- model: claude-opus-4-7
6
+ model: opus
7
7
  tier: buyer-persona
8
8
  evaluation_criteria:
9
9
  - "Completion-Rate-Uplift: messbare Steigerung der Lernabschluss-Quote vs. Baseline, Pilotdaten aus vergleichbaren Organisationen verfügbar"
@@ -3,7 +3,7 @@ name: klima-ai-expert
3
3
  schema_version: 1
4
4
  version: "1"
5
5
  role: "AI/ML Suitability Reviewer, climate research — rates research questions on AI-method fit"
6
- model: claude-opus-4-7
6
+ model: opus
7
7
  tier: domain-expert
8
8
  evaluation_criteria:
9
9
  - "D1 Datenverfügbarkeit (0-3): sufficient labeled or unlabeled corpus exists for training/validation"
@@ -3,7 +3,7 @@ name: klima-physicist
3
3
  schema_version: 1
4
4
  version: "1"
5
5
  role: "PhD Physicist, Climate Dynamics — peer-reviews research statements for methodological rigor"
6
- model: claude-opus-4-7
6
+ model: opus
7
7
  tier: domain-expert
8
8
  evaluation_criteria:
9
9
  - "Methodische Korrektheit: experimental design is valid, hypotheses are falsifiable, controls are adequate"