@staix/agent-hub 0.32.0 → 0.34.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 (58) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +2 -2
  3. package/docs/design/bus.md +68 -2
  4. package/docs/dogfood.md +3 -1
  5. package/docs/memory.md +9 -3
  6. package/docs/operations.md +124 -20
  7. package/docs/quickstart.md +32 -2
  8. package/docs/security.md +28 -9
  9. package/docs/specs/2026-09-19-agent-hub-design.md +36 -6
  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/2026-11-07-0.34.0.md +71 -0
  20. package/docs/verification/2026-11-07-compat-receipt-audit-1248.md +256 -0
  21. package/docs/verification/claude-shell-wrapper-native.py +1 -1
  22. package/docs/verified.json +11 -11
  23. package/package.json +2 -2
  24. package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
  25. package/plugins/agent-hub/server.js +528 -206
  26. package/src/adapters/compat.ts +11 -11
  27. package/src/adapters/definitions/native-cli-claude-setup.ts +14 -5
  28. package/src/broker/protocol.ts +5 -0
  29. package/src/broker/server.ts +54 -4
  30. package/src/broker/store.ts +6 -3
  31. package/src/cli/autonomy-homes.ts +12 -3
  32. package/src/cli/claude-homes.ts +5 -5
  33. package/src/cli/claude-profile-hook.ts +38 -9
  34. package/src/cli/install-paths.ts +71 -0
  35. package/src/cli/main.ts +20 -1
  36. package/src/cli/output.ts +5 -1
  37. package/src/cli/room.ts +17 -5
  38. package/src/cli/runtime-version-warning.ts +8 -6
  39. package/src/cli/setup-homes.ts +13 -10
  40. package/src/cli/status-lines.ts +8 -1
  41. package/src/cli/terminal-recovery.ts +96 -18
  42. package/src/cli/upgrade-interactive.ts +29 -6
  43. package/src/cli/upgrade-output.ts +3 -2
  44. package/src/cli/upgrade-runtime.ts +34 -4
  45. package/src/cli/upgrade.ts +3 -1
  46. package/src/hub/bus.ts +7 -0
  47. package/src/hub/daemon.ts +13 -4
  48. package/src/hub/handoff.ts +1 -1
  49. package/src/rooms/application.ts +15 -0
  50. package/src/rooms/commands.ts +76 -16
  51. package/src/rooms/health.ts +32 -0
  52. package/src/rooms/link.ts +267 -43
  53. package/src/rooms/remote-peer.ts +18 -3
  54. package/src/rooms/service.ts +27 -12
  55. package/src/rooms/status.ts +57 -1
  56. package/src/rooms/store.ts +20 -1
  57. package/src/rooms/wire.ts +10 -8
  58. package/src/ui/index.html +1 -1
@@ -23,6 +23,20 @@ ahub setup
23
23
 
24
24
  From a clone instead: `git clone`, `bun install`, `bun link`.
25
25
 
26
+ ### Installed with dotfiles
27
+
28
+ If the dotfiles CLI manages ahub (`dot ai family install ahub`), `ahub` runs from `~/.local/share/dotfiles/tools/ahub/<version>/`. Keep that the only copy:
29
+
30
+ - To update the global CLI, run `dot ai family install ahub --version <version>`, then `ahub setup`, and restart Claude sessions. Use this wherever an upgrade note says `bun add -g @staix/agent-hub@<version>`, or wherever `ahub upgrade` or `ahub doctor` says to update the global CLI the way it was installed. `dot ai rollback ahub` switches back.
31
+ - Do not also install with `bun add -g`. Check with `readlink -f "$(command -v ahub)"`, and remove a bun copy with `bun remove -g @staix/agent-hub` before running `ahub setup`.
32
+ - Moving from a bun install to dotfiles, `ahub setup` can refuse with `refused marketplace removal ... non-user plugin rows were preserved`. Claude still lists an older project- or local-scope agent-hub row (`claude plugin list --json`; after 0.33.0 the refusal names each row). Hub-launched sessions do not load it.
33
+ - Remove it with `claude plugin uninstall agent-hub@agent-hub --scope project`, run from that row's project directory.
34
+ - If the row's project path is your home directory, do not: there the project settings file is `~/.claude/settings.json`. Instead back up `<claude home>/plugins/installed_plugins.json` and delete only that row from it.
35
+ - Then run `ahub setup` again (#1245).
36
+ - If Claude then reports `PreToolUse ... hook error ... Module not found ... claude-profile-hook.ts`, a hook from the removed copy is left behind.
37
+ - After 0.33.0, `ahub setup` replaces it and `ahub doctor` names the home that needs it.
38
+ - With 0.33.0 or earlier, delete that one entry from `hooks.PreToolUse` in that home's `settings.json`; `ahub setup` has already installed the current one (#1245).
39
+
26
40
  `ahub doctor` tells you what is installed, running and configured. Rows you do not need can stay red: the hub works with any subset of the peers.
27
41
 
28
42
  For managed launchers, two-agent task/review work, approvals, graceful shutdown,
@@ -32,6 +46,22 @@ terminal in that project: it reviews the plan with you, applies it and follows
32
46
  it; other projects keep their version. It then names the `bun add -g` and
33
47
  `ahub setup` step when your global CLI or plugin is older than the new daemon.
34
48
 
49
+ ## Upgrading to 0.34.0
50
+
51
+ After an Orca restart, `ahub upgrade` no longer stops at panes that are orphaned but still connected: the plan screen offers `[t]` to reattach exactly the panes it verified (each Orca call bounded by 5 s), and the blocker names the refresh key. `ahub setup` now writes the stable install path of a symlinked CLI (for example a dotfiles-managed `~/.local/bin/ahub`) into the marketplace and the Claude profile hook instead of a versioned one, replaces a stale managed hook in place, and a refused marketplace replacement names every blocking row and the next step; `ahub doctor` checks the profile hook of each Claude home it can see. If you installed with dotfiles, follow [Installed with dotfiles](#installed-with-dotfiles) instead of `bun add -g`. Nothing else changes until you use it; N-1 is published 0.33.0 and control remains 16 through 17.
52
+
53
+ `ahub upgrade` does not update the global CLI or the shared Claude plugin: run `bun add -g @staix/agent-hub@0.34.0` and then `ahub setup` yourself, and `ahub doctor` warns while either is older than a running daemon.
54
+
55
+ ## Upgrading to 0.33.0
56
+
57
+ 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.
58
+
59
+ 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.
60
+
61
+ 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).
62
+
63
+ `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.
64
+
35
65
  ## Upgrading to 0.32.0
36
66
 
37
67
  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 +224,7 @@ The restarted Claude planner gets the release-train tools (`hub_release_new`, `h
194
224
 
195
225
  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
226
 
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).
227
+ 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
228
 
