@staix/agent-hub 0.12.33 → 0.12.35

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 (126) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +3 -3
  3. package/docs/agent-notes/adapters.md +9 -3
  4. package/docs/agent-notes/budget.md +7 -3
  5. package/docs/agent-notes/bus.md +2 -1
  6. package/docs/agent-notes/daemon.md +7 -3
  7. package/docs/agent-notes/local-worker.md +1 -1
  8. package/docs/agent-notes/tasks.md +6 -2
  9. package/docs/agent-notes/tests.md +2 -1
  10. package/docs/gsd-collaboration-analysis.md +5 -1
  11. package/docs/operations.md +80 -16
  12. package/docs/quickstart.md +10 -2
  13. package/docs/sdlc.md +59 -34
  14. package/docs/security.md +7 -4
  15. package/docs/smoke.md +1 -1
  16. package/docs/specs/2026-09-19-agent-hub-design.md +407 -10
  17. package/docs/verification/2026-10-18-0.12.34.md +48 -0
  18. package/docs/verification/2026-10-18-0.12.35.md +49 -0
  19. package/docs/verification/2026-10-18-493-claude-busy-channel.md +91 -0
  20. package/docs/verified.json +35 -19
  21. package/package.json +1 -1
  22. package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
  23. package/plugins/agent-hub/server.js +23567 -16606
  24. package/src/adapters/acp.ts +3 -1
  25. package/src/adapters/claude-channel.ts +59 -29
  26. package/src/adapters/codex-appserver.ts +82 -12
  27. package/src/adapters/definitions/builtin-metadata.ts +101 -7
  28. package/src/adapters/definitions/native-cli-claude-launch.ts +90 -0
  29. package/src/adapters/definitions/native-cli-claude-setup.ts +80 -0
  30. package/src/adapters/definitions/native-cli-codex-launch.ts +14 -0
  31. package/src/adapters/definitions/native-cli-doctor.ts +46 -0
  32. package/src/adapters/definitions/native-cli-entry-claude.ts +52 -0
  33. package/src/adapters/definitions/native-cli-entry-codex.ts +34 -0
  34. package/src/adapters/definitions/native-cli-entry-jcode.ts +27 -0
  35. package/src/adapters/definitions/native-cli-entry-kimi.ts +57 -0
  36. package/src/adapters/definitions/native-cli-entry-local.ts +15 -0
  37. package/src/adapters/definitions/native-cli-entry-pi.ts +53 -0
  38. package/src/adapters/definitions/native-cli-entry-qwen.ts +21 -0
  39. package/src/adapters/definitions/native-cli-entry-types.ts +41 -0
  40. package/src/adapters/definitions/native-cli-entry.ts +19 -0
  41. package/src/adapters/definitions/native-cli-jcode-mcp.ts +58 -0
  42. package/src/adapters/definitions/native-cli-launch-common.ts +17 -0
  43. package/src/adapters/definitions/native-cli-pi.ts +33 -0
  44. package/src/adapters/definitions/native-cli-preview-claude.ts +37 -0
  45. package/src/adapters/definitions/native-cli-preview-codex.ts +20 -0
  46. package/src/adapters/definitions/native-cli-preview-common.ts +57 -0
  47. package/src/adapters/definitions/native-cli-preview-jcode.ts +20 -0
  48. package/src/adapters/definitions/native-cli-preview-kimi.ts +28 -0
  49. package/src/adapters/definitions/native-cli-preview-pi.ts +36 -0
  50. package/src/adapters/definitions/native-cli-preview-qwen.ts +22 -0
  51. package/src/adapters/definitions/native-cli-preview.ts +16 -0
  52. package/src/adapters/definitions/native-config-defaults.ts +19 -0
  53. package/src/adapters/definitions/native-config-policy.ts +35 -0
  54. package/src/adapters/definitions/native-context.ts +35 -0
  55. package/src/adapters/definitions/native-daemon-kimi.ts +5 -0
  56. package/src/adapters/definitions/native-daemon-policy.ts +18 -0
  57. package/src/adapters/definitions/native-display.ts +18 -0
  58. package/src/adapters/definitions/native-factories.ts +48 -0
  59. package/src/adapters/definitions/native-policy-aux.ts +130 -0
  60. package/src/adapters/definitions/native-quota.ts +29 -0
  61. package/src/adapters/definitions/native-recovery-continuity.ts +12 -0
  62. package/src/adapters/definitions/native-recovery.ts +88 -0
  63. package/src/adapters/definitions/qwen-native.ts +2 -2
  64. package/src/adapters/definitions/qwen.ts +8 -4
  65. package/src/adapters/local-worker.ts +3 -2
  66. package/src/adapters/pi.ts +3 -1
  67. package/src/adapters/registry-types.ts +100 -10
  68. package/src/adapters/registry.ts +127 -11
  69. package/src/cli/console-state.ts +5 -5
  70. package/src/cli/identity.ts +8 -7
  71. package/src/cli/jcode-mcp.ts +2 -58
  72. package/src/cli/launch.ts +41 -102
  73. package/src/cli/main.ts +126 -290
  74. package/src/cli/output.ts +3 -2
  75. package/src/cli/preview.ts +26 -126
  76. package/src/cli/recovery-guidance.ts +43 -22
  77. package/src/cli/setup.ts +2 -80
  78. package/src/cli/shell-quote.ts +3 -0
  79. package/src/cli/terminal-recovery.ts +81 -22
  80. package/src/cli/upgrade-interactive.ts +4 -2
  81. package/src/cli/upgrade-restore-state.ts +17 -7
  82. package/src/cli/upgrade-runtime.ts +126 -147
  83. package/src/cli/upgrade.ts +44 -27
  84. package/src/hub/budget.ts +59 -31
  85. package/src/hub/bus.ts +1 -1
  86. package/src/hub/conductor.ts +19 -9
  87. package/src/hub/config-apply.ts +22 -15
  88. package/src/hub/config-reload.ts +18 -3
  89. package/src/hub/config-trust.ts +1 -1
  90. package/src/hub/context-window.ts +3 -27
  91. package/src/hub/control-client.ts +1 -1
  92. package/src/hub/crash.ts +15 -39
  93. package/src/hub/daemon.ts +506 -341
  94. package/src/hub/execution-budget.ts +3 -2
  95. package/src/hub/hub-tools.ts +19 -8
  96. package/src/hub/instance-budget.ts +73 -0
  97. package/src/hub/instance-config.ts +47 -0
  98. package/src/hub/instance-execution.ts +50 -0
  99. package/src/hub/instances.ts +100 -0
  100. package/src/hub/lifecycle-schema.ts +7 -3
  101. package/src/hub/peer-catalog.ts +4 -13
  102. package/src/hub/permission-mode.ts +14 -17
  103. package/src/hub/recovery-continuity.ts +6 -5
  104. package/src/hub/report.ts +9 -8
  105. package/src/hub/roster.ts +9 -9
  106. package/src/hub/routing.ts +94 -19
  107. package/src/hub/sdlc-queue.ts +2 -2
  108. package/src/hub/sdlc.ts +84 -38
  109. package/src/hub/settings.ts +39 -10
  110. package/src/hub/settled-roles.ts +1 -1
  111. package/src/hub/snapshots.ts +40 -9
  112. package/src/hub/start-mode.ts +13 -8
  113. package/src/hub/status-roster.ts +8 -0
  114. package/src/hub/tasks.ts +60 -27
  115. package/src/hub/text-projection.ts +7 -3
  116. package/src/hub/tooling.ts +4 -60
  117. package/src/hub/ui.ts +3 -1
  118. package/src/hub/workflow.ts +30 -52
  119. package/src/memory/recall.ts +4 -5
  120. package/src/models/route/signals.ts +3 -1
  121. package/src/pi/launch.ts +5 -3
  122. package/src/ui/index.html +4 -3
  123. package/src/ui/office-model.ts +3 -1
  124. package/src/ui/peer-palette.ts +16 -6
  125. package/templates/AGENTS.block.md +2 -1
  126. package/templates/routing.toml +2 -2
