@staix/agent-hub 0.19.0 → 0.21.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 (184) hide show
  1. package/CHANGELOG.md +70 -3
  2. package/README.md +2 -2
  3. package/docs/agent-notes/README.md +11 -0
  4. package/docs/agent-notes/adapters.md +10 -5
  5. package/docs/agent-notes/benchmarks.md +27 -0
  6. package/docs/agent-notes/budget.md +2 -1
  7. package/docs/agent-notes/bus.md +3 -3
  8. package/docs/agent-notes/daemon.md +20 -7
  9. package/docs/agent-notes/local-worker.md +5 -0
  10. package/docs/agent-notes/models.md +2 -0
  11. package/docs/agent-notes/tasks.md +20 -10
  12. package/docs/agent-notes/tests.md +13 -5
  13. package/docs/bench.md +1 -1
  14. package/docs/data-policy.md +2 -0
  15. package/docs/dogfood.md +41 -5
  16. package/docs/events.md +2 -1
  17. package/docs/memory.md +9 -3
  18. package/docs/operations.md +598 -63
  19. package/docs/profiles.md +13 -1
  20. package/docs/quickstart.md +18 -9
  21. package/docs/research.md +7 -4
  22. package/docs/sdlc.md +66 -10
  23. package/docs/security.md +397 -35
  24. package/docs/smoke.md +127 -0
  25. package/docs/specs/2026-09-19-agent-hub-design.md +1149 -19
  26. package/docs/verification/2026-10-27-0.19.0.md +5 -5
  27. package/docs/verification/2026-10-27-0.20.0.md +75 -0
  28. package/docs/verification/2026-10-28-claude-2.1.311-2.1.312-bash-permission.json +635 -0
  29. package/docs/verification/2026-10-28-claude-2.1.311-2.1.312-permission-transport.json +403 -0
  30. package/docs/verification/2026-10-28-claude-implementer-permission-triage.md +123 -0
  31. package/docs/verification/2026-10-28-jcode-0.99.1-usage.md +41 -0
  32. package/docs/verification/2026-10-28-realpath-name-audit.md +222 -0
  33. package/docs/verification/2026-10-28-routing-f0bb8ad0.md +1000 -0
  34. package/docs/verification/2026-10-29-0.21.0.md +61 -0
  35. package/docs/verification/2026-10-29-model-effort-capabilities.md +123 -0
  36. package/docs/verification/2026-10-29-modelrouting-b152ddb9.md +953 -0
  37. package/docs/verification/claude-implementer-permission-triage.ts +160 -0
  38. package/docs/verification/claude-permission-transport-native.py +71 -14
  39. package/docs/verification/profiles/YYYY-MM-DD-research.md +1 -1
  40. package/docs/verified.json +26 -18
  41. package/package.json +2 -2
  42. package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
  43. package/plugins/agent-hub/server.js +1116 -284
  44. package/src/adapters/acp.ts +87 -3
  45. package/src/adapters/channel-peer.ts +11 -5
  46. package/src/adapters/claude-channel.ts +13 -6
  47. package/src/adapters/claude-implementer.ts +61 -7
  48. package/src/adapters/codex-appserver.ts +88 -5
  49. package/src/adapters/conformance/enrollment.ts +4 -4
  50. package/src/adapters/conformance/factories.ts +2 -1
  51. package/src/adapters/conformance/fakes/jcode-agent.ts +6 -2
  52. package/src/adapters/conformance/kit.ts +10 -6
  53. package/src/adapters/definitions/builtin-metadata.ts +3 -114
  54. package/src/adapters/definitions/native-config-defaults.ts +1 -1
  55. package/src/adapters/definitions/native-config-policy.ts +3 -2
  56. package/src/adapters/definitions/native-context.ts +12 -0
  57. package/src/adapters/external-metadata.ts +48 -0
  58. package/src/adapters/external-modules.ts +63 -3
  59. package/src/adapters/jcode.ts +6 -2
  60. package/src/adapters/local-worker.ts +42 -25
  61. package/src/adapters/native-proof-ports.ts +10 -0
  62. package/src/adapters/pi.ts +7 -0
  63. package/src/adapters/registry-types.ts +4 -0
  64. package/src/adapters/reviewer-print.ts +1 -0
  65. package/src/broker/protocol.ts +203 -0
  66. package/src/broker/server.ts +314 -0
  67. package/src/broker/store.ts +548 -0
  68. package/src/cli/bench.ts +3 -2
  69. package/src/cli/broker.ts +58 -0
  70. package/src/cli/conductor-recovery.ts +142 -0
  71. package/src/cli/configured-acp-entry.ts +26 -6
  72. package/src/cli/console-state.ts +59 -17
  73. package/src/cli/console.ts +17 -2
  74. package/src/cli/facts-hook.ts +3 -1
  75. package/src/cli/help.ts +28 -16
  76. package/src/cli/identity.ts +23 -10
  77. package/src/cli/init.ts +34 -7
  78. package/src/cli/intake-output.ts +33 -0
  79. package/src/cli/main.ts +314 -71
  80. package/src/cli/output.ts +41 -1
  81. package/src/cli/recovery-package.ts +18 -1
  82. package/src/cli/role-holders.ts +35 -0
  83. package/src/cli/room.ts +304 -0
  84. package/src/cli/say-input.ts +16 -0
  85. package/src/cli/schedule-output.ts +49 -0
  86. package/src/cli/sdlc-output.ts +44 -6
  87. package/src/cli/smoke-pty-bridge.ts +33 -0
  88. package/src/cli/smoke-pty.ts +145 -0
  89. package/src/cli/smoke-run.ts +139 -0
  90. package/src/cli/smoke-target.ts +130 -0
  91. package/src/cli/source-output.ts +29 -0
  92. package/src/cli/task-output.ts +3 -2
  93. package/src/cli/upgrade-runtime.ts +98 -16
  94. package/src/cli/upgrade.ts +66 -7
  95. package/src/hub/ask.ts +76 -12
  96. package/src/hub/board.ts +132 -22
  97. package/src/hub/bus.ts +399 -56
  98. package/src/hub/child-process.ts +2 -0
  99. package/src/hub/ci-watch.ts +162 -0
  100. package/src/hub/claude-failure-stage.ts +85 -0
  101. package/src/hub/claude-launch-proof.ts +67 -2
  102. package/src/hub/claude-shell-wrapper.ts +11 -5
  103. package/src/hub/conductor.ts +17 -4
  104. package/src/hub/config-apply.ts +32 -5
  105. package/src/hub/config-reload.ts +7 -5
  106. package/src/hub/config-trust.ts +8 -1
  107. package/src/hub/context-window.ts +33 -3
  108. package/src/hub/control-client.ts +14 -2
  109. package/src/hub/corpus-config.ts +34 -0
  110. package/src/hub/corpus-evidence.ts +184 -0
  111. package/src/hub/corpus.ts +373 -0
  112. package/src/hub/cost-governance.ts +26 -0
  113. package/src/hub/daemon.ts +1228 -242
  114. package/src/hub/deliverable-files.ts +8 -2
  115. package/src/hub/delivery-journal.ts +123 -17
  116. package/src/hub/dogfood-profile.ts +32 -5
  117. package/src/hub/dogfood-read.ts +6 -2
  118. package/src/hub/envelope.ts +11 -0
  119. package/src/hub/eval-gate.ts +131 -0
  120. package/src/hub/events.ts +1 -1
  121. package/src/hub/external-instance.ts +69 -0
  122. package/src/hub/facts.ts +15 -5
  123. package/src/hub/folder-trigger.ts +223 -0
  124. package/src/hub/hub-tools.ts +2 -1
  125. package/src/hub/inference.ts +20 -5
  126. package/src/hub/instance-config.ts +69 -3
  127. package/src/hub/instance-execution.ts +6 -2
  128. package/src/hub/instances.ts +32 -4
  129. package/src/hub/intake.ts +125 -0
  130. package/src/hub/learning.ts +85 -0
  131. package/src/hub/lifecycle.ts +7 -3
  132. package/src/hub/limits.ts +12 -5
  133. package/src/hub/native-permission-request.ts +77 -0
  134. package/src/hub/operational-authority.ts +63 -5
  135. package/src/hub/operational-settings.ts +76 -0
  136. package/src/hub/operational-view.ts +1 -1
  137. package/src/hub/packs.ts +132 -0
  138. package/src/hub/path-policy.ts +7 -0
  139. package/src/hub/peer-doing.ts +130 -0
  140. package/src/hub/peers.ts +46 -0
  141. package/src/hub/queue-backpressure.ts +58 -0
  142. package/src/hub/read-tools.ts +2 -0
  143. package/src/hub/recovery-authority.ts +151 -0
  144. package/src/hub/recovery-policy.ts +220 -0
  145. package/src/hub/research.ts +24 -14
  146. package/src/hub/restart.ts +7 -0
  147. package/src/hub/routing.ts +54 -11
  148. package/src/hub/schedules.ts +266 -0
  149. package/src/hub/sdlc-merge.ts +38 -14
  150. package/src/hub/sdlc-metrics.ts +32 -10
  151. package/src/hub/sdlc-queue.ts +7 -1
  152. package/src/hub/sdlc-release.ts +1 -1
  153. package/src/hub/sdlc.ts +37 -7
  154. package/src/hub/security-baseline.ts +38 -0
  155. package/src/hub/settings.ts +7 -1
  156. package/src/hub/shipped-packs.ts +8 -0
  157. package/src/hub/snapshots.ts +72 -6
  158. package/src/hub/source-read.ts +160 -0
  159. package/src/hub/sources.ts +311 -0
  160. package/src/hub/task-shell-default.ts +3 -2
  161. package/src/hub/tasks.ts +1047 -115
  162. package/src/hub/workflow.ts +1 -1
  163. package/src/local/deny.ts +21 -0
  164. package/src/local/doc-read.ts +69 -0
  165. package/src/local/proxy.ts +4 -13
  166. package/src/local/sandbox.ts +3 -1
  167. package/src/local/tools.ts +37 -3
  168. package/src/local/web-fetch-config.ts +43 -0
  169. package/src/local/web-fetch.ts +183 -0
  170. package/src/memory/brief.ts +85 -13
  171. package/src/memory/capture.ts +1 -1
  172. package/src/rooms/application.ts +114 -0
  173. package/src/rooms/boundary.ts +103 -0
  174. package/src/rooms/commands.ts +294 -0
  175. package/src/rooms/crypto.ts +371 -0
  176. package/src/rooms/link.ts +584 -0
  177. package/src/rooms/policy.ts +82 -0
  178. package/src/rooms/remote-peer.ts +80 -0
  179. package/src/rooms/service.ts +426 -0
  180. package/src/rooms/status.ts +146 -0
  181. package/src/rooms/store.ts +1210 -0
  182. package/src/rooms/wire.ts +465 -0
  183. package/src/ui/index.html +91 -4
  184. package/templates/packs/example.pack.json +13 -0