199
229
  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
230
 
@@ -272,7 +302,7 @@ More: `ahub help`. How it is built and why: [`docs/specs/2026-09-19-agent-hub-de
272
302
 
273
303
  ## Shared memory
274
304
 
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.
305
+ 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
306
 
277
307
  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
308
 
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
@@ -4847,8 +4874,11 @@ upgrade remedy. Attached native TUIs without a live launcher or independent exac
4847
4874
  Orca session proof are shown as `attached, launcher unrecorded`, with person end
4848
4875
  or native resume guidance, never a fresh headless restart. Plain same-protocol
4849
4876
  Claude keeps its unmanaged reconnect-only path. An orphaned but connected pane
4850
- requires the person to run `orca terminal switch --terminal <handle>` and refresh;
4851
- it does not authorize another restore. Historical rows are retained, including
4877
+ requires `orca terminal switch --terminal <handle>` and a refresh (`[r]` on the
4878
+ plan screen, `[s]` on an open operation); the interactive `ahub upgrade` plan screen
4879
+ offers one confirmed key (`[t]`) that switches exactly the panes the plan verified
4880
+ and polls each for at most 5 s (#1246), and nothing else is mutated. It does not
4881
+ authorize another restore. Historical rows are retained, including
4852
4882
  invalid rows; current ownership is scoped to project, instance and peer, and a
4853
4883
  publication replaces only that scope's valid row. This current-source guarantee
4854
4884
  does not fence older binaries that directly rewrite the shared ledger.
@@ -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
@@ -0,0 +1,222 @@
1
+ # 0.33.0 release verification
2
+
3
+ This record covers release preparation and source review. It claims no installation, no running-hub upgrade to 0.33.0 and no live TUI launch.
4
+
5
+ ## Candidate
6
+
7
+ Version 0.33.0 was originally prepared from main `567b55be` (eight component commits since v0.32.0, one `feat`; bump rule: minor). Following the person's 2026-11-07 scope ruling, the release branch normally merged main `203d7a6da6b12bb38a0fd4743f736b9aa3d6a66d`, adding #1243 and #1244 for ten component PRs. The current candidate pins agent-mem 0.22.1 and includes the corrected activation copy. Earlier approval at `94f0a896` predates this rework and is not approval of the new candidate.
8
+
9
+ ## Reviews
10
+
11
+ Component pull requests since v0.32.0: #1234, #1235, #1236, #1237, #1238, #1239, #1241, #1240, #1243 and #1244.
12
+
13
+ All ten PRs merged after board approval. Fresh GitHub commit check-runs bind
14
+ the macOS, Ubuntu and seeded-guard aggregates to each final PR head; all three
15
+ aggregates succeeded. Skipped ancillary jobs are not test proof.
16
+
17
+ | PR / task | Approved and final PR head | Merge commit | Hosted CI |
18
+ | --- | --- | --- | --- |
19
+ | [#1234](https://github.com/STAIxBWLB/agent-hub/pull/1234), task 747 | `65ab9bf7256f00ba6faf14da606c513e89899898` | `25878b3e66c80718f8512e0cfe5c05e4772853ec` | [19 success, 2 skipped](https://github.com/STAIxBWLB/agent-hub/actions/runs/42183963274) |
20
+ | [#1235](https://github.com/STAIxBWLB/agent-hub/pull/1235), task 746 | `ca628faed478a0cce9a499ba8af562729871ab6b` | `1b99c2d264949d5f94b3c9ea08e5922002fc7159` | [19 success, 2 skipped](https://github.com/STAIxBWLB/agent-hub/actions/runs/42183799294) |
21
+ | [#1236](https://github.com/STAIxBWLB/agent-hub/pull/1236), task 750 | `fe70149224154bd7f8f86f72cf7258c9ca5d3979` | `db8828031db6f9c49746187762df1e756f387d9a` | [19 success, 2 skipped](https://github.com/STAIxBWLB/agent-hub/actions/runs/42192573950) |
22
+ | [#1237](https://github.com/STAIxBWLB/agent-hub/pull/1237), task 737 | `31a3e27db28e07d012e8a56b538acbfbf50e1874` | `73a4799662cbe416fc4b8f7c84aa7efc43646885` | [20 success, 2 skipped](https://github.com/STAIxBWLB/agent-hub/actions/runs/42211766399) |
23
+ | [#1238](https://github.com/STAIxBWLB/agent-hub/pull/1238), task 748 | `e70f4edcfebf681b841343907d043c7cf8c39c18` | `d36c27c43237524df8939d36c2109b99cebe3003` | [20 success, 2 skipped](https://github.com/STAIxBWLB/agent-hub/actions/runs/42205240730) |
24
+ | [#1239](https://github.com/STAIxBWLB/agent-hub/pull/1239), task 749 | `ff760ebf15fc0efe31ec4bc5db04733880d85de0` | `824a0b0f273dd47ac1acdfb70981584411464d3b` | [19 success, 2 skipped](https://github.com/STAIxBWLB/agent-hub/actions/runs/42217350346) |
25
+ | [#1240](https://github.com/STAIxBWLB/agent-hub/pull/1240), task 751 | `31e5edd834d8516fa3edbb693f0c21c6cbedd8a1` | `567b55be96e82c5b4662a04657a0e810ac48d6e2` | [19 success, 2 skipped](https://github.com/STAIxBWLB/agent-hub/actions/runs/42221274665) |
26
+ | [#1241](https://github.com/STAIxBWLB/agent-hub/pull/1241), task 753 | `668cd7a189d77bdc7db3285a8e679daa2a4fcd39` | `f193771aea0ba9f4b8e455ff28a58c13b2d9fb4b` | [19 success, 2 skipped](https://github.com/STAIxBWLB/agent-hub/actions/runs/42219293905) |
27
+ | [#1243](https://github.com/STAIxBWLB/agent-hub/pull/1243), task 754 | `e877ca4f6f96c02a564ca1e0ba77e7f7fe57ca62` | `a20d4f389615fb98380d45969665b9f5beaec702` | [19 success, 2 skipped](https://github.com/STAIxBWLB/agent-hub/actions/runs/42251717050) |
28
+ | [#1244](https://github.com/STAIxBWLB/agent-hub/pull/1244), task 755 | `f6971edf8980949eeb1c10f889a6c5f0c35b7e63` | `203d7a6da6b12bb38a0fd4743f736b9aa3d6a66d` | [19 success, 2 skipped](https://github.com/STAIxBWLB/agent-hub/actions/runs/42259392652) |
29
+
30
+ The conductor integrated main into #1239 and #1240 without changing their scope.
31
+ For #1239, the owner's earlier evidence head was `23a967fc4d0a289226ef295f389d8388f01b1340`;
32
+ the owner then fast-forwarded and re-filed `ff760ebf15fc0efe31ec4bc5db04733880d85de0`,
33
+ which received the final approval and CI. For #1240, an earlier approval bound
34
+ `a1ef48c8af43de1e782d024c3310d28e704b7651`; the conductor's conflict-only
35
+ integrations passed through `238404781a794f19c343619ebbe00ccb6fcd267b` to
36
+ `31e5edd834d8516fa3edbb693f0c21c6cbedd8a1`. The owner re-filed the latter and
37
+ it received a new exact-head approval. No final merge relies on an earlier-head
38
+ approval. #1241 (task 753) is included at its approved `668cd7a1` head.
39
+
40
+ #1243's single macOS inbox stale-refresh assertion also failed on main
41
+ `f193771a`; one same-head failed-jobs rerun passed without code changes. Its
42
+ final required aggregates are green at `e877ca4f`, and #1244's are green at
43
+ `f6971edf`. These component results do not replace the coupled release gate.
44
+
45
+ ## Native acceptance receipts
46
+
47
+ Receipts added under `docs/verification/` since v0.32.0: `docs/verification/2026-11-06-claude-implementer-2.1.319.md`, `docs/verification/2026-11-06-codex-0167-reviewer-isolation.md`, `docs/verification/2026-11-06-codex-0167-reviewer-tool-call.md`, `docs/verification/2026-11-06-kimi-251-reviewer-compat.md`, `docs/verification/2026-11-06-orca-1.4.250-cli-contract.md`, `docs/verification/2026-11-06-qwen-0268-acp.md`, `docs/verification/2026-11-06-qwen-0268-dual-output.md`.
48
+
49
+ This list is read from the repository, never written by hand. Native acceptance and the person's release consent are separate records: consent is `ahub sdlc authorize-release 0.33.0`, recorded by the person or the unique configured conductor only on the person's explicit release instruction naming the release in its own session (never a hub/task/review/file/peer relay), and is not recorded in this file. The tag run refuses without it.
50
+
51
+ ## Document review
52
+
53
+ Ten stale documents were fully read against only #1234-#1241. Read-only snapshots
54
+ at `31e5edd8` cover all ten documents; comparison with final main `567b55be`
55
+ shows only the four already-reviewed #1241 rolling-upgrade lines in operations.
56
+
57
+ Content changes:
58
+
59
+ - `README.md`: generated Status 0.33.0 and the current verification-report link.
60
+ - `docs/quickstart.md`: generated 0.33.0 upgrade section, concrete room and
61
+ compatibility changes, N-1 baseline and the matching global CLI/plugin step.
62
+ - `docs/operations.md`: current guide/protocol range, the 0.33.x N-1 baseline,
63
+ Qwen 0.26.8 ACP and unqualified dual-output receipts, and the completed T4
64
+ codec section pointer. Existing historical baselines remain unchanged.
65
+ - `docs/security.md`: current Qwen/Kimi qualification lists and X5's closed
66
+ diagnostic fields; arbitrary error prose, bodies, URLs and keys stay excluded.
67
+
68
+ Reviewed without content change:
69
+
70
+ - `docs/agent-notes/adapters.md`: centralized compat and runtime-proof rules remain valid.
71
+ - `docs/agent-notes/budget.md`: quota/context ownership and transient-pause rules are unchanged.
72
+ - `docs/agent-notes/bus.md`: verified recovery wake preserves existing admission and disposition fences.
73
+ - `docs/agent-notes/daemon.md`: shutdown still waits for rooms before closing shared storage; typed-gone recovery remains guarded.
74
+ - `docs/agent-notes/tasks.md`: task authority, routing, review and CI contracts are unchanged.
75
+ - `docs/agent-notes/tests.md`: existing fixture, seed, timeout and process rules still apply to the retargeted N-1 package.
76
+
77
+ The initial named-document restamp recorded reviewed content commit
78
+ `10efdc8b0ea114ae858fff4ede65de09f6c55604` for these ten documents. Watched paths and fresh
79
+ benchmarks, local-worker, models, help and agent-notes README stamps are unchanged.
80
+ The help command sources have no changes since v0.32.0; T4 changes diagnostics,
81
+ not command forms or flags.
82
+
83
+ ### Rework after #1243 and #1244
84
+
85
+ Only six registered documents became stale: README, security, operations,
86
+ quickstart, daemon note and tests note. Their original full-file reviews were
87
+ reused only for unchanged bytes, with all new dependency/copy deltas and the
88
+ 0.22.x official N-1 contract reviewed. Current-copy corrections are limited to
89
+ the new core pin, available native activation versus missing host attestation,
90
+ and shared-home compatibility; historical release baselines remain intact.
91
+ The daemon/tests notes remain byte-identical and require no instruction change.
92
+
93
+ Those six named documents are restamped at reviewed rework content commit
94
+ `ab8ae6f400d741ee9060d3087489e59996a72086`. Adapters, budget, bus and tasks notes retain their
95
+ initial reviewed stamps; other fresh stamps and all watched paths are unchanged.
96
+ `docs/memory.md` carries #1244's reviewed 0.22.1 activation/attestation text but is
97
+ not registered in the stamp manifest, so no stamp or new watch scope is invented.
98
+
99
+ ## Initial candidate checks (historical)
100
+
101
+ The official generator was dry-run first, then applied from exact main
102
+ `567b55be96e82c5b4662a04657a0e810ac48d6e2` on branch `release/0.33.0` in
103
+ a dgx02 checkout, using frozen root dependencies and pinned Bun 1.4.2. Only the
104
+ existing published v0.32.0 tag was fetched. The separate fixture lock was then
105
+ generated by Bun 1.4.2. Only the planned committed text artifacts returned;
106
+ no dependency tree or other build directory returned.
107
+
108
+ Producer SHA-256:
109
+
110
+ - Bundle: `94532d16e1380743e6a2dd08abe5aeab30d211ad893d56f3ea5d00982dd2234c`.
111
+ - Plugin manifest: `9705bfe5fd9320eefcf8ef1bc6a1bbabdfac85c121a09102ec4e82869904355a`.
112
+ - N-1 lock: `9926687c74cdc12aead17a6ff66cc29e762f4e2dff83bda9cf2309f07769f8c3`.
113
+
114
+ npm confirms 0.32.0 is the latest published 0.32.x patch, with exact agent-mem
115
+ 0.21.0. Its registry integrity matches the fixture lock. Protocol floor 0.25.0
116
+ is unchanged. The new N-1 prose distinguishes old `ahub room status` filtering
117
+ from generic `ahub status --json`, which passes raw daemon fields through.
118
+
119
+ At committed `d1f01f676ce9a940119b050d52467b7d1b5b682c`, dgx02 first passed
120
+ `node scripts/check-docs.mjs --require-fresh --committed`, frozen root and both
121
+ published-fixture installs, then the published protocol/plugin and broker tests:
122
+ 28 pass, 0 fail, 175 assertions across two files in 4.78 seconds. The control/plugin
123
+ legs are bidirectional and retain the existing synthetic native-parent-row
124
+ observation; they are not a real Claude launch or account receipt. The room cases
125
+ load an unchanged published 0.32.0 member against the current broker and current
126
+ links against the published 0.32.0 broker. Their ordinary current-to-old chat,
127
+ legacy presence and ephemeral/liveness observations supplement the unchanged
128
+ v1-codec source comparison; they do not establish live two-machine behavior.
129
+
130
+ The same exact-head run then executed `scripts/check.sh --changed`. Package and
131
+ fixture changes selected the full suite:
132
+
133
+ ```text
134
+ 12073 pass
135
+ 101 skip
136
+ 0 fail
137
+ 312186 expect() calls
138
+ Ran 12174 tests across 938 files. [2048.93s]
139
+ check: no current-invocation agent-hub daemon leaks
140
+ check: OK
141
+ remote_dev: verify dev/agent-hub/.worktrees/release-0.33.0 d1f01f676ce9 exit 0 in 2092s
142
+ ```
143
+
144
+ Typecheck, roles, inventory (3293 entries, 2288 classified, 1005 unchanged baseline
145
+ keys), bundle freshness and package contents passed. Documentation had 0 stale
146
+ documents. Total wall time includes the focused leg and setup above.
147
+
148
+ This following report-only commit records the completed result; it does not
149
+ inherit a new full-suite claim for itself. Final-head documentation/delta checks
150
+ and hosted CI are recorded in the release PR. Exact-head hosted CI remains the
151
+ merge gate, not a claim inherited from this runtime head or a component PR.
152
+
153
+ ## Rework checks
154
+
155
+ After normally integrating main `203d7a6d`, pinned Bun 1.4.2 regenerated the
156
+ 0.33.0 bundle with core 0.22.1 on dgx02. Current bundle SHA-256 is
157
+ `009b624ca203e3c34243b480bf79c5feb9b1e84053709f8523c306bdda0fa620`;
158
+ plugin manifest and N-1 lock hashes remain those above. The fixture still uses
159
+ published 0.32.0/core 0.21.0; protocol floor 0.25.0 is unchanged.
160
+
161
+ At exact committed candidate `ebf139b7288517a34059259676709dbe66558ee5`, dgx02
162
+ passed committed documentation freshness, frozen root/protocol-floor/N-1 installs,
163
+ and the focused published-protocol, broker/member and placement-health files.
164
+ The same run then executed `scripts/check.sh --changed`, which selected the
165
+ full suite with current core 0.22.1 and published N-1 core 0.21.0:
166
+
167
+ ```text
168
+ 12073 pass
169
+ 101 skip
170
+ 0 fail
171
+ 312186 expect() calls
172
+ Ran 12174 tests across 938 files. [2048.37s]
173
+ check: no current-invocation agent-hub daemon leaks
174
+ check: OK
175
+ remote_dev: verify dev/agent-hub/.worktrees/release-0.33.0 ebf139b72885 exit 0 in 2085s
176
+ ```
177
+
178
+ Documentation had 0 stale entries. Typecheck, roles, inventory, bundle freshness
179
+ and package contents passed. This is new coupled evidence, separate from the
180
+ initial candidate and component PRs. The following documentation-only commit
181
+ records these results and clarifies the conditional old-reader sentence and
182
+ table formatting; it does not inherit a new full-suite claim. Final-head
183
+ documentation/delta checks and exact-head hosted CI are recorded in the PR,
184
+ and hosted CI remains the merge gate.
185
+
186
+ ## Shared-home N-1 boundary
187
+
188
+ The current hub pins core 0.22.1; published hub 0.32.0 pins 0.21.0. Core 0.22.x's
189
+ own N-1 statement preserves curated, capture, hook-spool, candidates, work-list
190
+ and setup-receipt formats, `INDEX_VERSION` and the index filename. Shared-v1,
191
+ generation and v1/v2 shard sync are unchanged, and inactive homes behave as before.
192
+ Placement activation and writer renewal are opt-in person commands. If renewal
193
+ history is present, the old 0.21.0 closed journal reader refuses that history
194
+ and placement publication before effects. This is not a promise of compatibility after arbitrary person
195
+ operations. Shared-home coordination remains the person's separate operation
196
+ after release; preparation performs no activation, renewal or floor change.
197
+
198
+ ## Known gaps, not blocking
199
+
200
+ - This preparation makes no installation, running-hub upgrade, native/model call,
201
+ real-account, live TLS/proxy or two-machine acceptance claim. Published-package
202
+ control/plugin and isolated broker/member fixtures are separate evidence.
203
+ - The Claude 2.1.319, Kimi 2.5.1 and Qwen ACP 0.26.8 receipts are model-free.
204
+ Codex 0.167.0's single authorized attempt ended at harness readiness before
205
+ verdict readback: its outcome is unknown, not a proven model failure, no retry
206
+ occurred, and the version stays unverified. Qwen dual-output 0.26.8 is not
207
+ qualified; the verified dual-output version remains 0.26.1.
208
+ - Mixed room upgrades keep plain chat, but a 0.33.0 feature-required send to a
209
+ released member or through a released broker refuses before effects. Upgrade
210
+ broker, members, reconnect. Signed codec observations are compatibility only,
211
+ not privacy, permission, task or native authority.
212
+ - #1204's AC1-AC8 in-process acceptance audit was approved and the issue is closed.
213
+ Receiver dedupe retains its documented 30-day / 10,000-identity ceiling; removed
214
+ operator gap notices do not relax permanent replay floors.
215
+ - Agent-mem is now 0.22.1 via #1243, and #1244 accurately names the available
216
+ person-only activation preview. Default-host active-v3 sync still lacks fresh
217
+ placement-attestation integration (#1173); activation alone does not enable it.
218
+ No home activation, writer renewal or floor mutation occurs here.
219
+ - Other person/account-dependent gates remain in the smoke ledger. This task
220
+ performs no merge, tag, publication or release-consent write. The conductor's
221
+ release merge must preserve these stamps with a merge commit and the default
222
+ subject; the person's tag decision is separate.
@@ -0,0 +1,57 @@
1
+ # Claude Code 2.1.319 headless implementer receipt
2
+
3
+ Date: 2026-11-06. Scope: #888 (claude-implementer row), hub task #750. This repeats the procedures of the [2.1.318 receipt](2026-11-05-claude-implementer-2.1.318.md) on the installed Claude Code 2.1.319, with 2.1.318 run through the same producers as the control: the permission transport (Write, production-name Bash, Bash `updatedInput` rewrite) and the host shell wrapper. Source base: `f7cbefda` (0.32.0). Platform: macOS arm64, host Bun 1.4.3.
4
+
5
+ Result: every case passed on both binaries. `2.1.319` is added to `COMPAT["claude-implementer"].verified`.
6
+
7
+ | Native version | Binary SHA-256 |
8
+ | --- | --- |
9
+ | Claude Code 2.1.318 (control) | `677a2ea7bf576cedd20e191d973914ed8a41796f53a63b1923381ddc4d5b5e7d` |
10
+ | Claude Code 2.1.319 | `1f53587e92dee8e089fa349188a4cda64fa34ace6e7b0ca2ee278ddaa3cc2ebd` |
11
+
12
+ The 2.1.318 hash matches the 2.1.318 receipt, so the control is the binary it certified.
13
+
14
+ ## Upstream changes since 2.1.318
15
+
16
+ None to read: the upstream [CHANGELOG](https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md) had no 2.1.319 entry when this was checked (its newest heading was 2.1.318), and npm `@anthropic-ai/claude-code` latest was still 2.1.318. 2.1.319 reached this machine through the native installer. This receipt therefore rests on observed behavior only, with no changelog reading.
17
+
18
+ ## Runs
19
+
20
+ Each producer ran both binaries sequentially with an isolated HOME and `CLAUDE_CONFIG_DIR`, a fixture MCP server, a deterministic loopback provider and the literal API key `synthetic-probe-not-a-credential`, from a shell with the hub's agent markers (`AGENTHUB_HOME`, `AGENTHUB_PEER_ID`, `CLAUDECODE`, `CLAUDE_CODE_SESSION_ID`) unset. No account, provider request or model inference was involved. Every native child's process group was confirmed empty afterwards, and both binary hashes were the same before and after.
21
+
22
+ ```sh
23
+ python3 docs/verification/claude-permission-transport-native.py OUT/write --claude 2.1.318 --claude 2.1.319
24
+ python3 docs/verification/claude-permission-transport-native.py OUT/bash --tool Bash --server-name agent-hub --permission-tool hub_permission_request --require-tool-use-id --claude ... --claude ...
25
+ python3 docs/verification/claude-permission-transport-native.py OUT/rewrite --tool Bash --rewrite-bash --server-name agent-hub --permission-tool hub_permission_request --require-tool-use-id --claude ... --claude ...
26
+ python3 docs/verification/claude-shell-wrapper-native.py OUT/wrapper --bun ABSOLUTE_BUN --claude ... --claude ...
27
+ ```
28
+
29
+ (binary arguments are the absolute installed paths under `~/.local/share/claude/versions/`; `--bun` was the Homebrew Bun 1.4.3 path resolved with `readlink -f`).
30
+
31
+ | Producer | Cases per binary | 2.1.318 | 2.1.319 |
32
+ | --- | --- | --- | --- |
33
+ | Write transport (allow, deny, missing tool, hook deny/allow, MCP error, disconnect, pending, deadline) | 9 | 9 pass | 9 pass |
34
+ | Bash transport, production server and tool names, `tool_use_id` required | 9 | 9 pass | 9 pass |
35
+ | Bash `updatedInput` command replacement (allow, deny) | 2 | 2 pass | 2 pass |
36
+ | Host shell wrapper (persistent-cwd control, fixed-wrapper rewrite with replay refusal) | 2 | 2 pass | 2 pass |
37
+
38
+ Per-case shapes on 2.1.319 match the control: pending stopped externally at the deadline; wrapper control 3 requests and 2 permission calls, wrapper rewrite 4 requests and 3 permission calls with the effect counter at exactly 1 after replay.
39
+
40
+ The only producer change is the version allow-list in `claude-shell-wrapper-native.py`, which now admits `2.1.319`.
41
+
42
+ | Artifact | SHA-256 |
43
+ | --- | --- |
44
+ | Permission producer (unchanged) | `8f8885f7153b3a236f3b3f8ce49a344b908f2af3b3aba8b064762d82d1ecf12a` |
45
+ | Wrapper producer (this change) | `ce4b9fdd06e393656155a3bd767e899a445abaec4313d832f1a4a519a42c155d` |
46
+ | Wrapper host fixture (unchanged) | `616e6711e392f0eee7e3fa1c7bdc47a537dfa86bcc8ffb30e549ca94e5a71cef` |
47
+ | Fixed CLI wrapper (unchanged) | `8ff56514a6e3f25bce0784775d396df199b58b1b93f55ad0e8747bbc729d2fd8` |
48
+ | Write receipt JSON | `ed55c32bb86de8326251c63250b3bb90138e299558822f57fba19cb97231ddfb` |
49
+ | Bash receipt JSON | `a07501001835a7bcfb90bd4f6f546eb1e358bcad4be79b0e5b7f7d9b7c3d9e2d` |
50
+ | Rewrite receipt JSON | `1e3364f4925e098d34d9b7245a1b93bdd7815cb6d3e23138de2c25c7cede6238` |
51
+ | Wrapper receipt JSON | `f1708b427ae166cfc95e33e6c1c2ffc7d57acfae04cc6e2f394c9249292cab16` |
52
+
53
+ The receipt JSON files stay in the local diagnostic directory; they carry local paths and are not committed.
54
+
55
+ ## Evidence boundaries
56
+
57
+ Unchanged from the earlier receipts: no real provider authentication, model tool selection, person approval interaction, task-session resume or production-daemon task binding is proved, and this is not a runtime receipt gate. With no public changelog for 2.1.319, a behavior change outside these producers' cases would not be seen here. Native version admission and binary fencing remain required. The Monitor tool is still an unrewritten prompt-tool path. Exact-head package gate and CI are recorded on the PR.
@@ -0,0 +1,56 @@
1
+ # Codex 0.167.0 fresh-reviewer isolation receipt
2
+
3
+ Date: 2026-11-06. Platform: macOS arm64, Bun 1.4.3. Scope: issue #888, task 747. This repeats the [0.166.0 model-free production preparation](2026-10-31-codex-0166-reviewer-isolation.md) with 0.166.0 as the control. Source base: `f7cbefda` (0.32.0 on main). No `codex exec`, model request, login, credential copy or live reviewer run was performed. The returned launch was inspected, never started. The person's real HOME, `~/.codex`, the Orca codex account home and the global Codex install were never supplied to a Codex process or modified.
4
+
5
+ Result: all four model-free legs returned the expected outcome. 0.167.0 passed the model-free procedure and joins the verified reviewer set after the separately authorized model-backed run. This receipt does not add it, because `docs/agent-notes/adapters.md` requires a successful model-backed hub tool call before a reviewer version is marked verified (0.166.0 was reverted once for the same reason). That single run (the [2026-11-02 receipt](2026-11-02-codex-0166-reviewer-tool-call.md) is the 0.166.0 precedent) needs the person's separate authorization and was not run. It is unverified for 0.167.0, as is everything a model turn would show (tool selection, verdict delivery, the synthetic marker readback, real account authentication). Until then the person can run `ahub agents trust codex-review 0.167.0`, and every runtime proof still runs.
6
+
7
+ ## Source identity and re-read regions
8
+
9
+ `git ls-remote https://github.com/openai/codex.git` returned, for 0.167.0, annotated tag object `cb41599ccbe371272892f156286a236aa097bada` and peeled commit `086ccc833bc9cf01024ad2dd6af7dbd421b6bf9a`. The same readback returned the 0.166.0 tag object `593389380740f7b4762771573c447ccfdc59742f` and peeled commit `6ff1e1ca3b30fc8b914720681fcf5fe62e95f856`, matching its receipt.
10
+
11
+ Each of the seven files read for 0.166.0 was fetched at both peeled commits and compared by SHA-256 and by diff. Five are byte-identical between the tags: `exec/src/cli.rs`, `config/src/mcp_types.rs`, `core/src/mcp.rs`, `hooks/src/registry.rs` and `sandboxing/src/seatbelt.rs`. Two changed, `core/src/session/mod.rs` and `core-plugins/src/manager.rs`, and were read at their new anchors.
12
+
13
+ - [Exec switches, lines 40-50](https://github.com/openai/codex/blob/086ccc833bc9cf01024ad2dd6af7dbd421b6bf9a/codex-rs/exec/src/cli.rs#L40): identical. `--ephemeral`, `--ignore-user-config` and `--ignore-rules` remain independent global switches, and auth still uses `CODEX_HOME`.
14
+ - [Apps projection, lines 279-285](https://github.com/openai/codex/blob/086ccc833bc9cf01024ad2dd6af7dbd421b6bf9a/codex-rs/core/src/mcp.rs#L279) and [registration, lines 464-485](https://github.com/openai/codex/blob/086ccc833bc9cf01024ad2dd6af7dbd421b6bf9a/codex-rs/core/src/mcp.rs#L464): identical. Disabling MCP servers clears the Apps gate, and implicit Apps registration still needs Apps enabled and a non-isolated session. Configured inventory alone still cannot prove the runtime server absent, so effective feature readback stays required.
15
+ - [MCP schema, lines 243-245](https://github.com/openai/codex/blob/086ccc833bc9cf01024ad2dd6af7dbd421b6bf9a/codex-rs/config/src/mcp_types.rs#L243) and [291-297](https://github.com/openai/codex/blob/086ccc833bc9cf01024ad2dd6af7dbd421b6bf9a/codex-rs/config/src/mcp_types.rs#L291): identical. A disabled server is not initialized; `enabled_tools` restricts, `disabled_tools` filters afterwards.
16
+ - [Registry, lines 179-197](https://github.com/openai/codex/blob/086ccc833bc9cf01024ad2dd6af7dbd421b6bf9a/codex-rs/hooks/src/registry.rs#L179): identical. A non-empty legacy notify argv still becomes an after-agent hook independently of the hooks feature flag.
17
+ - [Session hook configuration, now line 5822](https://github.com/openai/codex/blob/086ccc833bc9cf01024ad2dd6af7dbd421b6bf9a/codex-rs/core/src/session/mod.rs#L5822) (was 5736) and the [session-static comment, now lines 2407-2410](https://github.com/openai/codex/blob/086ccc833bc9cf01024ad2dd6af7dbd421b6bf9a/codex-rs/core/src/session/mod.rs#L2407) (was 2389-2392): `session/mod.rs` changed (5756 to 5842 lines). The diff was read in full for the regions that matter here. `legacy_notify_argv: config.notify.clone()` is unchanged, and the comment still says legacy notify settings remain session-static. The other hunks are an `inject` visibility change, a `PendingApproval` import, a `NetworkApprovalTurn` enum, token-estimate and sampling bookkeeping, queued network approval holding, and an exec policy manager now built `from_snapshot` with its source requirements. None touches notify, hooks, Apps gating or isolated-session metadata. The host therefore still pins `notify=[]` for the metadata proofs and the returned exec argv.
18
+ - [Plugin manager, now lines 836-841](https://github.com/openai/codex/blob/086ccc833bc9cf01024ad2dd6af7dbd421b6bf9a/codex-rs/core-plugins/src/manager.rs#L836) (was 831-834): `manager.rs` changed (3793 to 3800 lines). The plugin-disabled early return of the default load outcome is unchanged. The one hunk, near line 665, clears per-plugin Apps policy before building the plugin load input, which does not change the disabled-plugins path.
19
+ - [Seatbelt glob compiler, lines 624-705](https://github.com/openai/codex/blob/086ccc833bc9cf01024ad2dd6af7dbd421b6bf9a/codex-rs/sandboxing/src/seatbelt.rs#L624): identical, so the anchored read/write denies, static-prefix variants and ancestor unlink denies are the same code.
20
+
21
+ ## Native production preparation
22
+
23
+ A throwaway producer outside the source checkout, in a private scratch directory, invoked the actual `codexReviewerBackend.prepare` from a clean worktree of main plus this change, with the frozen install's exact `@staix/agent-mem@0.21.0`. Each leg used its own fresh root holding project, HOME, CODEX_HOME and TMPDIR. The child ran under `env -i` with only PATH, LANG, HOME, CODEX_HOME, TMPDIR and two fixture markers. Before importing the backend, it rejected any extra variable, a `os.homedir()` that differed from HOME, and any home, CODEX_HOME or temp directory outside the root. The MCP transport was inert `/usr/bin/false` with no control token, and the private paths were `**/*.env`, `.private`, `nested/secret` and `~/private-proof`.
24
+
25
+ Both Codex versions were installed with `npm install --prefix` into separate private prefixes, with scratch HOME and cache and empty user and global npm configs. The command was each prefix's `codex.js` launcher, resolved by production to its native arm64 binary. Temporary roots and canaries were removed after each leg, and the returned exec launch was never executed.
26
+
27
+ | Leg | Outcome | Elapsed |
28
+ | --- | --- | --- |
29
+ | Before compat edit, 0.167.0, empty homes | Refused only at version admission, `causeClass: version`; previous verified set 0.146.0, 0.163.0, 0.164.0, 0.166.0 | 160.67 ms |
30
+ | With 0.167.0 provisionally in the local verified array (a stand-in for the person's machine trust), empty homes | All production preparation legs pass | 261.26 ms |
31
+ | Same provisional entry, synthetic ambient config | All production preparation legs pass | 261.83 ms |
32
+ | Control 0.166.0, empty homes (run before the edit) | All production preparation legs pass | 302.52 ms |
33
+ | Control 0.166.0, synthetic ambient config (run after the edit) | All production preparation legs pass | 252.46 ms |
34
+
35
+ The ambient file enabled Apps, plugins and hooks, set a legacy notify command and declared one stdio and one HTTP MCP server. Metadata preparation disabled the ambient servers, kept only the hub server with exactly `hub_review` and `hub_task_show`, and proved effective Apps, plugins and hooks disablement. Per-tool approval stays configured only for those two hub tools; actual MCP tool execution is outside this receipt.
36
+
37
+ | Version | Native binary SHA-256 | Production binary identity |
38
+ | --- | --- | --- |
39
+ | 0.167.0 | `030316ecfbb41f4e7946e584b0063ef333b7a36cd312ba349f2f6869e39b62cc` | `sha256:213f7a2c8109c5f5158151b829bfc561bc76bbcdcce0b641c1e9a01b8b541e37` |
40
+ | 0.166.0 (control) | `39acf979729dd290f9a24ee38b2914e036c91b65952872e28ae2a6b88a7db7c1` | `sha256:77c2eae1013cec5acaa8a2d980bb760a7ca7657ebb9cb3033550cad787ab2fdd` |
41
+
42
+ The control's native digest and production identity equal the values in the 0.166.0 receipt, so the procedure reproduces. Every successful launch returned `backend: codex`, `readOnly: true`, `strictMcp: true`, `ephemeral: true`, `current(): true`, an exec argv beginning `exec` and an explicit `-c notify=[]`. The evidence list was identical across all four successful launches and equal to the 0.166.0 list: `model-free-mcp-inventory-disabled-ambient`, `hub-tools-exact-allowlist`, `plugins-and-hooks-disabled`, `legacy-notify-disabled`, `apps-disabled-effective-feature-readback`, `web-search-disabled`, `project-untrusted`, `native-public-read-private-deny-write-deny`, `native-glob-and-symlink-private-deny`, `portable-core-name-and-state-deny`, `standard-host-credential-roots-denied`, `binary-config-stable`, `binary-hash-once-metadata-fence`, `session-ephemeral`.
43
+
44
+ Production's own native canaries passed for 0.167.0: public read, denied exact private read, denied nested private glob and symlink alias, denied portable-core `.env` and `.agenthub/state`, denied synthetic gh, kube and docker credential roots and credential alias, and denied creation of a new file with the file remaining absent. Production's metadata commands kept their 2-second command and 12-second overall limits and owned-group cleanup; none failed.
45
+
46
+ ## Compatibility and evidence boundaries
47
+
48
+ The verified reviewer versions stay 0.146.0, 0.163.0, 0.164.0 and 0.166.0. 0.167.0 is not added: the area note requires the model-backed hub tool call first, and a connector review on the first revision of this PR correctly flagged that I had added it. The two passing 0.167.0 legs above ran with 0.167.0 in a local, uncommitted copy of the verified array, which is the same admission outcome the person's `ahub agents trust codex-review 0.167.0` produces, since trust lifts only the version pin and every proof still runs. The committed tree refuses 0.167.0 at version admission, as the first leg showed. 0.165.0 stays unverified. The attached Codex adapter's capability pins (`NATIVE_PINS.codex`, still 0.166.0) are a separate contract and unchanged. No isolation implementation, sandbox ceiling or trust bypass changes. The compat receipt pointer names this receipt. `docs/verified.json` is not restamped.
49
+
50
+ Unverified for 0.167.0: the single model-backed tool-call run (marker, head, verdict and cleanup readback), which needs the person's separate authorization; exec selecting the named default profile; model tool selection; real account authentication; and effective web-search mode. The network setting is configured disabled without a separate probe. No native Linux result is claimed. Same-user mutation after the final metadata check is outside atomic snapshot guarantees, and the bounded credential-root list is not a classifier for every private host file.
51
+
52
+ Source claims apply to the two peeled commits only. Each upgrade repeats the procedure; the throwaway producer is not a supported command and its raw records carry temporary paths, so they stay outside git. The changed-source gate on dgx02 and exact-head hosted CI are separate evidence recorded on the PR.
53
+
54
+ ## Separately authorized model-backed attempt
55
+
56
+ The [2026-11-06 single tool-call attempt](2026-11-06-codex-0167-reviewer-tool-call.md) passed native startup isolation and the rendered accepted-plan marker precondition, then failed the harness readiness/readback leg before a complete persisted verdict/head/marker result was recorded. Its one-attempt fence was consumed once; no retry was made. The model/tool outcome remains unknown, not a proven missing verdict. This does not qualify 0.167.0, and the verified set remains unchanged.