@@ -374,7 +374,7 @@ Assignment is a pure function of `routing.toml`, the task's signals and the peer
374
374
  "skip_local"`, `pii = "local_only"`); `ahub route explain <id | --class <c> <title>>` runs the
375
375
  same function and prints its trace: signals, every candidate with the reason it was kept
376
376
  or skipped, owner, reviewer and route. `local` uses the class's `route` / `fixed_model` for a
377
- task turn and `[local]` otherwise. Verification failure (tests fail, review `changes_requested` twice) escalates
377
+ task turn and `[local]` otherwise. Verification failure (tests fail, review `changes_requested` `tasks.escalate_after` times in a row, default 3, #488) escalates
378
378
  the task to the next peer in `escalate_to`; Switchyard handles per-call escalation
379
379
  inside a peer.
380
380
 
@@ -573,7 +573,7 @@ AGENTS.md, REVIEW.md
573
573
  `end_turn`, never lost.
574
574
  3. `[STATUS]` messages from one peer are batched into one digest per recipient.
575
575
  4. A task proposed by Claude, accepted by Codex, marked done, is auto-routed to the
576
- reviewer; `changes_requested` twice escalates per `routing.toml`.
576
+ reviewer; `tasks.escalate_after` consecutive `changes_requested` (default 3) escalate per `routing.toml`.
577
577
  5. `ahub local` completes a `bulk_edit` task; OmniRoute log shows the request with the
578
578
  per-peer token and `x-omniroute-provider: vllm`; `ahub route explain` shows the
579
579
  chosen route.
@@ -1837,7 +1837,8 @@ push `accepted` and show none of them.
1837
1837
  selection excludes pull-only peers; only explicit role-specific naming or an
1838
1838
  honored owner reservation permits assignment.
1839
1839
  - `hub_inbox` sends `inbox`. The daemon answers "not attached yet; retry"
1840
- between welcome and attach, and refuses it for a session with pushes.
1840
+ between welcome and attach. Since #493 the current channel owner may also
1841
+ explicitly pull its queued work, including while its native turn is busy.
1841
1842
  `Bus.pull` is held by every hold a drain respects (`Bus.held`: recovery, an
1842
1843
  uncertain delivery, a console, budget or conductor pause), though unlike a
1843
1844
  drain it does not wait for the peer to be idle; a held pull journals nothing
@@ -1876,6 +1877,45 @@ push `accepted` and show none of them.
1876
1877
  - Control protocol 16 adds the hello `channel` field and `inbox`. Recovery
1877
1878
  sources add protocol 15 (0.12.17 through 0.12.19); the transition from a real
1878
1879
  0.12.19 hub is not yet proven.
1880
+
1881
+ ## Amendment: channel queue visibility and explicit pull (issue #493)
1882
+
1883
+ - A channel session's `hub_inbox` reads the daemon queue through the same
1884
+ authenticated `peer` socket as a tools-only Claude session. The daemon checks
1885
+ current socket ownership and the shared roster, pause, recovery, lifecycle and
1886
+ uncertain-delivery holds. It does not require an idle native turn. Tools-role
1887
+ sockets cannot consume another transport's queue.
1888
+ - `Bus.pull` claims one batch synchronously and completes it with its bus
1889
+ checkpoint in the existing journal transaction. A later idle drain or another
1890
+ concurrent inbox call cannot hand those originals out again. Existing accepted
1891
+ pushes remain independent; a pull does not complete them. The hand-out-before-
1892
+ model-read ceiling documented above remains. Framing, `sanitize`, public PII
1893
+ projections and task-offer read evidence retain their existing paths.
1894
+ - The plugin also returns its existing bounded local buffer of failed pushes
1895
+ without journal ids. Journaled failed pushes stay in `needs_review`; the plugin
1896
+ never consumes them from this local buffer. A daemon refusal or an unavailable
1897
+ connection cannot prevent reading that local fallback.
1898
+ - `delivery_holds` adds optional same-peer `queued` and `important` counts, with
1899
+ no bodies or caller-selected target. Every agent-hub tool-call result can show
1900
+ fresh counts when important work waits. Channel and tools-mode sessions remain
1901
+ silent when an older daemon supplies no counts. Plain pull-only sessions keep
1902
+ their old advisory nudge compatibility. A current zero clears old nudges;
1903
+ unavailable metadata never changes a saved result or its effect classification.
1904
+ Inbox replies show counts without suggesting a repeated refused read, and a
1905
+ tools-mode hint does not grant an inbox capability to that transport.
1906
+ - `[FYI]` remains record-only. PR ready, done or submitted, ruling-needed,
1907
+ blocker and changed-contract/path messages require an unmarked or important
1908
+ update. `hub_task_done` and `hub_review` already notify the assigned audience;
1909
+ an extra chat with the same outcome is unnecessary.
1910
+ - Native busy-notification evidence and the decision about channel steering are
1911
+ recorded separately in `docs/verification/2026-10-18-493-claude-busy-channel.md`.
1912
+ Claude Code 2.1.302 / Sonnet 5.5 returned the random notification token before
1913
+ the original interactive turn ended. Push-capable `WsPeer` therefore exposes
1914
+ important-only steer through the existing journal/generation-bound push path;
1915
+ detach and pull-only attach remove that capability. Ordinary messages remain
1916
+ queued while busy. A notification write alone is not proof that the native
1917
+ model saw it; the earlier print-mode probe was inconclusive.
1918
+
1879
1919
  ## Amendment: owner and reviewer read their task (issue #208)
1880
1920
 
1881
1921
  `hub_task_show` stays a conductor tool, and a task's current owner and current
@@ -2398,7 +2438,7 @@ the queue.
2398
2438
  - Tasks owns optional board artifact receipts and every mutation. Repository, issue/PR ids, claimed local result/head and a reviewed full SHA are distinct from fresh external evidence. Only the owner/reviewer/person records; only the reviewer/person binds a review head. Invalid identities, unsupported externally supplied facts and private-turn cloud records are refused before effects.
2399
2439
  - Enforce rechecks the current PR head, successful required checks, local receipt on that head, GitHub review and complete unresolved-thread readback before approval. Missing/unknown data blocks, a new head invalidates derived readiness, and changes requested needs no green CI. Advise exposes gates without additional blocks; off retains existing transitions. Historical board approval is not approval of a new head.
2400
2440
  - CLI sdlc status/explain reads bounded structured metadata, not remote bodies. Shared console/dashboard views expose unknown external evidence and the next actor/action; they cannot certify freshness. No merge/release authority is granted.
2401
- - Custom definitions, full merge/release presentation, gsd-lite and a native advise cycle remain pending; see docs/sdlc.md.
2441
+ - Later custom definitions and read-only merge/release reports are described below. #481 supersedes the original lifecycle vocabulary and workflow option; a full native advise cycle remains pending. See docs/sdlc.md.
2402
2442
  ## Amendment: optional Qwen Code 0.25.0 ACP peer (#256)
2403
2443
 
2404
2444
  - `qwen` joins the known catalog with default participation off. Only the project's roster selects it; no second enabled switch or default routing preference is added. Its flow roles default to implementer/verifier, which is guidance, not a claim of native reliability.
@@ -2422,9 +2462,9 @@ the queue.
2422
2462
  - Activity contains delivery ids/senders, message/thought chunks, bounded tool summaries, plans, permission request/outcome ids and turn end. It never enters persistent events/logs, UI, tools or cloud memory. Existing final answers still travel through the answer bus.
2423
2463
  - Kimi TUI defaults remain pull-only. Qwen TUI and native visualizer support remain gated by unverified T0 checks. See [verification](../verification/2026-10-11-acp-watch-t0.md).
2424
2464
 
2425
- # gsd-lite amendment, 2026-10-11 (#257)
2465
+ # Historical workflow amendment, 2026-10-11 (#257, superseded by #481)
2426
2466
 
2427
- - Optional workflow none|gsd-lite, none by default, uses existing SDLC receipts and Tasks authority. A reviewer/person-owned checklist stores bounded criterion ids, hashed evidence refs and verified/failed/unverified claims bound to the reviewed head.
2467
+ - The original optional workflow selector used existing SDLC receipts and Tasks authority; its current replacement is the #481 amendment below. A reviewer/person-owned checklist stores bounded criterion ids, hashed evidence refs and verified/failed/unverified claims bound to the reviewed head.
2428
2468
  - Existing task/predecessor ids must match current Tasks.after edges; missing/cyclic/private cross-links are refused before effects. Imports do not change task ownership, reservations or dependencies.
2429
2469
  - Required unknown/failed criteria and stale heads keep readiness false. Advise remains nonblocking; enforce adds these only to existing approval gates. Route explain, console/dashboard lifecycle views and read-only hashed exports derive the same board/config state. No second writable workflow store, automatic advance, permissions, merge/release or study execution.
2430
2470
 
@@ -2508,12 +2548,12 @@ pii.paths and data.readonly accept exact paths/subtrees and *, ? and whole-segme
2508
2548
 
2509
2549
  ## Amendment: custom lifecycle data (#257)
2510
2550
 
2511
- Optional ordered stage definitions map at most 32 bounded ids to the existing seven semantic bases, existing actor guidance and closed issue/pr/local/review/checks/phase entry/exit gates. Explicit after edges name at most eight earlier configured ids; missing/self/forward/cyclic references refuse. Review and merge base destinations are required by existing Tasks completion transitions. Built-in names cannot change base. Existing holder/person authority and the full approval floor remain; enforce additionally checks an explicit custom stage-change actor without granting a new caller authority. Off/advise preserve claim behavior. Config-aware receipts, projections and every managed native/local task schema use the same stage ids. Historical removed definitions remain unknown, not silently remapped. No new state, executable gate, auto-advance, merge, release, import authority or native success is introduced.
2551
+ Optional ordered stage definitions map at most 32 bounded ids to the semantic bases, existing actor guidance and closed entry/exit gates (updated to nine bases and the criteria gate by #481 below). Explicit after edges name at most eight earlier configured ids; missing/self/forward/cyclic references refuse. Review and merge base destinations are required by existing Tasks completion transitions. Built-in names cannot change base. Existing holder/person authority and the full approval floor remain; enforce additionally checks an explicit custom stage-change actor without granting a new caller authority. Off/advise preserve claim behavior. Config-aware receipts, projections and every managed native/local task schema use the same stage ids. Historical removed definitions remain unknown, not silently remapped. No new state, executable gate, auto-advance, merge, release, import authority or native success is introduced.
2512
2552
 
2513
2553
 
2514
2554
  ### Custom lifecycle review corrections (#257)
2515
2555
 
2516
- Phase gates require gsd-lite phase views at configuration validation. Authenticated daemon status gains optional lifecycleStages metadata, with no protocol bump. Separate MCP tools lists use that active snapshot; a live legacy daemon without the field keeps seven stages, while unknown/unavailable metadata withholds the lifecycle-record tool. Editing project data during a live daemon no longer changes its advertised stage ids.
2556
+ The original phase gate validation is superseded by the criteria gate and compatibility window in #481 below. Authenticated daemon status gains optional lifecycleStages metadata, with no protocol bump. Separate MCP tools lists use that active snapshot; a live legacy daemon without the field keeps seven stages, while unknown/unavailable metadata withholds the lifecycle-record tool. Editing project data during a live daemon no longer changes its advertised stage ids.
2517
2557
 
2518
2558
 
2519
2559
  ## Backlog foundation (#263)
@@ -3237,8 +3277,8 @@ The guard inventories AST comparisons, closed-list imports and vendor literals,
3237
3277
  including inline dashboard scripts, under stable file/symbol scopes. Its reviewed
3238
3278
  A1 baseline records the current source, rather than claiming the old A0 grep's
3239
3279
  265 line matches equal AST node counts. A new group, count growth or stale entry
3240
- fails; later phases may only shrink this baseline. Only real, unshadowed registry
3241
- resolver imports exempt kind-aware comparisons. Native adapter implementations and
3280
+ fails; later phases may only shrink this baseline. A1 originally exempted kind-aware comparisons from real, unshadowed registry
3281
+ resolver imports; the A2 amendment below counts them instead. Native adapter implementations and
3242
3282
  explicit non-peer config semantics remain the narrow exceptions. Existing literal
3243
3283
  catalog exports used by older recovery source probes are retained until their
3244
3284
  replacement compatibility proof is available; a refactor must not silently make a
@@ -3260,3 +3300,360 @@ same scanner reports 428/172 on that main and 415/171 on the combined A1 source.
3260
3300
  Every added or increased baseline entry matches that main-only delta; A1 still
3261
3301
  removes thirteen sites and one group. This explicit reconciliation precedes the
3262
3302
  first shipped baseline and does not permit later phases to grow it.
3303
+
3304
+ ## Adapter registry A2 amendment (#451)
3305
+
3306
+ A2 counts native-name comparisons even when a trusted registry resolver supplies
3307
+ its left or right operand. These sites use the `kind-aware-comparison` inventory
3308
+ pattern and the same lexical file/symbol group as a raw comparison, including
3309
+ switch cases. Replacing a raw comparison with `kindOf` or `definitionOf(...).kind`
3310
+ therefore does not shrink a baseline group. Alias and shadowing checks remain in
3311
+ force. The pre-existing kind-aware preview site is counted explicitly; the A1
3312
+ source has 415 other sites plus that one site. A2 removes the transitional
3313
+ baseline by migrating policy, rather than by adding resolver exemptions.
3314
+
3315
+ Session metadata distinguishes native resume arguments from daemon startup
3316
+ restoration. `session.resumeById` means that recovery passes the verified native
3317
+ session id to the start command (Qwen). `session.restoreOnStart` means that the
3318
+ daemon restores recorded startup options before automatic startup (Pi). Neither
3319
+ flag proves that a conversation can be resumed or permits a fresh replacement.
3320
+ Crash recovery tests `resumeById` and uses `crashIdentity`; transport choice or the
3321
+ presence of a factory does not establish that capability.
3322
+
3323
+ A2 preserves literal `KNOWN_PEERS` and `OPTIONAL_PEERS` exports in
3324
+ `peer-catalog.ts` for released coordinators that inspect their source. The guard
3325
+ records these exact file/symbol exceptions separately with the reason
3326
+ "cross-release source probe", and tests their values against the typed registry
3327
+ catalog. The same exception preserves `start-mode.ts`'s literal `START_MODE_PEERS`, which released coordinators inspect before restoring Kimi headlessly. The three probes are counted separately (5 + 2 + 3 sites). The native vendor baseline is otherwise empty. A retained coordinator's
3328
+ existing source probe must accept the A2 target; no unsupported-target ceiling is
3329
+ introduced. ponytail: retire these compatibility literals only after a separately
3330
+ approved minimum supported upgrade source no longer reads them.
3331
+
3332
+ Native recovery hooks return read-only facts over the existing narrow DTOs.
3333
+ `zeroTurn({ stateDir, binding, phase })` reads Codex's existing event proof only
3334
+ for planning, and Claude's existing transcript absence only for attachment or
3335
+ verification. `restoreArgs(peer)` and `recoveryRefusal(peer)` are pure over the
3336
+ captured peer. `personFresh` and `missingEvidence` are policy data, not authority.
3337
+ `resumeArgv(binding, fresh)` returns the CLI tail; the coordinator supplies the
3338
+ interpreter, entrypoint and project prefix and retains all receipt, repair,
3339
+ waiver and unknown-state decisions. The restore oracle, supplemental matrix and
3340
+ transition code remain byte-unchanged.
3341
+
3342
+ Quota and context readers are pure normalizers:
3343
+ `QuotaReader.read(value: unknown): UsageWindow[]` and
3344
+ `ContextReader.read(value: unknown, sessionId: string, measuredAt: number): ContextReading`.
3345
+ They preserve the existing malformed-input results. The coordinator still binds
3346
+ transport generation, native session and measurement time before reporting.
3347
+ Palette data additionally carries optional `tone` and `ansi`, preserving the
3348
+ existing terminal palette and rendered CSS bytes.
3349
+
3350
+ P4 conformance is transport-specific. Delivery-only native drivers set busy
3351
+ synchronously at admission; pull-only WebSocket peers receive no unsolicited
3352
+ delivery or busy mutation; Claude push keeps its existing receipt/native-start
3353
+ busy contract. Native production behavior does not change to satisfy a generic
3354
+ conformance case. The kit also covers the existing generation fences, process
3355
+ groups, approvals, quota refusals, mode acknowledgement/timeout and recovery
3356
+ contracts for each applicable transport, with explicit unsupported outcomes.
3357
+
3358
+ `resumeArgv` accepts the existing `SessionRef` (session id/file, backend and model),
3359
+ which withholds terminal and launch identity from a pure argument formatter.
3360
+ `recoveryRefusal(peer, phase?: "plan" | "restore")` defaults to planning and keeps
3361
+ both existing phase-specific native messages. Fixed private compatibility data
3362
+ `legacyTargetSupport` and `legacyHeadlessArgv` name only the existing catalog or
3363
+ start-mode literal exports; their old read points and regexes are unchanged.
3364
+
3365
+ `start.daemonPort` is a closed, data-only engine tag (`codex-appserver`, `acp`,
3366
+ `owned-acp`, `pi-rpc`, `local-worker`), required when `start.create` exists. Unknown
3367
+ values are refused at registry load. Channel/pull definitions without a factory
3368
+ leave it absent. Typed registry-owned wrappers retain the existing `DaemonPorts`
3369
+ union; core selects the engine and retains lifecycle/authentication closures,
3370
+ while the definition factory remains the only native constructor.
3371
+
3372
+ The trusted CLI host may supply `LaunchContext.pi` using the existing Pi builder
3373
+ options, extension path and live bridge port/token. A redacted preview supplies
3374
+ only redacted placeholders; bridge tokens never reach previews, logs or events.
3375
+ `LaunchPlan.env` preserves Pi's existing child environment. Definitions never
3376
+ load daemon config or infer executable commands from environment text.
3377
+ `VersionContext` adds `observedVersion`, `nativeCommand` and `projectRoot` once:
3378
+ the host still performs each probe, while definitions validate or display it.
3379
+ `cli.authority` and `cli.personOnlyFlags` can only restrict existing authority;
3380
+ identity.ts stays authoritative and missing/unknown metadata retains today's
3381
+ rule. `start.passthrough` is data only. The MCP hook is a pure plan over the
3382
+ existing project/state/server-entrypoint/form tuple; every write, ordering fence
3383
+ and finally cleanup remains in the CLI host.
3384
+
3385
+ ### A2 internal native host projections (2026-10-18)
3386
+
3387
+ The remaining AST inventory after the first A2 checkpoint has 260 policy sites in
3388
+ 113 lexical groups. Native CLI entrypoints and previews, configuration validators,
3389
+ settings rows, plugin inventory and recovery presentation need explicit definition
3390
+ projections in addition to the original frozen transport factory hooks. These are
3391
+ moves of existing built-in policy, with the same host-owned effects, argv, ordering,
3392
+ errors, privacy, permission and timing fences. They add no instance support,
3393
+ capability or native behavior.
3394
+
3395
+ Private, statically imported built-in preview helpers implement the frozen
3396
+ `start.launch` / `publicLaunch` redaction path. They preserve current validation,
3397
+ JSON order and placeholders, and cannot execute a native process, connect to
3398
+ control, allocate runtime state or write authoritative state. They are not public
3399
+ `AdapterDefinition` / `NativeHooks` extension points; configuration cannot register
3400
+ a helper. Person CLI entrypoints are relocated into a fixed private built-in
3401
+ dispatcher for C1, without adding a public `cli.run` or `NativeHooks` callback.
3402
+ The dispatcher cannot load external modules or accept caller-selected callbacks;
3403
+ its typed context contains only the original CLI host operations. Identity,
3404
+ command access, live-test delegation, audit and project/lifecycle admission remain
3405
+ in the host before dispatch, and each moved body retains its native effects,
3406
+ ordering, errors, environment and cleanup. Doctor projections carry existing probe
3407
+ metadata; the host retains probe execution and output. Configuration projections receive the current validator vocabulary and
3408
+ return the existing schema/settings entries. Recovery projections carry the current
3409
+ crash plan, continuity decoder/bookmark and unrecorded-terminal classification.
3410
+ Reporting flags, tool classification, recall source and display tones are semantic
3411
+ data; a consumer must not replace raw comparisons with kind-name wrappers or
3412
+ constant aliases. Plugin inventory takes the existing home/cwd/env context and
3413
+ returns the existing typed Addon rows, correcting the unused string-array
3414
+ placeholder. Arbitrary daemon callbacks and caller-chosen executables, paths,
3415
+ permissions or policy remain forbidden. External module publication/validation is
3416
+ still A4 and must freeze its accepted subset separately.
3417
+
3418
+ Claude's channel is native-hook-driven: delivery insertion remains idle until an
3419
+ authenticated native-start observation. Its conformance case asserts that behavior;
3420
+ transport adapters retain the synchronous-busy requirement. Unsupported native
3421
+ quota or process ownership is an explicit applicability result, never synthetic
3422
+ success. Every applicable P4 behavior is exercised with the real adapter and fake
3423
+ transport, without changing existing assertions or claiming live-account evidence.
3424
+
3425
+ The P4 late-result probe exposed an existing Codex watchdog defect on the unchanged
3426
+ 54e631d8 adapter: a completed agent message could refill the answer after watchdog
3427
+ invalidation, then its stale turn completion could broadcast it without its former
3428
+ audience. A2 repairs this intended generation fence in source. It discards answer
3429
+ notifications without an active turn and notifications naming an inactive turn,
3430
+ retains the legacy unknown-turn compatibility path, and clears expired deltas.
3431
+ The new probe keeps its strict no-message/needs-review assertions. Supported native
3432
+ RPC behavior, approvals, quota classification and existing tests stay unchanged.
3433
+
3434
+ The watchdog fence also covers acceptance before a queued `turn/started` report
3435
+ and unanswered hub `turn/start` RPCs. Cancelled named ids remain retired until their
3436
+ exact completion or session teardown; late acknowledgements cannot restore a
3437
+ cancelled audience or relabel uncertainty as `failed_safe`. Ordinary legacy
3438
+ unknown-id starts keep their fallback. After an invalidation with no provable
3439
+ native identity, unnamed lifecycle reports cannot be safely attributed: keep the
3440
+ peer offline and require a verified reattachment rather than guess a new turn.
3441
+
3442
+ ### A2 daemon semantic projections (2026-10-18)
3443
+
3444
+ The daemon constructs every native driver through `start.create` and the fixed,
3445
+ transport-typed `DAEMON_PORTS` wrappers. Protocol lifecycle dispatch may select the
3446
+ actual engine; provider policy does not select an unrelated capability as an alias
3447
+ for a kind. Existing host callbacks retain their original effect authority,
3448
+ privacy, owner checks, ordering and timing.
3449
+
3450
+ The internal definitions additionally carry the existing start-only enable-switch
3451
+ membership rule, exclusive-start refusal, tool-refresh requirement, explicit
3452
+ headless-mode argument, attached-worker reconfiguration rule, dashboard start
3453
+ command and pure ACP argv builder. Attach metadata serializes recovery launch
3454
+ identity and carries the existing pull-only admission and status guidance.
3455
+ Permission status text is separate from the existing permission refusal text;
3456
+ `permission.trackUnattended` keeps native unattended ownership accounting distinct
3457
+ from protocol dispatch.
3458
+ Budget metadata names the soft-token reset on resume. Session metadata declares
3459
+ native conversation revert support; the host still checks the actual driver and
3460
+ latest turn and owns the pause while reverting. CLI metadata formats retained
3461
+ terminal and roster-return notices and supplies the existing preview argument
3462
+ tail. These fields only move native policy, preserving existing output bytes and
3463
+ behavior. The version hook consumes the already frozen `observedVersion` and peer
3464
+ fields; the daemon retains the bounded native transcript probe.
3465
+
3466
+ The doctor command consumes fixed built-in metadata and pure observed-value
3467
+ projections exported through the registry. Native tool order, plugin probe argv,
3468
+ optional roster checks, section/severity, recovery identity fields and legacy
3469
+ capture labels stay in the built-in implementation. The CLI retains every spawn,
3470
+ source-verification, connection, gateway and memory effect in its existing order
3471
+ and privacy boundary. This private data adds no public definition member,
3472
+ executable callback or configurable probe; unknown names retain their existing
3473
+ Hub/unknown classification.
3474
+
3475
+ A2 reanchors thirteen seeded mutants to the same moved semantic guards: explicit Pi
3476
+ roster precedence, supported roster keys, retained-terminal result text, Kimi TUI
3477
+ recovery refusal and admission cleanup, Qwen opt-in/session/crash resume, planning
3478
+ reservation support, active Kimi TUI settings floor, live headless Kimi watch,
3479
+ disabled Codex plugins and bounded
3480
+ regular-file tooling reads. Seed ids and test targets remain unchanged; the other
3481
+ 406 seed objects remain byte-identical. The mutation pairs must still demonstrate
3482
+ green production behavior and failure with that guard removed.
3483
+
3484
+ The final A2 AST inventory is empty for core policy: zero sites and zero lexical
3485
+ groups. The reviewed policy baseline is explicitly `[]`; it is never generated
3486
+ from source during tests. Three cross-release literal probes remain separate
3487
+ (`KNOWN_PEERS` five, `OPTIONAL_PEERS` two, `START_MODE_PEERS` three). Precise
3488
+ screening-provider/lifecycle enum false positives remain scoped by file, symbol
3489
+ and AST shape; negative fixtures still catch vendor comparisons in those scopes.
3490
+
3491
+ Quota participation and execution-budget instrumentation are independent.
3492
+ `budget.quotaExempt` preserves native quota exemption while retaining `account`
3493
+ and instrumented execution limits: local sets it, Pi does not. Registered kinds
3494
+ without budget metadata remain quota-exempt; external ids retain manual quota
3495
+ accounting. The A1 named compatibility metadata export preserves its original
3496
+ wrapper plans and observable shape, while the registry consumes separate native
3497
+ runtime definitions. Native display constants retain reference identity; private
3498
+ stream tone selection does not add fields to that observable display object.
3499
+
3500
+ Configurable start-mode fallback reads the registered definition's default form,
3501
+ retaining explicit overrides and existing unknown-id behavior. The Kimi default
3502
+ mutant changes that native metadata from TUI to headless, so the original default
3503
+ assertion observes it directly; it does not remove a settings row or mutate the
3504
+ retained cross-release source literal.
3505
+
3506
+ A2 preserves the recovery tests' assertion contract while reconnecting their
3507
+ execution harnesses to production code. The Pi CLI parser harness imports its
3508
+ extracted pure parser rather than extracting a removed main.ts declaration.
3509
+ The reattach parser VM receives the real registry resolver, and the attachment
3510
+ wait VM receives the real exported session-field resolver. Every existing
3511
+ `expect` line in these three files remains byte-identical; no fallback, mock
3512
+ policy, weaker condition or changed expected result is introduced.
3513
+
3514
+ ### A2 round-1 parity and capability-scope constraints
3515
+
3516
+ Quota handoff uses the registry's native platform projection, preserving exactly
3517
+ Claude, Codex, Kimi, Qwen and Jcode. The per-delivery `recallInjected` flag remains
3518
+ independent: adding Kimi/Jcode handoff platforms does not make their own sessions
3519
+ part of injected-platform exclusion.
3520
+
3521
+ Routing reads on-prem trust for PII admission. Legacy fixed-model/relay policy,
3522
+ local-allowed refusal text, context handling, preference tier, relay ordering and
3523
+ trace labels are native definition data. Host routing and task flow retain their
3524
+ existing policy calculations, messages and candidate ordering (including class
3525
+ fallback duplicates). This native routing data is not an external configuration
3526
+ surface.
3527
+
3528
+ Registry loading calls `assertNativeCapabilityScope` before publication. A
3529
+ non-builtin definition cannot declare `start.acpCommand`, `attach.admission`,
3530
+ `budget.resetSoftTokensOnResume`, `session.crashIdentity`, a `pi-rpc` daemon port,
3531
+ or the native `routing` policy block. Fixed builtin membership is object identity,
3532
+ not a caller-supplied kind name. Current consumers combine these fields with fixed-builtin assumptions or
3533
+ host-global native state; generic shapes are follow-up work before A3/A4 loading. Other ordinary ACP
3534
+ metadata remains valid.
3535
+
3536
+ The Qwen conductor refusal uses the original generic CLI text. Pi terminal
3537
+ observation reads only observed top-level/nested session-file metadata, never
3538
+ launch `args.sessionFile`. Pi TUI recovery bindings preserve the captured
3539
+ `CLAUDE_CONFIG_DIR` fallback while retaining Codex's `CODEX_HOME` selection.
3540
+
3541
+ The guard resolves immutable peer-id constant aliases and supplied-source
3542
+ import/reexport bindings through lexical symbols before classifying comparisons.
3543
+ Shadowed and unrelated bindings remain independent; named non-peer enum exceptions
3544
+ keep their exact scope. It performs no filesystem or package lookup.
3545
+
3546
+ ## Amendment: playbook lifecycle and criteria checklist, 2026-10-18 (#481 S0/S8)
3547
+
3548
+ - The AI-Native SDLC Playbook supplies the built-in stage model of an enabled lifecycle: intent (Plan), spec (Design), plan and build (Build), test (Test), review, merge and release (Deploy), maintain (Maintain). `mode` advise or enforce without `stages` selects this list. Off (no file, or `mode = "off"`) keeps the seven #257 stages, so its config, receipts, `hub_sdlc_record` schema and status output stay byte for byte. An explicit #257 list still loads: off keeps it as written, and an enabled lifecycle keeps its order under canonical ids (spec, plan, build, review, test, merge, release). Any other list needs definitions.
3549
+ - Valid bases are the nine playbook stages plus the #257 names `implement` and `verify`, which mean build and test. A stored `implement` or `verify` receipt resolves to `build` or `test` in a playbook config; a write with the old id stores the id the config lists. Custom definitions keep loading with their old base names; a playbook-only built-in id (intent, build, test, maintain) cannot take another base. The test base takes the reviewer actor, like verify. Status carries `playbook` (the playbook stage) whenever the mode is not off; the dashboard shows it beside the stage.
3550
+ - The head-bound acceptance-criteria checklist (`criteria` in a receipt) belongs to the Compliance pass. It keeps id, head, 1..32 criteria with required, result and hashed refs, reviewer- or person-only writes and the reviewed-head binding; criterion ids may name issue AC ids (`AC8b`). Once recorded it adds its blockers in any enabled lifecycle; off ignores it unless the retired setting below asks for it. A `criteria` entry or exit gate needs no workflow selector: a missing checklist is a blocker the reviewer can clear.
3551
+ - Checklist task import is removed. A non-empty `tasks` list is refused before any write; dependencies stay with `Tasks.after` (`ahub task propose --after`). A receipt stored under `phase` reads as criteria, and its task list is shown with a note and never gates readiness. Board split-undo still treats such a stored list as a reference.
3552
+ - Deprecation window (constant `RETIRED_WORKFLOW_FROM`, 0.13.0): before it, `workflow = "none"` loads silently, `workflow = "gsd-lite"` loads with a `hub.log` warning and requires a criteria checklist on every task, the `phase` gate loads as an alias of `criteria` with a warning, and the `phase` receipt name is accepted silently. From 0.13.0 each is refused with a field-level reason; the aliases and their tests are then deleted.
3553
+ - Tool schema: when the mode is not off, daemon status carries `lifecycleCriteria: true`, and every managed surface (the channel and tools MCP servers and the local worker) advertises `criteria` instead of `phase` in `hub_sdlc_record`. Custom stage ids and the checklist rename are independent: off and older daemons, custom stage lists included, keep `phase`, because they accept only it. That off schema changes once, when the alias is removed at `RETIRED_WORKFLOW_FROM`.
3554
+ - `ahub sdlc export`: a plain off lifecycle (no retired setting) keeps the #257 export bytes (schema 1, `workflow: "none"`, `phase: null`). An enabled or retired-setting lifecycle emits schema 2: sanitized state (id, state, stage, criteria view or a private stub), `stateHash` and `sourceHash`, without the workflow field. In off, a `phase` receipt write also keeps its #257 bytes (`tasks: []`); task import stays retired in every mode, so a non-empty list is refused.
3555
+ - Contract amendment, seeds (419 before and after: 414 byte-unchanged, 3 modified, 2 removed, 2 added; the registry baseline is unchanged). Modified, each with the same id, test file, test name and mutation intent: `workflow-reviewer-only` (the criteria/phase check), plus `override-local-schema` and `lifecycle-native-schema`. The person approved the last two on 2026-10-18, because the `lifecycleCriteria` plumbing changed their call sites. Removed with the code they mutated: `workflow-exact-after` and `lifecycle-phase-view-required`. Added for the new guards: `criteria-task-import-retired` and `sdlc-workflow-window-closes`. Tests that pinned the retired gsd-lite behaviour (task import, phase naming, the workflow projection, the implement id stored in an enabled config) are amended in the same PR; every other test is unchanged.
3556
+ - S0/S8 implement none of S1-S7 and S9-S11. The issue stays the spec, Tasks owns mutations and GitHub owns PR, check and tag facts.
3557
+ ## Headless peer instances I2 amendment (#450)
3558
+
3559
+ `instances` is a person-authored, machine-local object in an untracked
3560
+ `.agenthub/config.local.json`. Each additional `<kind>-<name>` id names its kind
3561
+ explicitly and may set `roles`, `start_mode`, `permission_mode` and `worktree`.
3562
+ The bound catalog belongs to one project/daemon; there is no process-global
3563
+ registration or suffix inference. Declarations are validated before trust
3564
+ filtering, cloned and frozen, and limited to 64 additional ids of at most 32
3565
+ ASCII characters. Settings cannot create or modify declarations. Identity,
3566
+ execution directory and account membership are restart-bound; a live reload
3567
+ cannot publish their derived defaults ahead of that restart.
3568
+
3569
+ I2 accepts definitions with a native headless factory and environment or ACP
3570
+ session MCP identity. Additional Claude/channel peers belong to I3. Jcode's
3571
+ project-file MCP identity is not isolated by this phase and is refused for extra
3572
+ instances. Additional instances start headlessly; the existing Codex native TUI
3573
+ still initializes and attaches to its instance's own app-server proxy. The hub
3574
+ never initializes that app-server on the TUI's behalf. `ahub <kind> --as <id>`
3575
+ selects the declared identity; selection is removed from native passthrough.
3576
+ Missing `peer_instances` evidence on an old daemon/upgrade target is a refusal
3577
+ before instance runtime effects, rather than a guess that the instance is a base
3578
+ peer.
3579
+
3580
+ Each additional implementer requires an explicit registered Git worktree at
3581
+ `<project>/.worktrees/<id>` with an attached branch. I2 creates no worktree or
3582
+ branch; I4 owns automatic worktree orchestration. A supplied reviewer worktree
3583
+ is checked by the same real-path, repository and registration boundary. Without
3584
+ a supplied directory, a reviewer may share the project checkout. The native
3585
+ process executes in that directory while its MCP environment retains the
3586
+ canonical project's hub binding. Launch/restore receipts keep canonical
3587
+ `projectRoot`, optional extra-instance `executionCwd` and observed `terminalRoot`
3588
+ separate. The terminal grouping root may be only that project root or the
3589
+ verified execution directory; exact live launcher, handle, incarnation and
3590
+ worktree evidence is still required. Native kind metadata alone never binds an
3591
+ extra instance. Revoked declarations or changed directories refuse reuse.
3592
+ Effective roles resolve from declaration roles, exact-id policy roles, kind policy
3593
+ roles, then definition defaults; launch validation uses the same order.
3594
+
3595
+ I2 recovery ceiling: a recovering extra Codex launcher records its launch row only
3596
+ after the authenticated start response supplies its execution-root binding. Until
3597
+ then, the coordinator retains durable pending terminal-creation and attachment-wait
3598
+ evidence; it never records an assumed checkout. Base Codex pre-start recording is
3599
+ unchanged. Earlier recording for extras requires independently verified exact-instance
3600
+ execution-root evidence. Past-commit resumes do not repeat pre-commit instance
3601
+ compatibility checks. Abort and stop-and-archive validate historical receipt structure
3602
+ and authenticated runtime ownership independently of mutable declarations; restore,
3603
+ fresh and reattach retain current declaration authority.
3604
+
3605
+ Routing expands a kind preference to its declared members and considers idle
3606
+ state, board WIP and queued load with stable ties. Exact manual candidates,
3607
+ reservations and nominations stay exact ids. Assignment and explain use the same
3608
+ pure decision and name the chosen instance. Reviewer independence compares
3609
+ families (the kind); an eligible other family takes precedence even when busy.
3610
+ Only when no other family is eligible may an assignment use its own family,
3611
+ recording `sameFamilyFallback=true` in assignment history. This independence rule
3612
+ also applies to an explicit same-family reviewer nomination. A declared owner of
3613
+ implement, bulk-edit or test work requires the current implementer role and positive
3614
+ host evidence tied to the actual adapter generation started in a verified noncanonical
3615
+ worktree; a role-only reload cannot promote a canonical reviewer process. External
3616
+ ids, including console recipients, retain their existing admission and explicit
3617
+ nomination behavior without acquiring native metadata or automatic kind expansion.
3618
+
3619
+ Quota readings, pause records and reset windows are shared by the definition's
3620
+ account (one account per kind in I2). Member telemetry retains its exact reporter
3621
+ id, native context remains per instance, and the shared account's quota pause,
3622
+ checkpoint, handoff and reset notice cover all its members. Existing manual
3623
+ pauses remain in force. A startup migration conservatively merges old alias
3624
+ pause rows, retaining their provenance and moves; no pause is discarded.
3625
+ Per-instance ports, native session paths, Pi tool ledgers and model relay
3626
+ callbacks do not borrow another instance's process or conversation.
3627
+
3628
+ Worktree facts and native turn snapshots use the validated execution checkout,
3629
+ while task and turn ids remain in the canonical hub database. An additive
3630
+ `turn_workspaces` receipt stores the exact extra-instance root and its snapshot
3631
+ fields atomically with turn creation. The legacy `turns` snapshot fields remain
3632
+ unknown for those rows, so an older CLI cannot restore their files into the
3633
+ canonical checkout. New readers hydrate the same public turn shape from the
3634
+ receipt. An absent receipt preserves historical external-peer undo behavior;
3635
+ an existing receipt requires the current trusted declaration and the same
3636
+ validated root before context changes or file restoration. Pruning a turn also
3637
+ prunes its workspace receipt. Review projections resolve converter programs, task
3638
+ paths and private-path policy in the execution checkout while their sandbox denies
3639
+ other canonical project file data, including when read_allow encloses that project.
3640
+ Overlap refusal remains conservative across
3641
+ separate worktrees; it may refuse an undo rather than assume independence.
3642
+
3643
+ The I2 seed contract amendment re-anchors only `roster-r-pi-override`,
3644
+ `roster-r-catalog`, `roster-result-stop-text`, `roster-detached-pi-recovery`,
3645
+ `data-pi-factory-wire`, `projection-local-trust`,
3646
+ `planning-reservation-supported` and `planner-reserved-status-row` to the
3647
+ contextual resolver, aggregate Pi ledger, execution directory and declared-id
3648
+ forms. Each keeps its id and named test and removes the same guarantee. The
3649
+ projection mutant still removes only `text_projection`; the status mutant still
3650
+ removes only reservations. The other 411 seeds and registry baseline are
3651
+ unchanged. The PR records every old and new search/replacement and its clean
3652
+ and mutant result, per the reviewer's explicit ruling.
3653
+
3654
+ ## Amendment: roster membership in status, 2026-10-18 (#484)
3655
+
3656
+ - The authenticated `status` reply carries `roster: {peer, on}[]` for every supported peer, optional peers included, with the same `on` that `ahub roster list` shows. The field is additive, with no protocol bump; older CLIs ignore it.
3657
+ - Launchers that check membership before starting (`ahub jcode`, `ahub kimi --mode tui`) read it through `rosterInStatus` in `src/hub/status-roster.ts` (no imports, so the registry's native CLI entries add no cycle). A reply without the field (an older hub) is unknown: the launcher stops with an upgrade-or-restart remedy and starts nothing. It never reads unknown as off (the jcode bug) or as on (the dead kimi guard; daemon admission still refused off-roster Kimi, so that one was harmless).
3658
+ - `settings_get` stays console-only.
3659
+ - With declared headless instances, status includes each startup-bound extra id as well as every built-in and optional peer, with its own roster membership. No undeclared suffix acquires a row.
@@ -0,0 +1,48 @@
1
+ # 0.12.34 release verification
2
+
3
+ This record covers release preparation and source review. It does not claim publication, installation, a running-hub restart or native/live acceptance.
4
+
5
+ ## Candidate
6
+
7
+ Version 0.12.34, control protocol 16 (`src/hub/control-client.ts`), from merged main `f1c4140032d81f4840941a91137e9ab593349d9f`. The candidate includes the three PRs merged since `v0.12.33`: #487 (#451 A2), #491 (#488) and #492 (#485 S0). The exact first-party memory pin remains `@staix/agent-mem` 0.3.1.
8
+
9
+ - #451 A2 moves built-in native policy behind the adapter registry. Native behaviour is unchanged except the disclosed Codex watchdog fence: late results of a cancelled turn are dropped, and a cancellation without a verified native id takes Codex offline until reattach. The round-2 delta reviews (task #132 review note) diffed base and head probe output (permission, start, roster, palette, crash plans, launch env, previews, `routing.assign` over 3,840 inputs) and found no other difference. The registry guard baseline is `[]`.
10
+ - #488 replaces the fixed two-rejection escalation with `tasks.escalate_after` (default 3, live). Upgrading changes the default behaviour; `docs/quickstart.md` says how to keep two.
11
+ - #485 S0 protects `.agent`, `_agents`, `_agent`, `.gemini` and `.grok` like other agent configuration directories. Scoped grants under them now ask.
12
+ - Still open: live native clients, installed managed-Pi #418 AC8 (#142) and #438 AC7.
13
+
14
+ ## Document review
15
+
16
+ `node scripts/check-docs.mjs --require-fresh` reported 14 stale documents. Each was compared with its covered source changes from its stamp to the candidate by two read-only reviews, one for the user documents and one for the agent notes. Symbols, paths and limits were checked in the source. No document review is deferred.
17
+
18
+ | Document | Review result | Checked claims and correction |
19
+ | --- | --- | --- |
20
+ | `README.md` | corrected | Status 0.12.34; the Jcode MCP entry is byte-identical (moved into a definition); the verification link and open legs. |
21
+ | `docs/quickstart.md` | corrected | `v0.12.34` install; the upgrade section for the escalation default (#488) and the new protected directories (#485). |
22
+ | `docs/operations.md` | corrected | 0.12.34 header, protocol 16 range and upgrade examples; escalation via `tasks.escalate_after`; the Claude ask-when-needed protected list; the Codex watchdog fence and offline latch. |
23
+ | `docs/security.md` | corrected | The protected agent configuration list and the #485 directories with their look-alike rule. |
24
+ | `docs/agent-notes/README.md` | unchanged | Background only; the console tone lookup change touches no rule. |
25
+ | `docs/agent-notes/adapters.md` | corrected | `session.zeroTurn` replaces `codexZeroTurn`; registry lists and cross-release literals; the empty guard baseline and alias resolution; native capability scope. Paths now include the registry guard test and baseline. |
26
+ | `docs/agent-notes/benchmarks.md` | unchanged | The Pi command now comes from its definition with the same value. |
27
+ | `docs/agent-notes/budget.md` | corrected | Context readers in `native-context.ts`; checkpoint requests keyed on `budget.checkpoint`; `QUOTA_HANDOFF_PLATFORMS`; quota exemption rules. Scope and paths include the moved readers and the registry. |
28
+ | `docs/agent-notes/bus.md` | unchanged | Bus, journal and deferred-hub sources are unchanged; daemon changes swap peer names for definition fields only. |
29
+ | `docs/agent-notes/daemon.md` | corrected | The registry's `KNOWN_PEERS`; the recovery literal probes; scope and paths include the moved recovery, policy, config and CLI definition modules. |
30
+ | `docs/agent-notes/local-worker.md` | unchanged | `grantablePath` and grant rules hold with the larger protected set. |
31
+ | `docs/agent-notes/models.md` | unchanged | Tool classification now reads `hooks.classifyTool` with the same result. |
32
+ | `docs/agent-notes/tasks.md` | corrected | The PII gate by `trust.onPrem`; `escalateAfter()` read per verdict. Paths include `builtin-metadata.ts` and `src/hub/bus.ts` (`pendingEnvelopes`, backlog #193). |
33
+ | `docs/agent-notes/tests.md` | corrected | Guard failures move policy into a definition, and the baseline stays `[]`; conformance records unsupported cases explicitly. |
34
+
35
+ `AGENTS.md` area notes list the new definition modules for Budget and Daemon and recovery. A separate manifest commit restamps the reviewed documents against the reviewed source; it does not stamp itself. The release PR must use a merge commit, and committed freshness is rerun on main before tagging.
36
+
37
+ ## Recorded checks
38
+
39
+ | PR | Final head | CI run |
40
+ | --- | --- | --- |
41
+ | [#487](https://github.com/STAIxBWLB/agent-hub/pull/487) | `60e7f61fd9d6f3f0b15fe94d2baf69e32a504f97` | [39100633474](https://github.com/STAIxBWLB/agent-hub/actions/runs/39100633474) |
42
+ | [#491](https://github.com/STAIxBWLB/agent-hub/pull/491) | `4af794fadfb00d3357c9e3e8011513bff4669f8e` | [39103534833](https://github.com/STAIxBWLB/agent-hub/actions/runs/39103534833) |
43
+ | [#492](https://github.com/STAIxBWLB/agent-hub/pull/492) | `5895e3aa88a9b7f9f395680cb3818ba2ec942901` | [39105301256](https://github.com/STAIxBWLB/agent-hub/actions/runs/39105301256) |
44
+
45
+ Each PR passed an OCR delegation review by Claude subagents at its final head, and its exact-head CI passed on both OSes with all four seeded shards. #491's macOS job hit the known 20 s `checks.test.ts` flake once; only that job was re-run, and it passed. These prior PR gates do not replace the release candidate's own exact-head CI.
46
+
47
+ - Generated assets: `bun install --frozen-lockfile` and `bun run build` ran locally at `74899a40`. The only change to `plugins/agent-hub/server.js` and the plugin manifest is the version string 0.12.33 -> 0.12.34; the release PR's CI checks bundle freshness.
48
+ - The release PR's own exact-head CI and the release workflow's tag checks are recorded on the PR and the tag, not here.
@@ -0,0 +1,49 @@
1
+ # 0.12.35 release verification
2
+
3
+ This record covers release preparation and source review. It does not claim publication, installation, a running-hub restart or native/live acceptance.
4
+
5
+ ## Candidate
6
+
7
+ Version 0.12.35, control protocol 16 (unchanged), from merged main `ac6ff4e382abcec45b5dffcc1fc85f402383dccf`. The person directed the release on 2026-10-18, first so that #493 takes effect, then to ship all open PRs once merged.
8
+
9
+ - #493 (PR #495): a busy `ahub claude` session reads its queue with `hub_inbox`, sees fresh queued and important counts, and receives important messages mid-turn; `[FYI]` is forbidden for actionable messages.
10
+ - #484 (PR #500): `status` carries roster membership, and `ahub jcode` and `ahub kimi --mode tui` read it; an older hub is unknown, not off.
11
+ - #219 task (PR #499): the protected-segment grant test no longer grows with the set (test-only).
12
+ - #450 I2 (PR #497): declared headless peer instances with their own native and MCP identity, worktree execution roots for extra implementers, kind routing across instances, and account-shared quota.
13
+ - #481 S0+S8 (PR #496): the playbook lifecycle as the enabled default, gsd-lite retired into the `criteria` checklist, and a deprecation window until 0.13.0. Off keeps its #257 bytes.
14
+ - Still open (unchanged): live native clients, installed managed-Pi #418 AC8 (#142), #438 AC7, the native console settings leg (#439 AC5), a real upgrade with reattach (#463), a real upgrade with a managed terminal and cancelled rows (#478), and the live advise cycle of #481 AC9.
15
+ - New open legs:
16
+ - After installation, a busy `ahub claude` session reads its queue with `hub_inbox` and sees a steered important message before its turn ends (#493 D3, installed).
17
+ - A live run of two instances of one kind (#450 I4, #138).
18
+
19
+ ## Reviews
20
+
21
+ | PR | Final head | Review | CI |
22
+ | --- | --- | --- | --- |
23
+ | #495 (#493) | 3730bf20 | planner plus an independent OCR pass | exact head, success |
24
+ | #500 (#484) | b4a1bd6b | codex, approved | exact head, success |
25
+ | #499 (#219) | a67fd222 | codex, approved | exact head, success |
26
+ | #497 (#450 I2) | 254ba163 | two fresh-context reviews (round 1: changes requested, B1-B5); round-2 fresh review, approved; merge-delta review | exact head, success (macOS watchdog job rerun once) |
27
+ | #496 (#481 S0+S8) | b1120f96 | codex: round 1 five P2s, round 2 one P1 (off-mode PII screen), round 3 approved | exact head, success (macOS #463 attach-timeout job rerun once; passes locally) |
28
+
29
+ ## Document review
30
+
31
+ Round 1 checked 10 documents against #495, round 2 against #499 and #500, and round 3 13 stale documents against #497 and #496, read by a fresh-context reviewer and applied by the planner.
32
+
33
+ | Document | Result | Checked claims and correction |
34
+ | --- | --- | --- |
35
+ | `README.md` | corrected (round 1) | Status 0.12.35; the Jcode entry sentence's version; the verification link. Nothing #497 or #496 invalidates. |
36
+ | `docs/quickstart.md` | corrected | `v0.12.35` install. Upgrade paragraphs for #493 (session restart), #484, the #481 deprecation (`workflow`, the `phase` gate, `criteria` receipts) and #450 I2 instances. |
37
+ | `docs/operations.md` | corrected (rounds 1 and 2) | Busy channel sessions; the Jcode roster read. The #497 instance and #496 lifecycle sections match the code. |
38
+ | `docs/security.md` | corrected | `instances` is machine-local (read only from an untracked `config.local.json`) and refused from every surface; extras accept only `headless`. |
39
+ | `docs/sdlc.md` | corrected | The off schema-1 export, and the `phase` tool schema of off or older daemons. |
40
+ | `docs/specs/2026-09-19-agent-hub-design.md` | corrected | The #481 deprecation bullet: only `workflow = "gsd-lite"` and the `phase` gate warn; the `phase` receipt name is accepted silently. |
41
+ | `docs/agent-notes/tasks.md` | corrected | `checklistOf` screening and off compatibility; instance id resolution and family fallback; owner isolation proof. |
42
+ | `docs/agent-notes/budget.md` | corrected | Account-keyed quota, pause, checkpoint and handoff with per-member fanout; scope includes `instance-budget.ts`. |
43
+ | `docs/agent-notes/daemon.md` | corrected | Startup-bound declarations, execution roots, instance recovery and undo; scope includes the instance modules. |
44
+ | `docs/agent-notes/adapters.md` | corrected | Spawn identity per instance; an ACP kind only from the host declaration. |
45
+ | `docs/agent-notes/local-worker.md` | corrected | Scope includes the sandbox root in `instance-execution.ts`; no rule changed. |
46
+ | `docs/agent-notes/bus.md` | corrected (round 1) | Channel pull while busy; `WsPeer.steer` scope. No #497/#496 rule. |
47
+ | `docs/agent-notes/tests.md`, `benchmarks.md`, `README.md` | unchanged | #497/#496 touched only shared paths; no rule is wrong. |
48
+
49
+ `AGENTS.md` area notes and their `docs/verified.json` paths now list `instances.ts`, `instance-config.ts`, `instance-execution.ts` and `instance-budget.ts`. A separate manifest commit restamps the reviewed documents. The release PR must be merged with a merge commit so the stamps stay ancestors of the tag.