@@ -0,0 +1,1000 @@
1
+ # Routing promotion receipt: f0bb8ad0
2
+
3
+ Surface: task-routing. Corpus 1d3acc7cbf60, split `test` (24 cases). Generated 2026-10-28.
4
+ Verdict: **pass**.
5
+
6
+ - Current default (`HEAD`): sha256 `f0bb8ad0b4b544df2a5287103578235fa92aec80fa8cb8773ddec87c91e71b29`
7
+ - Candidate (`templates/routing.toml`): sha256 `f0bb8ad0b4b544df2a5287103578235fa92aec80fa8cb8773ddec87c91e71b29`
8
+ - Keys that differ: none (the same policy)
9
+ - Served model ids: not applicable: task routing calls no model. Model-routing keys (hub_routes, local.route, fixed_model) are not exercised by this corpus; their corpus and served model ids are #637 part 2.
10
+
11
+ | Metric | Current default | Candidate |
12
+ | --- | --- | --- |
13
+ | owner top-1 accuracy (primary) | 100.0% (24/24) | 100.0% (24/24) |
14
+ | reviewer accuracy (22 cases) | 100.0% | 100.0% |
15
+ | whole-case pass rate | 100.0% | 100.0% |
16
+
17
+ Regressions: none. PII or refusal regressions: none. Improvements: none.
18
+
19
+ ```json receipt
20
+ {
21
+ "kind": "routing-receipt",
22
+ "version": 1,
23
+ "surface": "task-routing",
24
+ "corpus_hash": "1d3acc7cbf60eb3d6703c857643404cf2ba025165a5e95fa8c6baa98c7b0cc4f",
25
+ "split": "test",
26
+ "base": {
27
+ "ref": "HEAD",
28
+ "sha256": "f0bb8ad0b4b544df2a5287103578235fa92aec80fa8cb8773ddec87c91e71b29",
29
+ "config": {
30
+ "classes": {
31
+ "bulk_edit": {
32
+ "escalate_to": [
33
+ "codex",
34
+ "kimi"
35
+ ],
36
+ "fixed_model": "fast",
37
+ "peers": [
38
+ "pi",
39
+ "local",
40
+ "kimi"
41
+ ],
42
+ "pi_backend": "dgx"
43
+ },
44
+ "implement": {
45
+ "escalate_to": [
46
+ "codex",
47
+ "kimi",
48
+ "claude"
49
+ ],
50
+ "peers": [
51
+ "pi",
52
+ "local",
53
+ "codex",
54
+ "kimi"
55
+ ],
56
+ "pi_backend": "dgx",
57
+ "route": "hub/stage"
58
+ },
59
+ "plan": {
60
+ "local_allowed": false,
61
+ "peers": [
62
+ "claude",
63
+ "codex"
64
+ ]
65
+ },
66
+ "review": {
67
+ "local_allowed": false,
68
+ "peers": [
69
+ "claude",
70
+ "codex"
71
+ ]
72
+ },
73
+ "summarize": {
74
+ "escalate_to": [
75
+ "codex",
76
+ "kimi"
77
+ ],
78
+ "fixed_model": "fast",
79
+ "peers": [
80
+ "pi",
81
+ "local",
82
+ "kimi"
83
+ ],
84
+ "pi_backend": "mlx"
85
+ },
86
+ "test": {
87
+ "escalate_to": [
88
+ "codex",
89
+ "kimi"
90
+ ],
91
+ "fixed_model": "fast",
92
+ "peers": [
93
+ "pi",
94
+ "local",
95
+ "kimi",
96
+ "codex"
97
+ ],
98
+ "pi_backend": "dgx"
99
+ },
100
+ "triage": {
101
+ "escalate_to": [
102
+ "codex",
103
+ "kimi"
104
+ ],
105
+ "fixed_model": "fast",
106
+ "peers": [
107
+ "pi",
108
+ "local",
109
+ "kimi"
110
+ ],
111
+ "pi_backend": "mlx"
112
+ }
113
+ },
114
+ "constraints": {
115
+ "budget_paused": "skip_peer",
116
+ "long_context": "skip_local",
117
+ "pii": "local_only"
118
+ },
119
+ "hub_routes": {
120
+ "hub/advisor": {
121
+ "capable": "coding",
122
+ "efficient": "fast",
123
+ "gate_min_tool_results": 1,
124
+ "max_reviews": 1,
125
+ "trigger": "no_tool_call",
126
+ "type": "advisor"
127
+ },
128
+ "hub/escalation": {
129
+ "capable": "coding",
130
+ "confirmations": 2,
131
+ "efficient": "fast",
132
+ "type": "escalation"
133
+ },
134
+ "hub/plan": {
135
+ "capable": "coding",
136
+ "efficient": "fast",
137
+ "type": "plan_execute"
138
+ },
139
+ "hub/stage": {
140
+ "capable": "coding",
141
+ "confidence_threshold": 0.5,
142
+ "efficient": "fast",
143
+ "hold_turns": 2,
144
+ "type": "stage"
145
+ }
146
+ },
147
+ "local": {
148
+ "fixed_model": "coding",
149
+ "route": "hub/stage"
150
+ },
151
+ "max_switch_prefill_tokens": 32000,
152
+ "pi": {
153
+ "dgx_max_context_tokens": 262144,
154
+ "mlx_max_context_tokens": 16000
155
+ },
156
+ "signals": {
157
+ "long_context_tokens": 120000,
158
+ "pii_patterns": [
159
+ "\\b\\d{6}-\\d{7}\\b"
160
+ ],
161
+ "pii_screen": "off"
162
+ },
163
+ "stay_switch": "shadow"
164
+ }
165
+ },
166
+ "candidate": {
167
+ "sha256": "f0bb8ad0b4b544df2a5287103578235fa92aec80fa8cb8773ddec87c91e71b29",
168
+ "config": {
169
+ "classes": {
170
+ "bulk_edit": {
171
+ "escalate_to": [
172
+ "codex",
173
+ "kimi"
174
+ ],
175
+ "fixed_model": "fast",
176
+ "peers": [
177
+ "pi",
178
+ "local",
179
+ "kimi"
180
+ ],
181
+ "pi_backend": "dgx"
182
+ },
183
+ "implement": {
184
+ "escalate_to": [
185
+ "codex",
186
+ "kimi",
187
+ "claude"
188
+ ],
189
+ "peers": [
190
+ "pi",
191
+ "local",
192
+ "codex",
193
+ "kimi"
194
+ ],
195
+ "pi_backend": "dgx",
196
+ "route": "hub/stage"
197
+ },
198
+ "plan": {
199
+ "local_allowed": false,
200
+ "peers": [
201
+ "claude",
202
+ "codex"
203
+ ]
204
+ },
205
+ "review": {
206
+ "local_allowed": false,
207
+ "peers": [
208
+ "claude",
209
+ "codex"
210
+ ]
211
+ },
212
+ "summarize": {
213
+ "escalate_to": [
214
+ "codex",
215
+ "kimi"
216
+ ],
217
+ "fixed_model": "fast",
218
+ "peers": [
219
+ "pi",
220
+ "local",
221
+ "kimi"
222
+ ],
223
+ "pi_backend": "mlx"
224
+ },
225
+ "test": {
226
+ "escalate_to": [
227
+ "codex",
228
+ "kimi"
229
+ ],
230
+ "fixed_model": "fast",
231
+ "peers": [
232
+ "pi",
233
+ "local",
234
+ "kimi",
235
+ "codex"
236
+ ],
237
+ "pi_backend": "dgx"
238
+ },
239
+ "triage": {
240
+ "escalate_to": [
241
+ "codex",
242
+ "kimi"
243
+ ],
244
+ "fixed_model": "fast",
245
+ "peers": [
246
+ "pi",
247
+ "local",
248
+ "kimi"
249
+ ],
250
+ "pi_backend": "mlx"
251
+ }
252
+ },
253
+ "constraints": {
254
+ "budget_paused": "skip_peer",
255
+ "long_context": "skip_local",
256
+ "pii": "local_only"
257
+ },
258
+ "hub_routes": {
259
+ "hub/advisor": {
260
+ "capable": "coding",
261
+ "efficient": "fast",
262
+ "gate_min_tool_results": 1,
263
+ "max_reviews": 1,
264
+ "trigger": "no_tool_call",
265
+ "type": "advisor"
266
+ },
267
+ "hub/escalation": {
268
+ "capable": "coding",
269
+ "confirmations": 2,
270
+ "efficient": "fast",
271
+ "type": "escalation"
272
+ },
273
+ "hub/plan": {
274
+ "capable": "coding",
275
+ "efficient": "fast",
276
+ "type": "plan_execute"
277
+ },
278
+ "hub/stage": {
279
+ "capable": "coding",
280
+ "confidence_threshold": 0.5,
281
+ "efficient": "fast",
282
+ "hold_turns": 2,
283
+ "type": "stage"
284
+ }
285
+ },
286
+ "local": {
287
+ "fixed_model": "coding",
288
+ "route": "hub/stage"
289
+ },
290
+ "max_switch_prefill_tokens": 32000,
291
+ "pi": {
292
+ "dgx_max_context_tokens": 262144,
293
+ "mlx_max_context_tokens": 16000
294
+ },
295
+ "signals": {
296
+ "long_context_tokens": 120000,
297
+ "pii_patterns": [
298
+ "\\b\\d{6}-\\d{7}\\b"
299
+ ],
300
+ "pii_screen": "off"
301
+ },
302
+ "stay_switch": "shadow"
303
+ }
304
+ },
305
+ "changed_keys": [],
306
+ "served_models": "not applicable: task routing calls no model. Model-routing keys (hub_routes, local.route, fixed_model) are not exercised by this corpus; their corpus and served model ids are #637 part 2.",
307
+ "evidence": {
308
+ "split": "test",
309
+ "n": 24,
310
+ "primary": {
311
+ "metric": "owner top-1 accuracy",
312
+ "base": 1,
313
+ "candidate": 1,
314
+ "baseCorrect": 24,
315
+ "candidateCorrect": 24
316
+ },
317
+ "secondary": {
318
+ "reviewer": {
319
+ "n": 22,
320
+ "base": 1,
321
+ "candidate": 1
322
+ },
323
+ "fullCase": {
324
+ "base": 1,
325
+ "candidate": 1
326
+ }
327
+ },
328
+ "regressions": [],
329
+ "guardRegressions": [],
330
+ "improvements": [],
331
+ "verdict": "pass",
332
+ "reasons": [],
333
+ "cases": [
334
+ {
335
+ "id": "pref-implement-pi-busy",
336
+ "expect": {
337
+ "owner": "local",
338
+ "reviewer": "claude"
339
+ },
340
+ "base": {
341
+ "owner": "local",
342
+ "reviewer": "claude",
343
+ "refusals": []
344
+ },
345
+ "candidate": {
346
+ "owner": "local",
347
+ "reviewer": "claude",
348
+ "refusals": []
349
+ },
350
+ "basePass": true,
351
+ "candidatePass": true
352
+ },
353
+ {
354
+ "id": "pref-implement-pi-offline",
355
+ "expect": {
356
+ "owner": "local",
357
+ "reviewer": "claude",
358
+ "refusals": [
359
+ "owner:pi:offline"
360
+ ]
361
+ },
362
+ "base": {
363
+ "owner": "local",
364
+ "reviewer": "claude",
365
+ "refusals": [
366
+ "owner:pi:offline"
367
+ ]
368
+ },
369
+ "candidate": {
370
+ "owner": "local",
371
+ "reviewer": "claude",
372
+ "refusals": [
373
+ "owner:pi:offline"
374
+ ]
375
+ },
376
+ "basePass": true,
377
+ "candidatePass": true
378
+ },
379
+ {
380
+ "id": "pref-implement-tier-absent-idle-before-busy",
381
+ "expect": {
382
+ "owner": "kimi",
383
+ "reviewer": "claude",
384
+ "refusals": [
385
+ "owner:pi:not-attached",
386
+ "owner:local:not-attached"
387
+ ]
388
+ },
389
+ "base": {
390
+ "owner": "kimi",
391
+ "reviewer": "claude",
392
+ "refusals": [
393
+ "owner:local:not-attached",
394
+ "owner:pi:not-attached"
395
+ ]
396
+ },
397
+ "candidate": {
398
+ "owner": "kimi",
399
+ "reviewer": "claude",
400
+ "refusals": [
401
+ "owner:local:not-attached",
402
+ "owner:pi:not-attached"
403
+ ]
404
+ },
405
+ "basePass": true,
406
+ "candidatePass": true
407
+ },
408
+ {
409
+ "id": "pref-test-all-idle",
410
+ "expect": {
411
+ "owner": "pi",
412
+ "reviewer": "claude"
413
+ },
414
+ "base": {
415
+ "owner": "pi",
416
+ "reviewer": "claude",
417
+ "refusals": []
418
+ },
419
+ "candidate": {
420
+ "owner": "pi",
421
+ "reviewer": "claude",
422
+ "refusals": []
423
+ },
424
+ "basePass": true,
425
+ "candidatePass": true
426
+ },
427
+ {
428
+ "id": "pref-triage-pi-paused",
429
+ "expect": {
430
+ "owner": "local",
431
+ "reviewer": "claude",
432
+ "refusals": [
433
+ "owner:pi:paused"
434
+ ]
435
+ },
436
+ "base": {
437
+ "owner": "local",
438
+ "reviewer": "claude",
439
+ "refusals": [
440
+ "owner:pi:paused"
441
+ ]
442
+ },
443
+ "candidate": {
444
+ "owner": "local",
445
+ "reviewer": "claude",
446
+ "refusals": [
447
+ "owner:pi:paused"
448
+ ]
449
+ },
450
+ "basePass": true,
451
+ "candidatePass": true
452
+ },
453
+ {
454
+ "id": "judge-plan-claude-offline",
455
+ "expect": {
456
+ "owner": "codex",
457
+ "reviewer": null
458
+ },
459
+ "base": {
460
+ "owner": "codex",
461
+ "reviewer": null,
462
+ "refusals": [
463
+ "owner:claude:offline",
464
+ "reviewer:claude:offline"
465
+ ]
466
+ },
467
+ "candidate": {
468
+ "owner": "codex",
469
+ "reviewer": null,
470
+ "refusals": [
471
+ "owner:claude:offline",
472
+ "reviewer:claude:offline"
473
+ ]
474
+ },
475
+ "basePass": true,
476
+ "candidatePass": true
477
+ },
478
+ {
479
+ "id": "judge-review-claude-busy",
480
+ "expect": {
481
+ "owner": "codex",
482
+ "reviewer": null
483
+ },
484
+ "base": {
485
+ "owner": "codex",
486
+ "reviewer": null,
487
+ "refusals": []
488
+ },
489
+ "candidate": {
490
+ "owner": "codex",
491
+ "reviewer": null,
492
+ "refusals": []
493
+ },
494
+ "basePass": true,
495
+ "candidatePass": true
496
+ },
497
+ {
498
+ "id": "judge-review-no-reviewer-attached",
499
+ "guard": "refusal",
500
+ "expect": {
501
+ "owner": null,
502
+ "refusals": [
503
+ "owner:claude:not-attached",
504
+ "owner:codex:not-attached"
505
+ ]
506
+ },
507
+ "base": {
508
+ "owner": null,
509
+ "reviewer": null,
510
+ "refusals": [
511
+ "owner:claude:not-attached",
512
+ "owner:codex:not-attached"
513
+ ]
514
+ },
515
+ "candidate": {
516
+ "owner": null,
517
+ "reviewer": null,
518
+ "refusals": [
519
+ "owner:claude:not-attached",
520
+ "owner:codex:not-attached"
521
+ ]
522
+ },
523
+ "basePass": true,
524
+ "candidatePass": true
525
+ },
526
+ {
527
+ "id": "pii-implement-local-offline",
528
+ "guard": "pii",
529
+ "expect": {
530
+ "owner": null,
531
+ "reviewer": "user",
532
+ "refusals": [
533
+ "owner:local:offline",
534
+ "owner:pi:pii",
535
+ "owner:codex:pii",
536
+ "owner:kimi:pii"
537
+ ]
538
+ },
539
+ "base": {
540
+ "owner": null,
541
+ "reviewer": "user",
542
+ "refusals": [
543
+ "owner:codex:pii",
544
+ "owner:kimi:pii",
545
+ "owner:local:offline",
546
+ "owner:pi:pii"
547
+ ]
548
+ },
549
+ "candidate": {
550
+ "owner": null,
551
+ "reviewer": "user",
552
+ "refusals": [
553
+ "owner:codex:pii",
554
+ "owner:kimi:pii",
555
+ "owner:local:offline",
556
+ "owner:pi:pii"
557
+ ]
558
+ },
559
+ "basePass": true,
560
+ "candidatePass": true
561
+ },
562
+ {
563
+ "id": "pii-implement-local-busy",
564
+ "guard": "pii",
565
+ "expect": {
566
+ "owner": "local",
567
+ "reviewer": "user",
568
+ "refusals": [
569
+ "owner:pi:pii"
570
+ ]
571
+ },
572
+ "base": {
573
+ "owner": "local",
574
+ "reviewer": "user",
575
+ "refusals": [
576
+ "owner:codex:pii",
577
+ "owner:kimi:pii",
578
+ "owner:pi:pii"
579
+ ]
580
+ },
581
+ "candidate": {
582
+ "owner": "local",
583
+ "reviewer": "user",
584
+ "refusals": [
585
+ "owner:codex:pii",
586
+ "owner:kimi:pii",
587
+ "owner:pi:pii"
588
+ ]
589
+ },
590
+ "basePass": true,
591
+ "candidatePass": true
592
+ },
593
+ {
594
+ "id": "pii-bulk-edit-local-paused",
595
+ "guard": "pii",
596
+ "expect": {
597
+ "owner": null,
598
+ "reviewer": "user",
599
+ "refusals": [
600
+ "owner:local:paused",
601
+ "owner:pi:pii",
602
+ "owner:kimi:pii"
603
+ ]
604
+ },
605
+ "base": {
606
+ "owner": null,
607
+ "reviewer": "user",
608
+ "refusals": [
609
+ "owner:kimi:pii",
610
+ "owner:local:paused",
611
+ "owner:pi:pii"
612
+ ]
613
+ },
614
+ "candidate": {
615
+ "owner": null,
616
+ "reviewer": "user",
617
+ "refusals": [
618
+ "owner:kimi:pii",
619
+ "owner:local:paused",
620
+ "owner:pi:pii"
621
+ ]
622
+ },
623
+ "basePass": true,
624
+ "candidatePass": true
625
+ },
626
+ {
627
+ "id": "pii-review-class",
628
+ "guard": "pii",
629
+ "expect": {
630
+ "owner": null,
631
+ "refusals": [
632
+ "owner:claude:pii",
633
+ "owner:codex:pii"
634
+ ]
635
+ },
636
+ "base": {
637
+ "owner": null,
638
+ "reviewer": "user",
639
+ "refusals": [
640
+ "owner:claude:pii",
641
+ "owner:codex:pii"
642
+ ]
643
+ },
644
+ "candidate": {
645
+ "owner": null,
646
+ "reviewer": "user",
647
+ "refusals": [
648
+ "owner:claude:pii",
649
+ "owner:codex:pii"
650
+ ]
651
+ },
652
+ "basePass": true,
653
+ "candidatePass": true
654
+ },
655
+ {
656
+ "id": "pii-test-pi-busy",
657
+ "guard": "pii",
658
+ "expect": {
659
+ "owner": "local",
660
+ "reviewer": "user",
661
+ "refusals": [
662
+ "owner:pi:pii",
663
+ "owner:kimi:pii",
664
+ "owner:codex:pii"
665
+ ]
666
+ },
667
+ "base": {
668
+ "owner": "local",
669
+ "reviewer": "user",
670
+ "refusals": [
671
+ "owner:codex:pii",
672
+ "owner:kimi:pii",
673
+ "owner:pi:pii"
674
+ ]
675
+ },
676
+ "candidate": {
677
+ "owner": "local",
678
+ "reviewer": "user",
679
+ "refusals": [
680
+ "owner:codex:pii",
681
+ "owner:kimi:pii",
682
+ "owner:pi:pii"
683
+ ]
684
+ },
685
+ "basePass": true,
686
+ "candidatePass": true
687
+ },
688
+ {
689
+ "id": "pii-triage-local-absent",
690
+ "guard": "pii",
691
+ "expect": {
692
+ "owner": null,
693
+ "reviewer": "user",
694
+ "refusals": [
695
+ "owner:local:not-attached",
696
+ "owner:pi:pii",
697
+ "owner:kimi:pii"
698
+ ]
699
+ },
700
+ "base": {
701
+ "owner": null,
702
+ "reviewer": "user",
703
+ "refusals": [
704
+ "owner:kimi:pii",
705
+ "owner:local:not-attached",
706
+ "owner:pi:pii"
707
+ ]
708
+ },
709
+ "candidate": {
710
+ "owner": null,
711
+ "reviewer": "user",
712
+ "refusals": [
713
+ "owner:kimi:pii",
714
+ "owner:local:not-attached",
715
+ "owner:pi:pii"
716
+ ]
717
+ },
718
+ "basePass": true,
719
+ "candidatePass": true
720
+ },
721
+ {
722
+ "id": "long-summarize-skips-pi-and-local",
723
+ "guard": "refusal",
724
+ "expect": {
725
+ "owner": "kimi",
726
+ "reviewer": "claude",
727
+ "refusals": [
728
+ "owner:pi:policy",
729
+ "owner:local:policy"
730
+ ]
731
+ },
732
+ "base": {
733
+ "owner": "kimi",
734
+ "reviewer": "claude",
735
+ "refusals": [
736
+ "owner:local:policy",
737
+ "owner:pi:policy"
738
+ ]
739
+ },
740
+ "candidate": {
741
+ "owner": "kimi",
742
+ "reviewer": "claude",
743
+ "refusals": [
744
+ "owner:local:policy",
745
+ "owner:pi:policy"
746
+ ]
747
+ },
748
+ "basePass": true,
749
+ "candidatePass": true
750
+ },
751
+ {
752
+ "id": "long-bulk-edit-pi",
753
+ "expect": {
754
+ "owner": "pi",
755
+ "reviewer": "claude"
756
+ },
757
+ "base": {
758
+ "owner": "pi",
759
+ "reviewer": "claude",
760
+ "refusals": [
761
+ "owner:local:policy"
762
+ ]
763
+ },
764
+ "candidate": {
765
+ "owner": "pi",
766
+ "reviewer": "claude",
767
+ "refusals": [
768
+ "owner:local:policy"
769
+ ]
770
+ },
771
+ "basePass": true,
772
+ "candidatePass": true
773
+ },
774
+ {
775
+ "id": "gate-exclude-both-tier",
776
+ "guard": "refusal",
777
+ "expect": {
778
+ "owner": "codex",
779
+ "reviewer": "claude",
780
+ "refusals": [
781
+ "owner:pi:excluded",
782
+ "owner:local:excluded"
783
+ ]
784
+ },
785
+ "base": {
786
+ "owner": "codex",
787
+ "reviewer": "claude",
788
+ "refusals": [
789
+ "owner:local:excluded",
790
+ "owner:pi:excluded"
791
+ ]
792
+ },
793
+ "candidate": {
794
+ "owner": "codex",
795
+ "reviewer": "claude",
796
+ "refusals": [
797
+ "owner:local:excluded",
798
+ "owner:pi:excluded"
799
+ ]
800
+ },
801
+ "basePass": true,
802
+ "candidatePass": true
803
+ },
804
+ {
805
+ "id": "gate-reserved-offline",
806
+ "guard": "refusal",
807
+ "expect": {
808
+ "owner": "local",
809
+ "reviewer": "claude",
810
+ "refusals": [
811
+ "owner:pi:offline"
812
+ ]
813
+ },
814
+ "base": {
815
+ "owner": "local",
816
+ "reviewer": "claude",
817
+ "refusals": [
818
+ "owner:pi:offline"
819
+ ]
820
+ },
821
+ "candidate": {
822
+ "owner": "local",
823
+ "reviewer": "claude",
824
+ "refusals": [
825
+ "owner:pi:offline"
826
+ ]
827
+ },
828
+ "basePass": true,
829
+ "candidatePass": true
830
+ },
831
+ {
832
+ "id": "gate-backlog-not-routed",
833
+ "expect": {
834
+ "owner": null,
835
+ "reviewer": null
836
+ },
837
+ "base": {
838
+ "owner": null,
839
+ "reviewer": null,
840
+ "refusals": []
841
+ },
842
+ "candidate": {
843
+ "owner": null,
844
+ "reviewer": null,
845
+ "refusals": []
846
+ },
847
+ "basePass": true,
848
+ "candidatePass": true
849
+ },
850
+ {
851
+ "id": "gate-approved-not-routed",
852
+ "expect": {
853
+ "owner": null,
854
+ "reviewer": null
855
+ },
856
+ "base": {
857
+ "owner": null,
858
+ "reviewer": null,
859
+ "refusals": []
860
+ },
861
+ "candidate": {
862
+ "owner": null,
863
+ "reviewer": null,
864
+ "refusals": []
865
+ },
866
+ "basePass": true,
867
+ "candidatePass": true
868
+ },
869
+ {
870
+ "id": "review-claude-offline",
871
+ "expect": {
872
+ "owner": "pi",
873
+ "reviewer": "codex"
874
+ },
875
+ "base": {
876
+ "owner": "pi",
877
+ "reviewer": "codex",
878
+ "refusals": [
879
+ "reviewer:claude:offline"
880
+ ]
881
+ },
882
+ "candidate": {
883
+ "owner": "pi",
884
+ "reviewer": "codex",
885
+ "refusals": [
886
+ "reviewer:claude:offline"
887
+ ]
888
+ },
889
+ "basePass": true,
890
+ "candidatePass": true
891
+ },
892
+ {
893
+ "id": "review-codex-owner",
894
+ "expect": {
895
+ "owner": "codex",
896
+ "reviewer": "claude"
897
+ },
898
+ "base": {
899
+ "owner": "codex",
900
+ "reviewer": "claude",
901
+ "refusals": [
902
+ "owner:kimi:not-attached",
903
+ "owner:local:not-attached",
904
+ "owner:pi:not-attached"
905
+ ]
906
+ },
907
+ "candidate": {
908
+ "owner": "codex",
909
+ "reviewer": "claude",
910
+ "refusals": [
911
+ "owner:kimi:not-attached",
912
+ "owner:local:not-attached",
913
+ "owner:pi:not-attached"
914
+ ]
915
+ },
916
+ "basePass": true,
917
+ "candidatePass": true
918
+ },
919
+ {
920
+ "id": "review-summarize-pi-excluded",
921
+ "expect": {
922
+ "owner": "local",
923
+ "reviewer": "claude"
924
+ },
925
+ "base": {
926
+ "owner": "local",
927
+ "reviewer": "claude",
928
+ "refusals": [
929
+ "owner:pi:excluded"
930
+ ]
931
+ },
932
+ "candidate": {
933
+ "owner": "local",
934
+ "reviewer": "claude",
935
+ "refusals": [
936
+ "owner:pi:excluded"
937
+ ]
938
+ },
939
+ "basePass": true,
940
+ "candidatePass": true
941
+ },
942
+ {
943
+ "id": "signal-urgent-long-context",
944
+ "expect": {
945
+ "owner": "pi",
946
+ "reviewer": "claude"
947
+ },
948
+ "base": {
949
+ "owner": "pi",
950
+ "reviewer": "claude",
951
+ "refusals": [
952
+ "owner:local:policy"
953
+ ]
954
+ },
955
+ "candidate": {
956
+ "owner": "pi",
957
+ "reviewer": "claude",
958
+ "refusals": [
959
+ "owner:local:policy"
960
+ ]
961
+ },
962
+ "basePass": true,
963
+ "candidatePass": true
964
+ }
965
+ ]
966
+ },
967
+ "generated": "2026-10-28"
968
+ }
969
+ ```
970
+
971
+ ## Cases
972
+
973
+ Each cell is `owner / reviewer`. A mark is whether the case passes (owner, reviewer where stated, and the stated refusals).
974
+
975
+ | Case | Guard | Expected | Current default | Candidate |
976
+ | --- | --- | --- | --- | --- |
977
+ | pref-implement-pi-busy | | local / claude | local / claude ok | local / claude ok |
978
+ | pref-implement-pi-offline | | local / claude | local / claude ok | local / claude ok |
979
+ | pref-implement-tier-absent-idle-before-busy | | kimi / claude | kimi / claude ok | kimi / claude ok |
980
+ | pref-test-all-idle | | pi / claude | pi / claude ok | pi / claude ok |
981
+ | pref-triage-pi-paused | | local / claude | local / claude ok | local / claude ok |
982
+ | judge-plan-claude-offline | | codex / none | codex ok | codex ok |
983
+ | judge-review-claude-busy | | codex / none | codex ok | codex ok |
984
+ | judge-review-no-reviewer-attached | refusal | none | none ok | none ok |
985
+ | pii-implement-local-offline | pii | none / user | none / user ok | none / user ok |
986
+ | pii-implement-local-busy | pii | local / user | local / user ok | local / user ok |
987
+ | pii-bulk-edit-local-paused | pii | none / user | none / user ok | none / user ok |
988
+ | pii-review-class | pii | none | none / user ok | none / user ok |
989
+ | pii-test-pi-busy | pii | local / user | local / user ok | local / user ok |
990
+ | pii-triage-local-absent | pii | none / user | none / user ok | none / user ok |
991
+ | long-summarize-skips-pi-and-local | refusal | kimi / claude | kimi / claude ok | kimi / claude ok |
992
+ | long-bulk-edit-pi | | pi / claude | pi / claude ok | pi / claude ok |
993
+ | gate-exclude-both-tier | refusal | codex / claude | codex / claude ok | codex / claude ok |
994
+ | gate-reserved-offline | refusal | local / claude | local / claude ok | local / claude ok |
995
+ | gate-backlog-not-routed | | none / none | none ok | none ok |
996
+ | gate-approved-not-routed | | none / none | none ok | none ok |
997
+ | review-claude-offline | | pi / codex | pi / codex ok | pi / codex ok |
998
+ | review-codex-owner | | codex / claude | codex / claude ok | codex / claude ok |
999
+ | review-summarize-pi-excluded | | local / claude | local / claude ok | local / claude ok |
1000
+ | signal-urgent-long-context | | pi / claude | pi / claude ok | pi / claude ok |