@staix/agent-hub 0.32.0 → 0.33.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 (43) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +2 -2
  3. package/docs/design/bus.md +68 -2
  4. package/docs/dogfood.md +1 -0
  5. package/docs/memory.md +9 -3
  6. package/docs/operations.md +47 -14
  7. package/docs/quickstart.md +12 -2
  8. package/docs/security.md +28 -9
  9. package/docs/specs/2026-09-19-agent-hub-design.md +31 -4
  10. package/docs/specs/2026-09-20-upgrade-recovery-design.md +7 -3
  11. package/docs/verification/2026-11-06-0.33.0.md +222 -0
  12. package/docs/verification/2026-11-06-claude-implementer-2.1.319.md +57 -0
  13. package/docs/verification/2026-11-06-codex-0167-reviewer-isolation.md +56 -0
  14. package/docs/verification/2026-11-06-codex-0167-reviewer-tool-call.md +66 -0
  15. package/docs/verification/2026-11-06-kimi-251-reviewer-compat.md +88 -0
  16. package/docs/verification/2026-11-06-orca-1.4.250-cli-contract.md +50 -0
  17. package/docs/verification/2026-11-06-qwen-0268-acp.md +75 -0
  18. package/docs/verification/2026-11-06-qwen-0268-dual-output.md +44 -0
  19. package/docs/verification/claude-shell-wrapper-native.py +1 -1
  20. package/docs/verified.json +10 -10
  21. package/package.json +2 -2
  22. package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
  23. package/plugins/agent-hub/server.js +528 -206
  24. package/src/adapters/compat.ts +11 -11
  25. package/src/broker/protocol.ts +5 -0
  26. package/src/broker/server.ts +54 -4
  27. package/src/broker/store.ts +6 -3
  28. package/src/cli/output.ts +5 -1
  29. package/src/cli/room.ts +17 -5
  30. package/src/cli/status-lines.ts +8 -1
  31. package/src/cli/terminal-recovery.ts +37 -15
  32. package/src/hub/bus.ts +7 -0
  33. package/src/hub/daemon.ts +13 -4
  34. package/src/rooms/application.ts +15 -0
  35. package/src/rooms/commands.ts +76 -16
  36. package/src/rooms/health.ts +32 -0
  37. package/src/rooms/link.ts +267 -43
  38. package/src/rooms/remote-peer.ts +18 -3
  39. package/src/rooms/service.ts +27 -12
  40. package/src/rooms/status.ts +57 -1
  41. package/src/rooms/store.ts +20 -1
  42. package/src/rooms/wire.ts +10 -8
  43. package/src/ui/index.html +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,26 @@ Issue and pull request numbers in the entries for 0.7.7 and earlier refer to the
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.33.0
8
+
9
+ - Exact-pin the first-party agent-mem core to 0.22.1 (PR #1243, task 754). It includes the upstream strict-host TOML serialization fix and adds no runtime dependency. Placement activation and writer renewal remain opt-in person commands; a pin upgrade does not activate a home or add the hub's missing fresh placement-attestation integration.
10
+ - Correct inactive-placement CLI/dashboard guidance and memory documentation (PR #1244, task 755): the native person-only `amem migrate --sync-placement --dry-run` preview exists and requires every writer through `--writer-root`. The hub still does not supply fresh `placementAttestation` for active-placement sync (#1173); `ahub memory declined` remains the safe inspection step. No activation or API adoption is performed.
11
+ - Rooms expose retained refusal counts, outbox depth/ages, last receipt age and closed link causes with recovery steps (#1204 T4, PR #1237, task 737). Store opening failures retry with bounded backoff, verified journal recovery wakes deferred inbound work, and selective three-member traffic raises no false sequence-gap notice. Codec support is signed current-session compatibility evidence; pending observations keep the original queue expiry and known unsupported feature sends refuse before effects. Plain chat and existing permission, privacy, replay and person-disposition fences remain unchanged. PR #1241 (task 753) documents the rolling-upgrade order and simplifies status projections without behavior changes.
12
+ - Orca terminal recovery recognizes `terminal_exited`, `terminal_gone` and `no_connected_pty` alongside the existing stale-handle code, and preserves Orca's structured error code in failures (#1233, PR #1235, task 746). A missing terminal still follows the existing launcher ownership and reopen checks.
13
+ - Record the single authorized Codex 0.167.0 reviewer tool-call attempt (Refs #888, task 751): startup isolation and the rendered marker precondition passed, but the harness readiness/readback leg did not produce a complete verdict result. No retry; 0.167.0 remains unverified (`docs/verification/2026-11-06-codex-0167-reviewer-tool-call.md`).
14
+ - Verify exactly Qwen ACP 0.26.8 with model-free native macOS arm64 initialization, session, mode and published permission-handler receipts, plus Linux x86_64 evidence (#888, task 749). Qwen dual-output 0.26.8 stays unqualified: required queued-submit Q2 fails identically on the matched 0.26.1 control; its verified entry stays at 0.26.1. Real account/model behavior remains unverified.
15
+ - Kimi Code 2.5.1 is an exact receipt-verified fresh-reviewer version (#888, task 748): the official macOS arm64 artifact passes the production preparation and native two-tool/Write controls in fixture-trust and verified/no-trust runs (`docs/verification/2026-11-06-kimi-251-reviewer-compat.md`). Runtime preparation remains required; real account, model and quota behavior remain unverified.
16
+ - Claude Code 2.1.319 is a receipt-verified headless implementer version (#888, task 750): the model-free permission-transport and host shell-wrapper producers pass on it with 2.1.318 as the control (`docs/verification/2026-11-06-claude-implementer-2.1.319.md`).
17
+ - Codex 0.167.0 passed the model-free reviewer isolation procedure (#888, task 747): all four legs passed with 0.166.0 as the control (`docs/verification/2026-11-06-codex-0167-reviewer-isolation.md`). This is model-free evidence only; the single authorized tool-call attempt above ended with an unknown outcome, so 0.167.0 stays unverified and any new attempt needs fresh person authorization. The person can explicitly trust that version, but every runtime proof still runs. Verified stays 0.146.0, 0.163.0, 0.164.0 and 0.166.0.
18
+
19
+ - 0.33.0 N-1: published 0.32.0, the latest 0.32.x patch, pins agent-mem 0.21.0; this hub pins agent-mem 0.22.1. Control remains protocol 17 (descriptor floor 16). The release N-1 fixture and matrix retain published 0.32.0/core 0.21.0; the separate protocol-16 fixture stays 0.25.0.
20
+ - Room wire: 0.33.0 keeps `x-agent-hub-ephemeral: 1` and adds a separate `x-agent-hub-codecs: 1` upgrade header. A released 0.32.0 broker ignores the latter and retains ephemeral presence/liveness. A 0.32.0 member on a 0.33.0 broker receives its unchanged legacy ready/presence grammar, never codec advertisements or inventories. Plain v1 chat works in both directions.
21
+ - Rolling upgrade: a 0.33.0 person-inbox (`user@label`) or invocation send to a 0.32.0 member, or between upgraded hubs through a 0.32.0 broker, is refused before any effect with the upgrade step. Upgrade the broker, then every member to a codec-capable release, then reconnect. A merely pending observation waits under the original queue expiry; no timer grants support. Codec evidence grants no native, exposure, privacy or task authority.
22
+ - CLI/status: the 0.32.0 `ahub room status` command drops additive health, closed cause and generated action fields, including in its JSON output; its generic `ahub status --json` instead passes raw daemon fields through unchanged. A 0.33.0 room-status client accepts missing diagnostics from an older daemon as unknown. The sequence-gap operator notice is removed; the signed room-wide sequence and permanent replay floors are unchanged.
23
+ - Shared memory home: agent-mem 0.22.x's own N-1 statement keeps curated, capture, hook-spool, candidates, work-list and setup-receipt formats, `INDEX_VERSION` and the index file name unchanged from 0.21.0. Shared-v1, generation and v1/v2 shard sync are unchanged; inactive homes behave as before. Placement activation and writer renewal are opt-in person commands. If renewal history is present, the 0.21.0 closed journal reader refuses that history and placement publication before effects. The person coordinates shared-home operations separately after release; this preparation performs none of them.
24
+ - Local compatibility: hub.db remains schema 2 and RoomStore remains schema 5. The current core is 0.22.1 while N-1's is 0.21.0, with the shared-home limits above. The Orca recovery correction and exact compat additions change neither the control protocol nor native authorization; Codex reviewer 0.167.0 and Qwen dual-output 0.26.8 remain unqualified.
25
+ - Evidence ceiling: the N-1 fixture uses the unmodified published 0.32.0 package for control/plugin and isolated broker/member tests. These source/fixture claims do not establish real-account inference, live TLS/proxy behavior, installation or two-machine operation; the release verification report records execution results separately.
26
+
7
27
  ## 0.32.0
8
28
 
9
29
  - Rooms gain advisory liveness and person-visible epoch changes (T3 of #1204, task 736). An ephemeral-capable broker enables 30-second presence refresh and unknown status after three missed periods; aging never changes sending authority. Graceful stop fences new work and attempts a signed offline snapshot within two seconds without overtaking an attempted FIFO head. Legacy brokers report liveness untracked with an upgrade step. Epoch-changing commands preview sealed outstanding delivery IDs, recheck the exact set and roster, and immediately hold old-epoch work as needs_review with the cause "epoch rotated". Bus-only work and person/terminal dispositions are preserved; T4 remains open.
package/README.md CHANGED
@@ -5,7 +5,7 @@ Code, Codex, Kimi Code, Pi and a hub-owned local worker (plus Qwen Code, Jcode a
5
5
  Antigravity if you want them) share a message bus, a task board and a memory, each
6
6
  connected through its own native interface.
7
7
 
8
- Status: 0.32.0, control protocol 17 (accepts 16). Bun + TypeScript, one loopback daemon per
8
+ Status: 0.33.0, control protocol 17 (accepts 16). Bun + TypeScript, one loopback daemon per
9
9
  project. Site: [agent-hub.staix.net](https://agent-hub.staix.net).
10
10
 
11
11
  ## Quick start
@@ -143,7 +143,7 @@ uses the home must run a version that understands the new layout.
143
143
  [#258](https://github.com/STAIxBWLB/agent-hub/issues/258)).
144
144
 
145
145
  Live checks that still need a real account or a person are listed in the
146
- [release verification report](docs/verification/2026-11-06-0.32.0.md) and the
146
+ [release verification report](docs/verification/2026-11-06-0.33.0.md) and the
147
147
  [smoke checklist](docs/smoke.md).
148
148
 
149
149
  ## Documentation
@@ -119,7 +119,7 @@ persistence, which belong to T2. Existing layer caps remain authoritative.
119
119
 
120
120
  ### Room wire compatibility (#1204 T1)
121
121
 
122
- The link requests only the ephemeral feature with the WebSocket upgrade header
122
+ Version 1 requests only the ephemeral feature with the WebSocket upgrade header
123
123
  `x-agent-hub-ephemeral: 1`. A supporting broker includes `ephemeral: true` in its
124
124
  ready response only to an opted-in client, preserving the exact legacy ready
125
125
  shape for older hubs. Each new connection starts with the feature disabled.
@@ -130,7 +130,7 @@ members under its old queue rules. Upgrade the broker for ephemeral retention.
130
130
  A supporting broker forwards ephemeral presence only to ready members that
131
131
  opted in. Older members do not see upgraded members' presence until they upgrade. Application
132
132
  chat frames keep the legacy shape. This is the one-bit compatibility bridge;
133
- full codec feature advertisement belongs to #1204 T4.
133
+ current links keep this header unchanged and add the codec opt-in described below.
134
134
 
135
135
  Ephemeral replacement preserves a recipient's outstanding one-packet transport
136
136
  slot until its matching ACK or the original TTL/grace bound expires. Only the
@@ -231,3 +231,69 @@ ACK after durable local commit of either the receipt or the inbox entry.
231
231
  Deferred application admission may ACK its durable crypto inbox entry so it does
232
232
  not pin broker capacity; later admission commits and replays the same durable
233
233
  receipt path before retiring its local work.
234
+
235
+ ## Room codec visibility and sequence diagnostics (#1204 T4)
236
+
237
+ The room-wide signed sequence counter and durable replay floors stay unchanged.
238
+ A chat addresses one recipient, so another member can legitimately observe a
239
+ numeric gap. The host no longer turns that number into an operator loss notice;
240
+ three-member selective traffic therefore produces no false sequence-gap alarm.
241
+ The low-level replay result remains available to transport tests and does not
242
+ relax authentication, permanent sequence floors or exactly-once application admission.
243
+
244
+ Codec support is compatibility evidence from fresh authenticated presence, never
245
+ a permission or privacy grant. Every link retains the released
246
+ `x-agent-hub-ephemeral: 1` upgrade header byte for byte and adds
247
+ `x-agent-hub-codecs: 1` in the same WebSocket upgrade. Released brokers ignore
248
+ the codec header and retain ephemeral presence and liveness. A supporting
249
+ broker adds `codecFeatures: true` and the connection's `codecSession` token
250
+ only to an opted-in client's ready response. Legacy ready and presence shapes
251
+ remain unchanged.
252
+
253
+ Upgraded links keep the existing signed presence payload byte shape and send a
254
+ separate presence snapshot carrying a bounded, sorted `features` list. That
255
+ snapshot has signed `ephemeral: true` and `codecFeatures: true` headers. The
256
+ broker routes it only to clients that opted into codec support; legacy clients
257
+ receive only their original presence grammar. Legacy and codec snapshots have
258
+ separate coalescing groups so neither can replace the other's pending state.
259
+ The signed feature snapshot echoes its connection's `codecSession`; it does not
260
+ request a reply or renew peer-state observations. Ordinary presence does not
261
+ revoke support for that same connection.
262
+
263
+ Before ciphertext delivery, the broker gives codec-aware recipients a bounded
264
+ `codec_peers` inventory scoped to the current roster digest. A row names an
265
+ authenticated member's current connection token and whether it opted into codec
266
+ advertisements; a null token means the observation is pending or disconnected.
267
+ Replacement, disconnect and roster change invalidate prior connection evidence.
268
+ Only a fresh signed advertisement echoing the current token establishes support;
269
+ a delayed advertisement from another session cannot establish it. New current
270
+ peer-session evidence also triggers a coalesced feature-only advertisement from
271
+ this hub, independently of legacy replies and snapshot dedupe; missed bootstrap
272
+ advertisements therefore do not require unrelated application traffic to recover.
273
+
274
+ An early ordinary live-state observation from a codec-capable session waits as
275
+ bounded metadata until that session supplies signed codec evidence. Releasing
276
+ it preserves its original local receive time; the signed advertisement does not
277
+ renew liveness. Empty or offline snapshots and known legacy sessions remain
278
+ immediate. The receive-time annotation is host-only and is never accepted from
279
+ the room wire.
280
+
281
+ The advertised codecs are `chat_v1`, `person_inbox_v1` and `read_invocation_v1`.
282
+ Plain chat and status retain their legacy shape. Person-inbox sends require
283
+ `person_inbox_v1`; invocation kinds require `read_invocation_v1`. Compatibility
284
+ has three states: pending, supported and unsupported. Pending observations defer
285
+ the original Bus queue entry without application, sequence or socket effects;
286
+ the original queue lifetime still bounds this wait. A signed advertisement wakes
287
+ that member's queued feature-required sends as well as retained durable intents.
288
+ The pending path rechecks observations after requeue so an advertisement arriving
289
+ during asynchronous refusal cannot be lost. No timer or grace period grants support.
290
+ The private low-level link API has no Bus queue: it returns a typed not-sent
291
+ pending outcome and the caller retries after signed evidence; it never waits
292
+ inside the serialized receive lane. Codec-aware publication puts signed codec
293
+ evidence before its ordinary peer-state observation on the outbound FIFO.
294
+ Only a known legacy transport, an authenticated legacy member, or a signed
295
+ advertisement missing the required feature refuses with the upgrade-and-reconnect
296
+ step. Support is rechecked across awaited admission and at actual publication.
297
+ Live signed observations are scoped to the current connection and roster; saved,
298
+ stale or replayed presence never grants codec support. Existing native, exposure,
299
+ privacy and invocation authorization checks still decide whether a send is allowed.
package/docs/dogfood.md CHANGED
@@ -25,6 +25,7 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
25
25
  | Presence publication cost (#1204, #740) | source and isolated broker coverage; installed rooms remain off here | unchanged 1,000-flip AC1 test under its 20 s guard; transient pause/resume journal-write count, explicit manual-pause persistence, requestReply and exposure fences; hosted macOS is the acceptance gate |
26
26
  | Room automatic resend and late settlement (#1204 T2) | off here; source and isolated in-process broker coverage after validation; release and person enrollment/exposure required; live two-machine behavior remains unverified | AC2-AC4: receiver offline for 15 minutes then each application admitted once; pre-enqueue refusal retries without uncertainty; ACK deadline resends within the original TTL; signed late receipt settles once; local receipt commit survives restart before broker storage; no person-disposition override or native/task-read evidence |
27
27
  | Room liveness and epoch-change preview (#1204 T3, #736) | source and isolated fixtures, validation pending; rooms remain off here and installed/two-machine behavior is unverified | `rooms-liveness-link-736.test.ts`: signed offline within five seconds, idle crossed-request convergence and no reply loop, synchronous stop fence/FIFO preservation; `rooms-presence-aging-736.test.ts`: three local periods to advisory unknown without changing outbound admissibility, legacy untracked behavior, restart and clock rollback; `rooms-rotation-736.test.ts`: sorted ids-only preview, changed id-set/digest refusal, sealed hold versus Bus-only queue, unchanged person/terminal disposition; `rooms-liveness-status-736.test.ts`: native state preserved, broker upgrade guidance and named epoch-rotated cause; defaults 30 s refresh, 90 s aging, 2 s stop bound; exact-head gate and live proof remain separate |
28
+ | Room health and codec compatibility (#1204 T4, #737) | source and isolated fixtures; installed rooms remain off here | metadata-only refused counts, outbox depth/ages, closed causes, store-open retry/stop and clock rollback; Bus recovery edge wakes receive-only admission; selective three-member traffic emits no false gap; broker opt-in preserves released-broker ephemeral/liveness and legacy presence; immediate-online and forced-refresh feature sends defer pending observations under the original TTL, known unsupported codecs refuse before wire effects; dgx02 and hosted evidence recorded in the PR, native/account and two-machine receipts remain unverified |
28
29
  | Worktree shelf (#1057): `ahub worktrees`, `tidy`, `tidy --confirm <fingerprint>`, the Agents panel section, Park/Pin, the explicit PR refresh and the inbox alert | fixture-only until a person uses it, and only after release and upgrade: this repository keeps every task in `.worktrees/<name>`, so it is the first real use, but nothing here has run `tidy --confirm` yet, and `worktrees.quiet_days` stays 7 until the owner has used it for a week | `ahub worktrees` live and settled counts over a week, and how many settled rows a person then Pins (a Pin means a rule was wrong); `tidy` preview refusals by reason (`task not approved or cancelled`, `unpushed commits`, `branch changed since preview`); after a confirm, `git worktree list` against the preview; test/worktree-shelf.test.ts, test/worktree-tidy.test.ts and test/worktree-panel.test.ts (a PII row stays live and redacted, a branch switch refuses, no GitHub call on a read, the daemon removes nothing) |
29
30
  | Message bus, digests, priorities | on | `ahub report`: messages, digests, overflow, undeliverable; delivery latency from events |
30
31
  | Control-send recipient normalization (#963) | active after release and hub upgrade; this PR does not change the running hub | string recipients reach only the named peer, invalid shapes publish nothing, omitted/empty arrays preserve broadcast; real native recipient behavior remains unverified |
package/docs/memory.md CHANGED
@@ -271,8 +271,14 @@ An unchanged failure emits one safe log line per episode. A complete bounded pol
271
271
 
272
272
  `ahub memory declined [--json]` is a person-only, read-only inspection. It reports physical outbound row IDs and safe policy categories, never title, body, path nodes or literal private patterns. Reads defer promotions and recheck the profile binding. Forgotten originals still matter: `forget` changes materialized visibility but leaves the source row in append-only history. Do not use it as a promise to clear a sync refusal.
273
273
 
274
- The exact-pinned agent-mem 0.21.0 supplies bounded `inspectSyncPolicy` inspection for shared-v1 and generation profiles. A complete result lists the declined IDs and safe rule categories for the inspected physical outbound history, including originals hidden by a later forget. An unavailable, stale or bounded-out inspection remains explicitly incomplete; it never proves that no declined rows exist. The hub uses the public SDK rather than private helpers, snapshots of full history or its own portable log reader.
274
+ The exact-pinned agent-mem 0.22.1 supplies bounded `inspectSyncPolicy` inspection for shared-v1 and generation profiles. A complete result lists the declined IDs and safe rule categories for the inspected physical outbound history, including originals hidden by a later forget. An unavailable, stale or bounded-out inspection remains explicitly incomplete; it never proves that no declined rows exist. The hub uses the public SDK rather than private helpers, snapshots of full history or its own portable log reader.
275
275
 
276
- The package also owns per-row local placement. The hub adopts only the projection of a successful trusted SDK placement result: `ok` with its verified withheld/exported counts. This is tested through an injected SDK-result seam, not an activated store. Agent-mem 0.21.0 requires a fresh `placementAttestation` for each v3 sync; the default hub does not supply one, so its active-v3 sync remains unsupported until legitimate host-attestation integration is added. The hub never fabricates that proof. Count projection does not delete or rewrite notes, change policy or promote a declined row; transport failures remain failures.
276
+ The package also owns per-row local placement. The hub adopts only the projection of a successful trusted SDK placement result: `ok` with its verified withheld/exported counts. This is tested through an injected SDK-result seam, not an activated store. Agent-mem 0.22.1 requires a fresh `placementAttestation` for each v3 sync; the default hub does not supply one, so its active-v3 sync remains unsupported until legitimate host-attestation integration is added. Activation alone does not enable this hub's automatic sync, and the hub never fabricates that proof. Count projection does not delete or rewrite notes, change policy or promote a declined row; transport failures remain failures.
277
277
 
278
- Legacy stores without active per-row placement still refuse a sync containing declined rows. Agent-mem 0.21.0 provides no activation command; the hub neither invents one nor supplies a local fallback or fabricated activation proof. The missing core activation path is tracked by [agent-mem#281](https://github.com/STAIxBWLB/agent-mem/issues/281). Complete bounded diagnostics address #1173 AC4; The AC5 result projection is ready, while default-host active-v3 sync still requires supported activation and fresh-attestation integration. #1173 remains open until #281 ships and the hub adopts its supported path. Source adoption and isolated fixtures do not establish activation, deployed behavior or a successful sync of the person's memory home.
278
+ Legacy stores without active per-row placement still refuse a sync containing declined rows. The native amem CLI has person-only activation from 0.22.0 ([activation documentation](https://github.com/STAIxBWLB/agent-mem/blob/v0.22.1/README.md#initial-sync-placement-activation)). A person using the 0.22.1 CLI can preview it with every local writer installation declared, including the CLI and hub library installs:
279
+
280
+ ```sh
281
+ amem migrate --sync-placement --dry-run --writer-root '<cli-install-root>' --writer-root '<host-amem-install-root>' --json
282
+ ```
283
+
284
+ Declare any other local writers too, and review the package's layout and version prerequisites before a separately authorized apply. The preview writes nothing; activation does not migrate layouts, change privacy policy or automatically raise a format floor. This hub neither invokes activation nor supplies a local fallback or fabricated attestation. Complete bounded diagnostics address #1173 AC4; AC5 has result projection only. #1173 remains open for legitimate fresh host-attestation integration. Source adoption and isolated fixtures do not establish activation, deployed behavior or a successful sync of the person's memory home.
@@ -1,6 +1,6 @@
1
1
  # Operations guide
2
2
 
3
- This guide describes ahub 0.31.0 and control protocols 16 through 17. Live verification
3
+ This guide describes ahub 0.33.0 and control protocols 16 through 17. Live verification
4
4
  results and remaining prerequisites are recorded separately in [the smoke ledger](smoke.md).
5
5
 
6
6
  ## Agent-operated live verification
@@ -1824,7 +1824,7 @@ ahub memory forget 1a2b3c4d # a person's; also promote, demote, sup
1824
1824
 
1825
1825
  `"memory": { "native": false }` in `.agenthub/config.json` turns it off for a project.
1826
1826
 
1827
- The exact-pinned `@staix/agent-mem` 0.20.1 resolves `AMEM_HOME`, then `$AGENTHUB_HOME/memory`, then `~/.agenthub/memory`. An absent `M/profile.json` selects shared v1; an explicit generation selects `M/generations/G` with the package's readonly legacy bridge. All daemon memory consumers and the hub memory/goal CLI use that selected profile. Invalid metadata or a missing selected generation makes native memory unavailable while the bus and board continue; there is no fallback to legacy writes. Inspect the daemon's memory binding/availability before interpreting missing memory as an empty store.
1827
+ The exact-pinned `@staix/agent-mem` 0.22.1 resolves `AMEM_HOME`, then `$AGENTHUB_HOME/memory`, then `~/.agenthub/memory`. An absent `M/profile.json` selects shared v1; an explicit generation selects `M/generations/G` with the package's readonly legacy bridge. All daemon memory consumers and the hub memory/goal CLI use that selected profile. Invalid metadata or a missing selected generation makes native memory unavailable while the bus and board continue; there is no fallback to legacy writes. Inspect the daemon's memory binding/availability before interpreting missing memory as an empty store.
1828
1828
 
1829
1829
  The daemon checks its selector at hub operation entry and before candidate/counter writes. It does not hot-switch handles or provide an atomic fence against selection changes during an in-flight core call. Quiesce consumers and close their handles before migration or selection changes; reopen through the supported session-preserving lifecycle afterward. Candidate/counter storage remains `M/candidates.db`, independent of `G`; since agent-mem 0.7.0 `amem review` also lists and accepts candidates on a selected generation. Every running hub using this home needs an authenticated receipt: a matching ready binding, or a generation-capable unbound receipt (`disabled` when native memory is off, `unavailable` when opening failed) proving it holds no memory handle. An unbound daemon and zero running hubs are quiesced for memory; a stale bound handle, unreadable registry or unknown runtime is not ready. Existing JSON memory/goal results remain unchanged; the additive binding receipt belongs to daemon status, profile-check and the decay object. This source integration does not authorize installing a new runtime, migrating real memory, restarting sessions or claiming real-machine sync/capture receipts. Migration/deactivation and their limits belong to [agent-mem](https://github.com/STAIxBWLB/agent-mem); see [the hub profile contract](memory.md#selected-memory-profile).
1830
1830
 
@@ -3569,7 +3569,7 @@ or the plugin is older than the daemon it installed (#1179). It prints nothing w
3569
3569
  | Runtime | Control protocol window | Legacy status field |
3570
3570
  | --- | --- | --- |
3571
3571
  | 0.12.20 through 0.25.0 | 16 only | `protocol: 16` |
3572
- | 0.26.0 through 0.32.0 | 16 through 17 | `protocol: 16`, `protocolMin: 16`, `protocolMax: 17` |
3572
+ | 0.26.0 through 0.33.0 | 16 through 17 | `protocol: 16`, `protocolMin: 16`, `protocolMax: 17` |
3573
3573
 
3574
3574
  New clients choose the highest common protocol. The protocol window remains 16
3575
3575
  through 17, so the published protocol-16 client and channel plugin remain usable; unrelated feature
@@ -3577,7 +3577,10 @@ capabilities still require their own labels. A disjoint window refuses with 4426
3577
3577
  The compatibility-floor `protocol` field remains readable by old clients.
3578
3578
 
3579
3579
  Release N-1 is counted in minor versions, separately from this protocol window
3580
- (#1164, family contract entelecheia/ai-workspace#70). For 0.32.x, N-1 is 0.31.0,
3580
+ (#1164, family contract entelecheia/ai-workspace#70). For 0.33.x, N-1 is 0.32.0,
3581
+ the latest published patch of 0.32.x (exact `@staix/agent-mem` 0.21.0, control
3582
+ protocol 17 with descriptor floor 16). Every patch on 0.33.x keeps that release
3583
+ baseline. For 0.32.x, N-1 is 0.31.0,
3581
3584
  the latest published patch of 0.31.x (exact `@staix/agent-mem` 0.21.0, control
3582
3585
  protocol 17 with descriptor floor 16). Every patch on 0.32.x keeps that release
3583
3586
  baseline. A change that cannot retain it needs a new minor release. The 0.31.x
@@ -4876,7 +4879,7 @@ selected roster and existing capabilities; the TUI is always a person's start.
4876
4879
  - If the hub cannot read the event file the peer is `detached`, shown as offline with a notice, never idle: Qwen itself keeps working, and the hub reattaches when the file is readable again.
4877
4880
  - Restart: if the hub restarts while your Qwen keeps running, it reads on from its saved offset (no event twice, no launch). If Qwen is gone, `ahub qwen --mode tui` starts `qwen -r <session id>` on the same two files; the earlier submits are not replayed and the recorded answers are not shared again. Recovery never restores this terminal as a headless worker, and `ahub stop qwen` refuses: end Qwen in its own terminal.
4878
4881
 
4879
- Receipt-verified native ACP identities are qwen-code 0.25.0 and 0.26.0 ([dated receipt](verification/2026-10-22-kimi-qwen-compat.md)), 0.26.1 ([0.26.1 receipt](verification/2026-10-26-qwen-0261-acp.md)) 0.26.4 ([0.26.4 ACP receipt](verification/2026-10-31-qwen-0264-acp.md)) and 0.26.5 ([0.26.5 ACP receipt](verification/2026-11-03-qwen-0265-acp.md)). The separate [0.26.4](verification/2026-10-31-qwen-0264-dual-output.md) and [0.26.5](verification/2026-11-03-qwen-0265-dual-output.md) dual-output attempts did not establish their queued-turn criterion, so `qwen-dual` stays at 0.26.1. A CLI version label alone
4882
+ Receipt-verified native ACP identities are qwen-code 0.25.0 and 0.26.0 ([dated receipt](verification/2026-10-22-kimi-qwen-compat.md)), 0.26.1 ([0.26.1 receipt](verification/2026-10-26-qwen-0261-acp.md)), 0.26.4 ([0.26.4 ACP receipt](verification/2026-10-31-qwen-0264-acp.md)), 0.26.5 ([0.26.5 ACP receipt](verification/2026-11-03-qwen-0265-acp.md)) and 0.26.8 ([0.26.8 ACP receipt](verification/2026-11-06-qwen-0268-acp.md)). The separate [0.26.4](verification/2026-10-31-qwen-0264-dual-output.md), [0.26.5](verification/2026-11-03-qwen-0265-dual-output.md), and [0.26.8](verification/2026-11-06-qwen-0268-dual-output.md) dual-output attempts did not establish their queued-turn criterion, so `qwen-dual` stays at 0.26.1. A CLI version label alone
4880
4883
  is insufficient: startup verifies its native identity/version and advertised mode
4881
4884
  ids before any prompt. The earlier local installation reported CLI 0.25.0 while
4882
4885
  its package/ACP source said 0.24.1; that was not a ready identity. The 0.26.0 receipt
@@ -5558,7 +5561,7 @@ Default-branch capture runs only at daemon startup when a Claude implementer is
5558
5561
 
5559
5562
  Project Git retains the core policy that clears credential.helper and core.askpass; an HTTPS push needing those helpers may fail, rather than importing credentials or relaxing that policy. Task branch/config proof reads are bounded synchronous reads (1.5 seconds per reader); slow or unknown evidence asks. The existing sandbox profile discovery is also synchronous; moving it to an asynchronous inventory proof with a shared deadline remains a follow-up. The nonce is visible in a permission response, so it proves a bounded grant rather than native-dispatch provenance.
5560
5563
 
5561
- The [native permission receipt](verification/2026-10-23-headless-claude-permissions.md) covers Claude Code 2.1.309, and the [2.1.310 receipt](verification/2026-10-26-claude-implementer-2.1.310.md) repeats it on 2.1.310 (with 2.1.309 as a control), and the [2.1.314 receipt](verification/2026-10-31-claude-implementer-2.1.314.md) repeats it and the host-wrapper procedure on 2.1.314 (with 2.1.310 as a control), and the [2.1.316 receipt](verification/2026-10-31-claude-implementer-2.1.316.md) repeats both on 2.1.316 (with 2.1.314 as a control), and the [2.1.318 receipt](verification/2026-11-05-claude-implementer-2.1.318.md) repeats both on 2.1.318 (with 2.1.316 as a control), each with a deterministic loopback fixture and no real account/model call. It is not sandbox proof or a runtime receipt gate. The real account/model/person interaction remains a separate live leg.
5564
+ The [native permission receipt](verification/2026-10-23-headless-claude-permissions.md) covers Claude Code 2.1.309, and the [2.1.310 receipt](verification/2026-10-26-claude-implementer-2.1.310.md) repeats it on 2.1.310 (with 2.1.309 as a control), and the [2.1.314 receipt](verification/2026-10-31-claude-implementer-2.1.314.md) repeats it and the host-wrapper procedure on 2.1.314 (with 2.1.310 as a control), and the [2.1.316 receipt](verification/2026-10-31-claude-implementer-2.1.316.md) repeats both on 2.1.316 (with 2.1.314 as a control), and the [2.1.318 receipt](verification/2026-11-05-claude-implementer-2.1.318.md) repeats both on 2.1.318 (with 2.1.316 as a control), and the [2.1.319 receipt](verification/2026-11-06-claude-implementer-2.1.319.md) repeats both on 2.1.319 (with 2.1.318 as a control), each with a deterministic loopback fixture and no real account/model call. It is not sandbox proof or a runtime receipt gate. The real account/model/person interaction remains a separate live leg.
5562
5565
 
5563
5566
  A headless Claude reviewer is run by the hub instead (task 223): declare
5564
5567
  `"claude-review": { "kind": "claude", "roles": ["reviewer"], "start_mode": "headless" }`
@@ -5596,9 +5599,9 @@ A reviewer has a review scope (#852): `full` (reads the code, runs the affected
5596
5599
 
5597
5600
  Start them with `ahub claude --as claude-review`, `ahub codex --as codex-review` and `ahub kimi --as kimi-review`; stop with `ahub stop <id>`. For the Claude and Codex reviewers the command asks the running hub to start the reviewer and returns: nothing runs in that terminal, it takes no launch arguments, and `--print-command` or `--dry-run` prints a hub-start note instead of a launch (#720). Fresh Claude and Codex variants share the project checkout; the Kimi variant runs in a clean temporary working directory and reviews only the screened brief and host facts. All fresh variants refuse a custom worktree or permission mode. Codex and Kimi require `review_mode: "fresh"`; without it, an existing headless instance with the reviewer role keeps its native app-server/ACP behavior, worktree and permission options and does not join this pool. Claude retains its task 223 automatic headless-reviewer declaration. The agy reviewer slot remains automatically unavailable (`agy is an implementer peer (#485)`). A failed or unsupported fresh start never downgrades to a native continuing session. Ordinary implementer instances retain their own adapters. The default logical pool order is Claude, Codex, Kimi. Only configured kinds with at least one declared reviewer count as slots, including declared ones that are offline, paused, quota-limited or failing, so availability never renumbers them; configured kinds with no declaration are listed after the walk as `no declared reviewer`. `review.rerotate` defaults to false. Pool selection starts at PR number modulo the number of declared kind slots, or task id when there is no PR, then skips the implementer's family and unavailable candidates. Delta review prefers the preceding eligible independent family in a fresh child. A preceding same-family fallback does not outrank a newly available independent family. `ahub route explain` shows the same pure walk.
5598
5601
 
5599
- Codex requires a verified `codex-cli` (0.146.0, 0.163.0, 0.164.0 or 0.166.0) or one the person trusts on this machine, and a passing bounded runtime receipt before its model child starts. 0.146.0 and 0.163.0 passed the [2026-10-22 model-free production admission](verification/2026-10-22-codex-reviewer-isolation.md) and 0.164.0 the [2026-10-24 one](verification/2026-10-24-codex-0164-reviewer-isolation.md); 0.166.0 passed the [2026-10-31 model-free procedure](verification/2026-10-31-codex-0166-reviewer-isolation.md). Its [first authorized model review](verification/2026-10-31-codex-0166-reviewer-tool-call.md) missed a marker hidden by the fixture's accepted plan, so that admission was reverted. After a committed model-free envelope regression and a fixture correction, the separately authorized [2026-11-02 single model review](verification/2026-11-02-codex-0166-reviewer-tool-call.md) persisted one approved verdict with the required marker and exact head; 0.166.0 is now verified. A refusal names the installed and verified versions. Either set `codex_bin` to a verified executable, or run `ahub agents trust codex-review <version>`: trust lifts only the version pin, and every proof below still runs before each child (#691). Each launch approves exactly `hub_review` and `hub_task_show` per tool (`approval_mode = "approve"`), never through a server-wide default: without it Codex 0.164.0 listed the tools but refused the call, so reviews ended with no verdict (#783). A model-free receipt proves the inventory, not that a verdict reaches the hub; a [model-backed 0.164.0 run](verification/2026-10-25-codex-0164-reviewer-tool-call.md) recorded one verdict through that path. The producer checks native binary/config stability, configured MCP inventory with only the two hub tools, effective Apps/plugins/hooks disablement, an explicit empty legacy `notify` command and a named filesystem profile. Apps needs separate feature readback because configured inventory omits runtime connectors. Web search is requested disabled; its effective turn mode is not read back and managed requirements can select Cached (see the verification ceiling). Each launch proves public-read, exact/glob/symlink private-denial, standard host credential denial and write-denial in temporary fixtures. Standard credential and configured tool-home/XDG subtrees are denied independently of project `local.deny`. Its sandboxed shell is filesystem read-only with private paths denied and network configured disabled; it is not Claude's Read/Grep/Glob-only tool whitelist. No credential home is copied.
5602
+ Codex requires a verified `codex-cli` (0.146.0, 0.163.0, 0.164.0 or 0.166.0) or one the person trusts on this machine, and a passing bounded runtime receipt before its model child starts. 0.146.0 and 0.163.0 passed the [2026-10-22 model-free production admission](verification/2026-10-22-codex-reviewer-isolation.md) and 0.164.0 the [2026-10-24 one](verification/2026-10-24-codex-0164-reviewer-isolation.md); 0.166.0 passed the [2026-10-31 model-free procedure](verification/2026-10-31-codex-0166-reviewer-isolation.md). Its [first authorized model review](verification/2026-10-31-codex-0166-reviewer-tool-call.md) missed a marker hidden by the fixture's accepted plan, so that admission was reverted. After a committed model-free envelope regression and a fixture correction, the separately authorized [2026-11-02 single model review](verification/2026-11-02-codex-0166-reviewer-tool-call.md) persisted one approved verdict with the required marker and exact head; 0.166.0 is now verified. 0.167.0 passed the [2026-11-06 model-free procedure](verification/2026-11-06-codex-0167-reviewer-isolation.md) with 0.166.0 as control. The separately authorized [single model-backed attempt](verification/2026-11-06-codex-0167-reviewer-tool-call.md) failed a harness readiness/readback check after startup and marker preconditions; a complete persisted verdict/head/marker result was not recorded, so the model/tool outcome is unknown and 0.167.0 remains unverified. No retry was made. It joins the verified set only after a separately authorized model-backed tool-call run succeeds; until then it is refused unless the person runs `ahub agents trust codex-review 0.167.0`, and every runtime proof still runs. A refusal names the installed and verified versions. Either set `codex_bin` to a verified executable, or run `ahub agents trust codex-review <version>`: trust lifts only the version pin, and every proof below still runs before each child (#691). Each launch approves exactly `hub_review` and `hub_task_show` per tool (`approval_mode = "approve"`), never through a server-wide default: without it Codex 0.164.0 listed the tools but refused the call, so reviews ended with no verdict (#783). A model-free receipt proves the inventory, not that a verdict reaches the hub; a [model-backed 0.164.0 run](verification/2026-10-25-codex-0164-reviewer-tool-call.md) recorded one verdict through that path. The producer checks native binary/config stability, configured MCP inventory with only the two hub tools, effective Apps/plugins/hooks disablement, an explicit empty legacy `notify` command and a named filesystem profile. Apps needs separate feature readback because configured inventory omits runtime connectors. Web search is requested disabled; its effective turn mode is not read back and managed requirements can select Cached (see the verification ceiling). Each launch proves public-read, exact/glob/symlink private-denial, standard host credential denial and write-denial in temporary fixtures. Standard credential and configured tool-home/XDG subtrees are denied independently of project `local.deny`. Its sandboxed shell is filesystem read-only with private paths denied and network configured disabled; it is not Claude's Read/Grep/Glob-only tool whitelist. No credential home is copied.
5600
5603
 
5601
- Kimi requires a compat-admitted Kimi Code on the hub's PATH (receipt-verified 2.2.0, 2.3.0, 2.3.1, 2.3.2 and 2.4.1), signed in through its managed OAuth provider, and a passing runtime preparation before each child; an unverified/untrusted version or a failed preparation is unavailable with its reason. The [2.3.0](verification/2026-10-22-kimi-qwen-compat.md), [2.3.1](verification/2026-10-25-kimi-231-reviewer-compat.md), [2.3.2](verification/2026-10-26-kimi-232-reviewer-compat.md) and [2.4.1](verification/2026-10-31-kimi-241-reviewer-compat.md) receipts are model-free and do not verify real login/provider readiness. Each review runs a new `kimi -p` child without Seatbelt, in a private `KIMI_CODE_HOME` with managed-provider-only config, a clean temporary working directory and an empty skills directory. Its agent may call only `hub_review` and `hub_task_show`, through a task-bound loopback MCP session that never carries the hub's control token, and has no native read, file or shell tool: it reviews the screened brief and host facts only. Its `credentials/`, `oauth/` and `device_id` link to the person's native Kimi files, so it shares the native login, refresh lock and the Kimi account's budget; no token is copied. A stop revokes its verdict authority first, then waits briefly while an OAuth refresh holds the lock; a forced stop mid-refresh may require a native re-login. The Kimi backend records no measured token counts here, so its usage stays unknown; the 2.3.0 receipt makes no usage claim. This is a native tool-authority boundary, not filesystem or network isolation.
5604
+ Kimi requires a compat-admitted Kimi Code on the hub's PATH (receipt-verified 2.2.0, 2.3.0, 2.3.1, 2.3.2, 2.4.1 and 2.5.1), signed in through its managed OAuth provider, and a passing runtime preparation before each child; an unverified/untrusted version or a failed preparation is unavailable with its reason. The [2.3.0](verification/2026-10-22-kimi-qwen-compat.md), [2.3.1](verification/2026-10-25-kimi-231-reviewer-compat.md), [2.3.2](verification/2026-10-26-kimi-232-reviewer-compat.md), [2.4.1](verification/2026-10-31-kimi-241-reviewer-compat.md) and [2.5.1](verification/2026-11-06-kimi-251-reviewer-compat.md) receipts are model-free and do not verify real login/provider readiness. Each review runs a new `kimi -p` child without Seatbelt, in a private `KIMI_CODE_HOME` with managed-provider-only config, a clean temporary working directory and an empty skills directory. Its agent may call only `hub_review` and `hub_task_show`, through a task-bound loopback MCP session that never carries the hub's control token, and has no native read, file or shell tool: it reviews the screened brief and host facts only. Its `credentials/`, `oauth/` and `device_id` link to the person's native Kimi files, so it shares the native login, refresh lock and the Kimi account's budget; no token is copied. A stop revokes its verdict authority first, then waits briefly while an OAuth refresh holds the lock; a forced stop mid-refresh may require a native re-login. The Kimi backend records no measured token counts here, so its usage stays unknown; the 2.3.0 receipt makes no usage claim. This is a native tool-authority boundary, not filesystem or network isolation.
5602
5605
 
5603
5606
  A dangling or unreadable standard/configured credential root makes the Codex reviewer unavailable with only its path class in the reason (for example `~/.docker` or `$DOCKER_CONFIG`, never an expanded path or contents); repair the root and start the reviewer again.
5604
5607
 
@@ -5696,7 +5699,7 @@ Native launcher connections retry transport timeouts/unclean closes with bounded
5696
5699
 
5697
5700
  ## amem runtime (agent-mem#13 P4)
5698
5701
 
5699
- The hub exact-pins @staix/agent-mem 0.21.0 for recall, curated evidence and local deterministic capture. No runtime call reaches a claude-mem worker; `memory.worker_url` is ignored. The person's `ahub memory import claude-mem` remains explicit and off by default. Existing profile, alias, PII and private-turn fences still apply. `ask --remember` and context checkpoints propose machine-local candidates, never automatic curated evidence. See [memory integration](memory.md#in-process-recall-and-capture-agent-mem13-p4) for changed behavior and bounded-view ceilings.
5702
+ The hub exact-pins @staix/agent-mem 0.22.1 for recall, curated evidence and local deterministic capture. No runtime call reaches a claude-mem worker; `memory.worker_url` is ignored. The person's `ahub memory import claude-mem` remains explicit and off by default. Existing profile, alias, PII and private-turn fences still apply. `ask --remember` and context checkpoints propose machine-local candidates, never automatic curated evidence. See [memory integration](memory.md#in-process-recall-and-capture-agent-mem13-p4) for changed behavior and bounded-view ceilings.
5700
5703
 
5701
5704
  ## Person-run backlog legs (#1176)
5702
5705
 
@@ -5992,7 +5995,7 @@ With a legacy broker, status says `liveness not tracked (broker without ephemera
5992
5995
  Upgrade the broker to enable periodic refresh and aging. Legacy connections keep
5993
5996
  identical-snapshot dedupe and ordinary state-change publication, with no
5994
5997
  periodic refresh or freshness expiry. Older clients may ignore the new advisory
5995
- status fields. Full capability advertisement remains #1204 T4.
5998
+ status fields. Codec negotiation is described under Room health diagnostics below.
5996
5999
 
5997
6000
  A graceful room stop immediately fences new publications and attempts one signed
5998
6001
  offline snapshot behind an already attempted FIFO frame, bounded to two seconds
@@ -6331,12 +6334,42 @@ Corrupt or unreadable provenance stays unknown and held. The status next step di
6331
6334
 
6332
6335
  A ready memory profile does not prove a successful sync. Read the separate automatic-sync result and timestamp in `ahub status` or Memory. It resets to not run after daemon restart; it is not a machine-global record of manual CLI attempts. Missing remote configuration is the neutral `not-configured` state; an interrupted/stopped attempt is neutral `stopped`. Both keep their safe next step and produce no failure log under `quietSyncError`.
6333
6336
 
6334
- For policy-declined rows, a person runs `ahub memory declined --json` to inspect IDs and safe rule categories, never note text. The pinned agent-mem 0.21.0 public `inspectSyncPolicy` API bounds physical outbound inspection for shared-v1 and generation profiles. A complete result supplies the declined IDs and rules; `complete:false` means the scan is unavailable, stale or over its diagnostic bound, not zero declined rows. The command stays read-only and rechecks its profile binding. No migration or policy edit is performed automatically.
6337
+ For policy-declined rows, a person runs `ahub memory declined --json` to inspect IDs and safe rule categories, never note text. The pinned agent-mem 0.22.1 public `inspectSyncPolicy` API bounds physical outbound inspection for shared-v1 and generation profiles. A complete result supplies the declined IDs and rules; `complete:false` means the scan is unavailable, stale or over its diagnostic bound, not zero declined rows. The command stays read-only and rechecks its profile binding. No migration or policy edit is performed automatically.
6335
6338
 
6336
- The hub projects verified withheld/exported counts when a trusted SDK sync returns a successful placement result. That projection is covered by an injected-result fixture, not an activated-store sync. Agent-mem 0.21.0 requires a fresh `placementAttestation` even for an already active v3 store; the default hub supplies no such integration and therefore cannot perform that sync yet. No attestation is fabricated. A nonzero withheld count in a successful result is not a transport failure and does not mean those rows were deleted, rewritten or published. Inspect the IDs and rules before deliberately changing any source or approved policy; a forget operation does not remove its original text from physical history.
6339
+ The hub projects verified withheld/exported counts when a trusted SDK sync returns a successful placement result. That projection is covered by an injected-result fixture, not an activated-store sync. Agent-mem 0.22.1 requires a fresh `placementAttestation` even for an already active v3 store; the default hub supplies no such integration and therefore cannot perform that sync yet. Activation alone does not enable the hub's automatic sync, and no attestation is fabricated. A nonzero withheld count in a successful result is not a transport failure and does not mean those rows were deleted, rewritten or published. Inspect the IDs and rules before deliberately changing any source or approved policy; a forget operation does not remove its original text from physical history.
6337
6340
 
6338
- A legacy store without active per-row placement still blocks a sync containing declined rows. Status says: `machine sync blocked: N declined rows; per-row placement is not active on this store (agent-mem has no activation command yet, agent-mem#281). Inspect with ahub memory declined.` Here `N` is the known declined count. Agent-mem 0.21.0 has no activation command, so there is no migration or activation step to run in this release. The hub does not replace the core placement protocol or fabricate its activation proof. [Agent-mem#281](https://github.com/STAIxBWLB/agent-mem/issues/281) owns the missing supported activation path.
6341
+ A legacy store without active per-row placement still blocks a sync containing declined rows. Status names inactive placement and the person-only `amem migrate --sync-placement --dry-run` preview, which requires every local writer installation through repeatable `--writer-root` flags. It also names the missing host `placementAttestation` and keeps `ahub memory declined` as the safe inspection step. The native CLI supports activation from 0.22.0; the pinned core is 0.22.1. See the [activation preview and prerequisites](memory.md#automatic-sync-health-1173) before any separately authorized apply. Preview writes nothing, and activation does not migrate layouts, change policy or automatically raise a format floor. The hub does not invoke it or fabricate its proof.
6339
6342
 
6340
- The bounded diagnostic addresses #1173 AC4; AC5 has result projection only; supported activation and fresh host-attestation integration remain necessary for default-host v3 sync. #1173 remains open until #281 ships and its supported path is adopted here.
6343
+ The bounded diagnostic addresses #1173 AC4; AC5 has result projection only. The core activation command is available, while legitimate fresh host-attestation integration remains necessary for default-host v3 sync. #1173 remains open for that integration.
6341
6344
 
6342
6345
  For a transport or unknown failure, run `ahub memory sync` as a person to see the local diagnostic. Logs keep only the cause class and known declined count, once per unchanged failure episode. Complete declined-ID sets can distinguish a changed failure without placing IDs or bodies in the log; incomplete inspection keeps the set unknown. Existing write-time screening and profile/privacy fences remain. SDK adoption and isolated fixtures do not prove live rollout or a successful sync of the person's memory home.
6346
+
6347
+ ### Room health diagnostics (#1204 T4)
6348
+
6349
+ `ahub room status [name]` prints retained refused-frame counts by reason, room
6350
+ outbox depth, oldest age, last signed receipt age and the link cause with a next
6351
+ step. `--json` contains the same allowlisted metadata. Unknown age is not zero;
6352
+ legacy generic outbox rows have no creation timestamp. Refusal counts cover only
6353
+ retained diagnostics, not lifetime failures. No message body, key, broker URL or
6354
+ raw exception appears in these projections.
6355
+
6356
+ `ahub status` names `rooms: unavailable (<code>)` if room storage cannot open.
6357
+ Open retries back off from 1 s to at most 30 s and stop on shutdown. For
6358
+ `clock_rollback`, correct the system clock to at least the last recorded room
6359
+ time; do not edit stored replay or clock records. A receive-only hub retries
6360
+ blocked admission when a successful journal checkpoint clears its storage error.
6361
+ Status reads and idle ticks do not poll blocked plaintext.
6362
+
6363
+ Codec negotiation keeps `x-agent-hub-ephemeral: 1` and adds
6364
+ `x-agent-hub-codecs: 1` on the same WebSocket upgrade. A released broker ignores
6365
+ the latter and retains its ephemeral/liveness behavior. A peer with a pending
6366
+ codec observation waits under the original queue expiry; it does not receive a
6367
+ false upgrade refusal. Known legacy or unsupported peers name the upgrade step.
6368
+ Ordinary presence refreshes preserve same-connection signed codec evidence.
6369
+ During a rolling upgrade, person-inbox (`user@label`) and invocation sends to a
6370
+ released 0.31/0.32 member, or between upgraded hubs on a released broker, are
6371
+ refused before any effect with an upgrade step; plain chat keeps working.
6372
+ Upgrade the broker, then every room member to a codec-capable release, then reconnect.
6373
+ `ahub status` distinguishes local room storage opening from a failed broker
6374
+ connection; direct `ahub room status` failures expose only closed cause/action
6375
+ metadata. A healthy online link needs no broker repair advice.
@@ -32,6 +32,16 @@ terminal in that project: it reviews the plan with you, applies it and follows
32
32
  it; other projects keep their version. It then names the `bun add -g` and
33
33
  `ahub setup` step when your global CLI or plugin is older than the new daemon.
34
34
 
35
+ ## Upgrading to 0.33.0
36
+
37
+ Rooms now show refused-frame counts, outbox depth/ages and a closed link cause with a recovery step. Store-open failures retry, receive-only work wakes after journal recovery, and selective traffic no longer produces false sequence-gap notices. For a rolling room upgrade, update the broker first, then every member, then reconnect: 0.33.0 person-inbox (`user@label`) and invocation sends to a released 0.32.0 member, or through a released 0.32.0 broker are refused before effects with the upgrade step; plain chat keeps working. Use the matching CLI for the new diagnostics: 0.32.0 `ahub room status` drops the new fields, including in its JSON output, while `ahub status --json` passes raw daemon fields through.
38
+
39
+ Orca recovery now recognizes its gone-terminal codes. The compat policy adds exactly Claude headless implementer 2.1.319, Kimi reviewer 2.5.1 and Qwen ACP 0.26.8 based on their model-free receipts. Codex reviewer 0.167.0 remains unverified after an unknown tool-call outcome, and Qwen dual-output remains at 0.26.1. These entries do not install agent CLIs or prove real-account/model behavior. N-1 is published 0.32.0 and control remains 16 through 17.
40
+
41
+ This hub pins agent-mem 0.22.1 while 0.32.0 pins 0.21.0. Placement is opt-in; inactive homes behave as before, and the common formats and `INDEX_VERSION` are unchanged. The person-only activation preview is available, but activation alone does not enable this hub's automatic v3 sync: fresh host `placementAttestation` integration remains #1173. Shared-home activation and writer renewal are separate person operations; upgrading the hub performs neither. See [memory integration](memory.md#automatic-sync-health-1173).
42
+
43
+ `ahub upgrade` does not update the global CLI or the shared Claude plugin: run `bun add -g @staix/agent-hub@0.33.0` and then `ahub setup` yourself, and `ahub doctor` warns while either is older than a running daemon.
44
+
35
45
  ## Upgrading to 0.32.0
36
46
 
37
47
  Rooms on an ephemeral-capable broker now refresh signed presence every 30 seconds; three missed periods display advisory unknown without changing sending authority. A graceful stop attempts a signed offline snapshot within two seconds. Epoch-changing room commands list sealed outstanding delivery IDs before confirmation and immediately hold old-epoch work with the named cause. Upgrade the global CLI and plugin with the step below to see the new previews and advisory status: a 0.31.0 CLI ignores those additive fields, even in JSON. A broker without ephemeral support keeps state-change publication and reports liveness untracked, with no periodic aging. Protocol 16 through 17 and room v1 shapes remain; the N-1 baseline is published 0.31.0, with the same agent-mem 0.21.0 pin.
@@ -194,7 +204,7 @@ The restarted Claude planner gets the release-train tools (`hub_release_new`, `h
194
204
 
195
205
  Jcode must be 0.98.0 or later, below 1.0.0; 0.94.0 is no longer accepted, so `ahub doctor` fails its Jcode row for an older install and the peer does not start (#529). Every owned jcode process runs with `JCODE_NO_TELEMETRY=1`.
196
206
 
197
- Since 0.12.37 the hub opens a split memory home through its shards (#534); the current exact `@staix/agent-mem` pin is 0.21.0. Before anyone runs `amem migrate --shards` on a memory home, every hub using that home must run 0.12.37 or later: an older hub does not see the split and keeps writing the old layout. `ahub memory profile-check` is split-aware and compares each hub with its own project's shard (#536). See [memory profiles and rollout](memory.md#selected-memory-profile).
207
+ Since 0.12.37 the hub opens a split memory home through its shards (#534); the current exact `@staix/agent-mem` pin is 0.22.1. Before anyone runs `amem migrate --shards` on a memory home, every hub using that home must run 0.12.37 or later: an older hub does not see the split and keeps writing the old layout. `ahub memory profile-check` is split-aware and compares each hub with its own project's shard (#536). See [memory profiles and rollout](memory.md#selected-memory-profile).
198
208
 
199
209
  From 0.12.30 or earlier, existing Jcode project MCP entries need one refresh before conductor or dashboard starts. Once per project, the person runs:
200
210
 
@@ -272,7 +282,7 @@ More: `ahub help`. How it is built and why: [`docs/specs/2026-09-19-agent-hub-de
272
282
 
273
283
  ## Shared memory
274
284
 
275
- The hub exact-pins the first-party `@staix/agent-mem` 0.21.0 core, including deterministic capture; no claude-mem worker is needed. Existing shared-v1 memory remains the default; upgrading does not migrate it. Managed agents use screened `hub_memory_search`, `hub_memory_show` and `hub_memory_graph` tools, or propose a correction with `hub_memory_correct`; only a person accepts candidates through the supported `amem review` path. Since agent-mem 0.7.0, `amem review` also accepts candidates on a selected generation.
285
+ The hub exact-pins the first-party `@staix/agent-mem` 0.22.1 core, including deterministic capture; no claude-mem worker is needed. Existing shared-v1 memory remains the default; upgrading does not migrate it. Managed agents use screened `hub_memory_search`, `hub_memory_show` and `hub_memory_graph` tools, or propose a correction with `hub_memory_correct`; only a person accepts candidates through the supported `amem review` path. Since agent-mem 0.7.0, `amem review` also accepts candidates on a selected generation.
276
286
 
277
287
  Before any real generation migration, upgrade every hub sharing that memory home to 0.12.30 or later and check its authenticated binding with `ahub memory profile-check` in each custom registry. Ready bindings prove compatibility, not an atomic live cutover: quiesce consumers and close their handles before migrating, then reopen through the supported session-preserving lifecycle. Invalid or changed profiles disable native memory without falling back to legacy writes; the bus and board continue. See [memory operations](operations.md#hub-memory) for the remaining rollout gates.
278
288
 
package/docs/security.md CHANGED
@@ -26,7 +26,7 @@ agent-hub connects agents that can each run commands. This page says what the hu
26
26
 
27
27
  ## Native memory authority and profile selection
28
28
 
29
- The portable core is the exact-pinned first-party `@staix/agent-mem` 0.21.0 package; it does not replace the hub's caller identity, PII policy or task-write authority. Deny, hardened git, real paths and process identity are single-sourced in its Node-safe platform entry. Current project privacy is applied by the hub before promotion and again before model-facing reads. Standalone person reads are unscreened, and the standalone `--policy-free` acknowledgement grants no hub or peer authority.
29
+ The portable core is the exact-pinned first-party `@staix/agent-mem` 0.22.1 package; it does not replace the hub's caller identity, PII policy or task-write authority. Deny, hardened git, real paths and process identity are single-sourced in its Node-safe platform entry. Current project privacy is applied by the hub before promotion and again before model-facing reads. Standalone person reads are unscreened, and the standalone `--policy-free` acknowledgement grants no hub or peer authority.
30
30
 
31
31
  `hub_memory_search`, `hub_memory_show` and `hub_memory_graph` take the project from the daemon, require `memory_read`, refuse private turns and validate UTF-8 input before logs or storage work. Complete records and graph metadata are screened before counts and truncation. Search is at most 20 lines/4 KiB (default 8); show accepts at most 8 ids and returns at most 8 KiB; graph is at most 120 nodes/240 edges/6 KiB (default 60 nodes), with no edge lacking an endpoint. Unknown, ambiguous and withheld ids share one neutral refusal. Arguments and results are excluded from hub-managed capture; this does not govern a vendor's independent transcript or memory hooks.
32
32
 
@@ -729,7 +729,7 @@ withholds the scoped mode on these writes so an older hook grants nothing too.
729
729
 
730
730
  Agent CLI versions (#691). One policy gates the Codex and Kimi fresh reviewers, the headless Claude implementer, Jcode, agy, Qwen (ACP and the dual-output TUI) and Pi (#843): a receipt-verified version passes, Jcode and agy also start an untested version inside their compatible line with a note, and any other version is refused unless the person trusts that exact version on this machine with `ahub agents trust <id> <version>`. The record is `agent-compat.json` in the hub home (`~/.agenthub`), written atomically with mode 600 and at most 64 entries; an unreadable, linked, oversized or invalid record trusts nothing. Agent shells and `--live-test` may read `ahub agents` but cannot trust or revoke. Trust lifts only the version pin: the fresh reviewers' runtime proofs still run before every child, and an untested version's native contract stays unverified.
731
731
 
732
- Qwen Code's optional production ACP peer requires the qwen-code native identity, a compat-admitted version (receipt-verified 0.25.0, 0.26.0, 0.26.1, 0.26.4 and 0.26.5)
732
+ Qwen Code's optional production ACP peer requires the qwen-code native identity, a compat-admitted version (receipt-verified 0.25.0, 0.26.0, 0.26.1, 0.26.4, 0.26.5 and 0.26.8)
733
733
  and advertised mode ids before setting a policy or starting work. Its own tools
734
734
  have no hub sandbox; auto-edit approves file edits, yolo every tool. Configured
735
735
  never-ask still requires the person's confirmation. qwen_cmd is machine-local and
@@ -824,8 +824,10 @@ result. Failure logs retain only the closed cause and known declined count.
824
824
  and uses bounded physical-row inspection to show IDs and rule categories, never
825
825
  note text or literal patterns; incomplete inspection is not a zero count.
826
826
  Default-host v3 sync remains unsupported because the hub supplies no fresh
827
- placement attestation. No activation proof is fabricated; the supported activation
828
- and attestation path remains agent-mem#281. Suggested graph edges are off by default
827
+ placement attestation. No activation proof is fabricated. The native amem CLI
828
+ provides person-only activation from 0.22.0; the hub does not invoke it, and
829
+ default-host v3 sync still requires legitimate fresh host-attestation integration
830
+ (#1173). Suggested graph edges are off by default
829
831
  and are not evidence until a person confirms them. Operational details and limits: [hub memory](memory.md).
830
832
 
831
833
  ## Floating pet retirement (#1012)
@@ -873,7 +875,7 @@ Task branch authority uses recorded `refs.branch`, otherwise a host-observed non
873
875
 
874
876
  The fresh Codex reviewer (#519) needs `review_mode: "fresh"` and a compat-admitted Codex (receipt-verified 0.146.0, 0.163.0 and 0.164.0; `ahub agents` shows the current policy); an unverified/untrusted version is unavailable. Before each review it requires a model-free isolation receipt: binary and config unchanged, only the two hub tools in the configured MCP inventory (each approved by its own name, never by a server-wide default, #783), plugins, hooks and Apps disabled (Apps by a separate feature readback), and a named filesystem profile whose fixtures prove public reads, private-path denial (exact, glob and symlink), standard host credential denial and write denial. Credential and tool-home roots are denied even with an empty `local.deny`; that list does not cover every personal file. A dangling or unreadable credential root refuses the reviewer, and the reason names only its path class (`~/.docker`, `$DOCKER_CONFIG`), never the path or its contents. A failed per-review start names one class from a closed list (`version`, `binary`, `mcp_inventory`, `plugins_hooks_apps`, `sandbox_proof`, `credential_root`, `timeout`, `unknown`) with a fixed sentence in the unavailable reason, `hub.log` and the `reviewer` line of `ahub status`; it never carries a path, native CLI text or a token (#722). Its shell is sandboxed read-only, not Claude's Read/Grep/Glob whitelist. Network and web search are configured disabled but not observed: managed requirements can still select cached web search, and no run has shown the review selecting the profile through `default_permissions`. A failed receipt or start never falls back to a continuing native session, and a child that ends without a saved verdict is never approval. The agy reviewer slot is an unavailable placeholder and never runs; it binds nothing, so agy's own `hub_task_show` reads are not fenced as a review (#792).
875
877
 
876
- The fresh Kimi reviewer (#533) needs `review_mode: "fresh"` and a compat-admitted Kimi Code (receipt-verified 2.2.0, 2.3.0, 2.3.1, 2.3.2 and 2.4.1; `ahub agents` shows the current policy) with its native OAuth login; an unverified/untrusted version, or a failed preparation, is unavailable. The [2.3.0](verification/2026-10-22-kimi-qwen-compat.md) and [2.3.1](verification/2026-10-25-kimi-231-reviewer-compat.md) receipts are model-free and do not prove real login or a model review. It is a native tool-authority boundary, not a sandbox: no Seatbelt wraps it, and same-user native code is not isolated from the filesystem or network. Each review starts a new child in a private `KIMI_CODE_HOME` with managed-provider-only config, a clean temporary working directory and an empty skills directory. Its agent may use only `hub_review` and `hub_task_show`, served by a loopback MCP session bound to the task, head and review revision that never carries the hub's control token; it has no native read, file or shell tool and sees only the screened review brief and host facts. Its `credentials/` and `oauth/` directories and `device_id` link to the person's native ones, so refresh keeps Kimi's own lock and atomic rename; no token is copied and `KIMI_DISABLE_OAUTH_LOCK` is never set. A stop revokes its verdict authority before termination; killing it mid-refresh may require a native re-login. Private tasks are never given to it, and a child that ends without a saved verdict is never approval.
878
+ The fresh Kimi reviewer (#533) needs `review_mode: "fresh"` and a compat-admitted Kimi Code (receipt-verified 2.2.0, 2.3.0, 2.3.1, 2.3.2, 2.4.1 and 2.5.1; `ahub agents` shows the current policy) with its native OAuth login; an unverified/untrusted version, or a failed preparation, is unavailable. The [2.3.0](verification/2026-10-22-kimi-qwen-compat.md), [2.3.1](verification/2026-10-25-kimi-231-reviewer-compat.md) and [2.5.1](verification/2026-11-06-kimi-251-reviewer-compat.md) receipts are model-free and do not prove real login or a model review. It is a native tool-authority boundary, not a sandbox: no Seatbelt wraps it, and same-user native code is not isolated from the filesystem or network. Each review starts a new child in a private `KIMI_CODE_HOME` with managed-provider-only config, a clean temporary working directory and an empty skills directory. Its agent may use only `hub_review` and `hub_task_show`, served by a loopback MCP session bound to the task, head and review revision that never carries the hub's control token; it has no native read, file or shell tool and sees only the screened review brief and host facts. Its `credentials/` and `oauth/` directories and `device_id` link to the person's native ones, so refresh keeps Kimi's own lock and atomic rename; no token is copied and `KIMI_DISABLE_OAUTH_LOCK` is never set. A stop revokes its verdict authority before termination; killing it mid-refresh may require a native re-login. Private tasks are never given to it, and a child that ends without a saved verdict is never approval.
877
879
 
878
880
  The review brief (#520) withholds private changes whole (both sides of a move) and counts them; a rule file that fails the private-data screen is named, not shown. Attributes and rules are read at the merge base, so a change cannot loosen its own review. Optional changed symbols (#684) come from ripwire 0.6.7 on the daemon's host PATH, run as an owned process on a disposable snapshot of the task's commit; each path, name and kind passes the hub's public metadata screen before the brief, the console's task detail or the dashboard shows it, a private task stores and shows none, and a failed or missing read is `unknown`, never a gate. Spec acceptance, plan review, plan conformance, premature-review, cost, test-integrity (#481 S4), issue and PR identity linking (#694) and dogfood scorecard (#687) reads fetch GitHub metadata only (edit times, check states, thread authorship and resolution, changed file names, open PR heads, workflow run conclusions), never issue bodies, comments or patches. Issue identity linking at propose and accept (#723) parses the task's title and refs locally, reads nothing from GitHub and skips PII tasks. The CI workflow keeps `contents: read` and `actions: read`.
879
881
 
@@ -1207,10 +1209,11 @@ X5b adds the separate durable inbox boundary below.
1207
1209
 
1208
1210
  The console Rooms panel (`8`) and dashboard Agents > Rooms use only the canonical
1209
1211
  room metadata projection: local name/id, epoch, owner/self fingerprints, member
1210
- count, link state and exposed peer ids/states. No body, title, reason, broker URL,
1211
- key material or delivery history enters this projection. Reading it creates no
1212
- room storage or keys; missing rooms stay hidden and unavailable metadata stays
1213
- explicitly unknown.
1212
+ count, link state and exposed peer ids/states, closed link cause and regenerated
1213
+ next step, retained refusal counts, outbox depth and transport ages. No body,
1214
+ title, arbitrary reason/error prose, broker URL, key material or delivery history
1215
+ enters this projection. Reading it creates no room storage or keys; missing rooms
1216
+ stay hidden and unavailable metadata stays explicitly unknown.
1214
1217
 
1215
1218
  Relay counts are daemon-session observations, reset at restart: successful
1216
1219
  outbound handoffs, confirmed inbound admissions and withheld handoffs as a subset
@@ -1320,3 +1323,19 @@ Person comment writes (`review_comment_put`, `review_comment_delete`, `review_co
1320
1323
  - **Material.** Placement material comes only from guarded immutable Git snapshots at the task's recorded head (declared refs, plan paths, or same-head verified PR paths), bounded per operation to eight files and eight seconds; a sent package is at most 12,000 bytes. `review_blob` refuses a PII task, and periodic snapshots make no comment-material Git or GitHub read. PII tasks and private paths keep comments on the board and count-only in every public view.
1321
1324
  - **Delivery.** A sent package carries the host-only `refs.reviewPackage` marker: the intended owner gets the body, while logs, stream projections, incoming labels, memory capture and observers get an ids-only stub; review markers a peer supplies are discarded. Open sent comments, anchored findings and unsettled review deliveries keep the original recipient's responses out of shared memory and observers until resolution, dismissal, task close or explicit disposition (#1192, #1205). The marker grants no task, console or PII authority.
1322
1325
  - **Retry and recovery.** A send is never retried automatically, and a queued receipt proves publication, not that the owner read it. A restart, upgrade or recovery onto a daemon lacking `review_comments` is refused while anchored comments are stored.
1326
+
1327
+ ### Room health and codec advertisements (#1204 T4)
1328
+
1329
+ Room health projects closed cause codes, retained refusal counts and transport
1330
+ ages only. Raw store errors, broker URLs, bodies, titles and key material never
1331
+ enter status. Codec advertisements are signed compatibility evidence scoped to
1332
+ the current local session, source connection token and roster. Missing observation
1333
+ is pending and permits no wire effect; only positively known legacy or unsupported
1334
+ members receive an upgrade refusal. Pending sends retain their original queue
1335
+ expiry and wake on a current member observation. Peer connection metadata is
1336
+ compatibility evidence only, never an authorization source. The existing ephemeral
1337
+ header remains exactly `1`; an extra ignored codec header preserves released
1338
+ broker behavior. A feature-presence variant reaches opted-in sessions only; legacy members retain
1339
+ the unchanged presence payload. Codec support grants no exposure, role, privacy,
1340
+ invocation or native permission. A storage-recovery wake retries deferred
1341
+ admission under its existing guards and never replays uncertain native work.
@@ -1130,8 +1130,20 @@ The optional ephemeral field is used only after an opted-in connection receives
1130
1130
  clients that do not opt in. Missing advertisement means legacy presence frames,
1131
1131
  with dedupe/backoff still active. The broker withholds ephemeral frames from older member hubs
1132
1132
  until upgraded; application chat stays wire-compatible. See the [compatibility
1133
- ceiling](../design/bus.md#room-wire-compatibility-1204-t1); #1204 T4 owns full codec
1134
- feature negotiation.
1133
+ ceiling](../design/bus.md#room-wire-compatibility-1204-t1). Codec-aware presence
1134
+ keeps `x-agent-hub-ephemeral: 1` and adds `x-agent-hub-codecs: 1` on that same
1135
+ WebSocket upgrade. Released brokers ignore the codec header while preserving
1136
+ ephemeral presence and liveness. Only explicitly opted-in clients receive the
1137
+ bounded current-roster peer connection inventory and signed feature snapshots.
1138
+ Feature evidence is tied to the observed source connection token and roster;
1139
+ ordinary presence never revokes a same-connection claim. Legacy members receive
1140
+ the unchanged legacy presence bytes. A missing observation is pending, grants no
1141
+ support, and defers a send under its original queue expiry. Known legacy members
1142
+ or signed feature lists missing the required codec refuse with an upgrade step.
1143
+ Fresh support and known-legacy observations wake only that member's codec waiters,
1144
+ including sends not yet admitted to the room outbox. Requeue rechecks the observation
1145
+ to avoid losing a wake that arrived during an await. These signals grant no exposure,
1146
+ roles, privacy clearance or native authority. Plain v1 chat stays compatible.
1135
1147
 
1136
1148
  ### Durable state and outbound link
1137
1149
 
@@ -1402,11 +1414,26 @@ confirmed local admissions. Withheld counts are a subset of outbound handoffs,
1402
1414
  not an additional total. Missing or unreadable values stay `null`/unknown, never
1403
1415
  zero. These counters do not prove application completion or lifetime traffic.
1404
1416
 
1405
- The projection contains no message body/title, reason, broker URL, key material
1406
- or delivery history. This projection never reads a person inbox body; X5b below
1417
+ Room health additionally exposes retained refused-frame counts by closed reason,
1418
+ current outbox depth, oldest outbox age and last retained signed receipt age, and
1419
+ a closed link cause with a locally generated next step (#1204 T4). Unknown ages
1420
+ remain null, including generic legacy outbox rows without creation time. Counts
1421
+ are bounded retained diagnostics, not lifetime totals or delivery authority.
1422
+ The projection contains no message body/title, arbitrary error reason, broker URL,
1423
+ key material or delivery history. This projection never reads a person inbox body; X5b below
1407
1424
  provides that separate person-only CLI. Native/account and X7 two-machine
1408
1425
  receipts remain separate live verification.
1409
1426
 
1427
+ A failed store open is shown as `rooms: unavailable (<code>)` with a next step,
1428
+ and retried with exponential delay from one second to a thirty-second ceiling.
1429
+ Shutdown cancels the owned retry. Clock rollback is explicitly named; status
1430
+ reads never advance the durable clock. A verified Bus journal recovery write
1431
+ wakes deferred inbound room admission once without unrelated traffic or plaintext
1432
+ polling. This wake preserves recovery, PII, exposure and person-disposition fences.
1433
+ The signed sequence remains room-wide. Recipient-selective traffic makes gaps
1434
+ unobservable at a member, so operator gap notices are removed; monotone replay
1435
+ floors, dedupe and receipt evidence remain unchanged.
1436
+
1410
1437
  ## Encrypted rooms: X5b person inbox (#446)
1411
1438
 
1412
1439
  Authenticated eligible chat to local `user` is admitted to a durable person
@@ -242,9 +242,13 @@ slices, and once the terminal reads idle (an idle terminal may be the shell the
242
242
  launcher returned to), a recorded launcher that is gone means the launch failed,
243
243
  recognized within one slice. A launcher whose identity cannot be read is unknown
244
244
  and is waited for, never taken as gone. A handle Orca reports
245
- `terminal_handle_stale` means the terminal is gone only when no recorded
246
- launcher may still run and Orca no longer lists the terminal's incarnation;
247
- otherwise the create stays uncertain. A launcher that died before recording
245
+ `terminal_handle_stale`, `terminal_exited`, `terminal_gone` or
246
+ `no_connected_pty` (the codes Orca itself groups as gone; 1.4.250 raises
247
+ `terminal_exited` for a wait on a pane whose process ended, #1233) leads to the
248
+ launcher check: the terminal is gone only when no recorded launcher may still
249
+ run and Orca no longer lists the terminal's incarnation; otherwise the create
250
+ stays uncertain. Any other Orca failure is reported with Orca's error code and
251
+ message, and a wait Orca answers as blocked names its `blockedReason`. A launcher that died before recording
248
252
  itself is not distinguished from a slow one, and whether Orca reports the bare
249
253
  login shell as TUI-idle is not verified: if it does, the create stops at once as
250
254
  not mappable to the session; if not, after the 10-minute readiness bound. Either