@staix/agent-hub 0.12.31 → 0.12.32

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 (73) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/README.md +13 -7
  3. package/docs/agent-notes/adapters.md +7 -4
  4. package/docs/agent-notes/bus.md +1 -0
  5. package/docs/agent-notes/daemon.md +10 -7
  6. package/docs/agent-notes/local-worker.md +1 -1
  7. package/docs/agent-notes/tasks.md +3 -2
  8. package/docs/agent-notes/tests.md +1 -0
  9. package/docs/cooperbench.md +1 -1
  10. package/docs/gsd-collaboration-analysis.md +1 -1
  11. package/docs/memory.md +1 -1
  12. package/docs/operations.md +114 -22
  13. package/docs/quickstart.md +10 -6
  14. package/docs/security.md +12 -8
  15. package/docs/smoke.md +34 -0
  16. package/docs/specs/2026-09-19-agent-hub-design.md +204 -0
  17. package/docs/specs/2026-09-20-upgrade-recovery-design.md +191 -0
  18. package/docs/verification/2026-10-18-0.12.32.md +54 -0
  19. package/docs/verified.json +20 -15
  20. package/package.json +2 -2
  21. package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
  22. package/plugins/agent-hub/server.js +1296 -26
  23. package/src/adapters/acp.ts +5 -6
  24. package/src/adapters/definitions/builtin-metadata.ts +121 -0
  25. package/src/adapters/definitions/kimi-native.ts +4 -0
  26. package/src/adapters/definitions/qwen-native.ts +24 -0
  27. package/src/adapters/definitions/qwen.ts +71 -0
  28. package/src/adapters/pi.ts +6 -2
  29. package/src/adapters/registry-types.ts +174 -0
  30. package/src/adapters/registry.ts +36 -0
  31. package/src/cli/console-state.ts +74 -5
  32. package/src/cli/console.ts +35 -2
  33. package/src/cli/help.ts +3 -1
  34. package/src/cli/identity.ts +13 -3
  35. package/src/cli/launch.ts +1 -6
  36. package/src/cli/main.ts +200 -39
  37. package/src/cli/output.ts +2 -0
  38. package/src/cli/preview.ts +8 -5
  39. package/src/cli/recovery-guidance.ts +137 -0
  40. package/src/cli/recovery-presentation-options.ts +8 -0
  41. package/src/cli/recovery-session-file.ts +18 -0
  42. package/src/cli/terminal-recovery.ts +48 -0
  43. package/src/cli/upgrade-interactive.ts +129 -75
  44. package/src/cli/upgrade-labels.ts +30 -0
  45. package/src/cli/upgrade-presentation-data.ts +41 -0
  46. package/src/cli/upgrade-presentation-flags.ts +31 -0
  47. package/src/cli/upgrade-presentation.ts +217 -0
  48. package/src/cli/upgrade-restore-state.ts +6 -2
  49. package/src/cli/upgrade-runtime.ts +345 -194
  50. package/src/cli/upgrade.ts +276 -25
  51. package/src/hub/bus.ts +11 -0
  52. package/src/hub/cohorts.ts +2 -2
  53. package/src/hub/config-apply.ts +242 -0
  54. package/src/hub/config-reload.ts +120 -0
  55. package/src/hub/config-trust.ts +11 -2
  56. package/src/hub/crash.ts +8 -6
  57. package/src/hub/daemon.ts +559 -170
  58. package/src/hub/events.ts +2 -2
  59. package/src/hub/manager.ts +1 -1
  60. package/src/hub/peer-catalog.ts +10 -13
  61. package/src/hub/peers.ts +12 -2
  62. package/src/hub/permission-mode.ts +5 -3
  63. package/src/hub/recovery-continuity.ts +152 -0
  64. package/src/hub/recovery-store.ts +10 -4
  65. package/src/hub/sdlc.ts +5 -1
  66. package/src/hub/settings.ts +50 -36
  67. package/src/hub/settled-roles.ts +35 -0
  68. package/src/hub/supervision.ts +3 -2
  69. package/src/hub/tasks.ts +28 -8
  70. package/src/hub/ui.ts +1 -1
  71. package/src/memory/brief.ts +6 -5
  72. package/src/pi/session.ts +23 -4
  73. package/src/ui/index.html +23 -7
@@ -3056,3 +3056,207 @@ Evidence: `docs/verification/2026-10-17-418-probes.md`. The feasibility probe is
3056
3056
  - Cancellation releases overlap/reservation participation and sends each distinct former owner/reviewer one stop notice. Its trusted cancellation revision marker keeps that stop notice relevant; earlier notices for the cancelled task become moot under #434. The classifier never uses timestamps alone to identify the stop notice. Dependents keep waiting and receive the cancelled-dependency cause. List, show, explain, dashboard and release projections treat cancellation as closed, retaining the current privacy screen and distinguishing cancellation from successful approval.
3057
3057
  - The daemon advertises `task_cancel` in hello and status features. Current clients refuse cancellation without that feature. Upgrade and restart persist the verified target's exported features with its immutable root/digest before prepare, including cached targets, and reuse that receipt on resume after verifying the same bytes. A legacy staged receipt without feature evidence is probed only while a project is not yet past commit; fully committed projects do not require another probe. This preserves #215: a transient probe failure cannot refuse a target that was already staged with verified evidence. Preflight checks only uncommitted sources and refuses a target lacking `task_cancel` while cancelled rows exist. Source prepare/commit recheck before holds/snapshots and around asynchronous work; cancellation cannot write through recovery preparation. Refusals name task ids and never rewrite rows. An older binary started manually can misclassify cancelled rows as open or fail to move them; this is the explicit unsupported compatibility ceiling. Never map cancellation to approval.
3058
3058
  - The post-release live step remains separate: do not cancel the historical task or enable the project's sweep from implementation tests. AC7 needs installed-runtime receipts.
3059
+
3060
+ ## Amendment: live configuration reload (issue #439)
3061
+
3062
+ The daemon validates one captured candidate containing config.json, config.local.json,
3063
+ routing.toml and routing.local.toml before applying any part of it. Missing files use
3064
+ existing defaults; unreadable, malformed, unknown or invalid configuration refuses the
3065
+ whole candidate. The accepted routing snapshot remains authoritative until another
3066
+ complete candidate succeeds; last-good parser fallbacks never authorize a reload.
3067
+ Settings writes, undo, explicit `ahub settings reload`, dashboard reload and debounced
3068
+ file changes share this path. One invalid candidate produces one bounded notice naming
3069
+ the file/key and validation error, without echoing configuration values.
3070
+
3071
+ Every setting and configuration block has one apply class. Leaf rules override block
3072
+ rules. `live` changes future decisions immediately; `next use` changes the next task,
3073
+ request, batch or peer start; `restart` retains the running value and reports its key
3074
+ and reason. The registry exposes the running and file values separately.
3075
+
3076
+ | Apply class | Configuration |
3077
+ |---|---|
3078
+ | live | runtime permission choices, authorized roster changes, roles/planner/conductor, instruction-file protection, approvals.notify, research.enabled, snapshots.enabled/keep, task_sweep, tasks.wip_limits, capabilities, routing classes/stay_switch/signals/constraints/hub_routes/max_switch_prefill_tokens |
3079
+ | next use | permission_modes and catalog_roles at the next peer start; peers.*.start_mode and native launch argv; coordination for newly created tasks; task release/review policy; new approval timeouts; bus batch/admission limits; budget/context/inference/limits; peer watchdog and step limits; recovery and experiment decisions; memory brief/injection/suggestion limits |
3080
+ | next use | pi.auto_start changes a later startup/recovery auto-start decision; reloading it never starts or replaces a running peer |
3081
+ | restart | memory.enabled/native/worker_url/short_ttl_days/sync_interval_min: open consumers, selected profile binding, client and sync timer must be quiesced together |
3082
+ | next use | routing targets/routes/local selection at the next local peer or sidecar creation; existing native sessions retain their model contract |
3083
+ | restart | pi.dgx_coding/dgx_fast and routing.pi: model catalogue and context publication belong to the existing Pi relay; a reload must not replace a live native relay |
3084
+ | restart | omniroute: credential and gateway clients are bound to relay ownership |
3085
+ | restart | mlx: model/runtime ownership and device resources belong to the running instance |
3086
+ | restart | checks: bounded runner and completion-check execution contracts are constructed together |
3087
+ | restart | pii, data and local deny/read/network policy: existing native sessions and generated sandbox/proxy contracts must not acquire a different trust boundary mid-session |
3088
+ | restart | profile/profile_overrides and text_projection: session tool schemas, role/profile contracts and converter/cache ownership are bound at startup |
3089
+ | restart | terminal.open: the terminal provider is supplied by the daemon lifecycle |
3090
+ | restart | bench.enabled: the benchmark execution environment is selected before work starts |
3091
+
3092
+ Listener ports and the state directory are startup options rather than editable
3093
+ settings; their already-bound sockets and state ownership require a new daemon.
3094
+ Changing the external memory selector likewise requires the existing quiesce/reopen
3095
+ lifecycle and is never a hot reload or automatic migration.
3096
+
3097
+ Trust is checked against the actual source files and their last accepted raw layers,
3098
+ not against a scratch project's Git status. Effective guarded changes are also
3099
+ checked when unchanged raw declarations acquire different Git provenance. A
3100
+ settings ticket never authorizes command/policy fields outside the editable registry.
3101
+ Changed MACHINE_LOCAL values and raising
3102
+ registry values are refused from tracked or unverifiable files. Ordinary dashboard
3103
+ and watcher authority cannot adopt a raise hidden in an unrelated local edit. A
3104
+ settings session or terminal may adopt an untracked value within its existing
3105
+ settings authority; neither bypasses the tracked-file rule or the never-ask and
3106
+ roster confirmation/lifecycle fences. Runtime permission mutation still uses
3107
+ permissionChange/changePermission exclusively.
3108
+
3109
+ A sweep reload validates its next-pass policy and reschedules its timer without
3110
+ changing a pass already in progress. Bus scheduling changes retain queued originals,
3111
+ prefaces, manual pauses, recovery holds and inflight delivery. Coordination preference
3112
+ is pinned when a task is created (including split children); changing it neither
3113
+ retroactively silences an existing task nor lifts an existing silent cohort. Current
3114
+ PII and capability fences remain authoritative. Snapshot enablement applies to a
3115
+ later turn; a running turn retains its capture decision and is never stopped.
3116
+
3117
+ The console's sixth Settings tab reads the same registry as the dashboard. It edits
3118
+ through the authenticated daemon client: value, preview, nonempty bounded reason,
3119
+ then explicit y; undo also previews and confirms. Stale preview replies cannot arm a
3120
+ write, and pasted confirmation text never executes one. The daemon accepts additive
3121
+ settings_reload and undo-preview requests only from console roles. The dashboard's
3122
+ setting_reload action uses its existing authenticated session; manager forwarding
3123
+ has ordinary authority. No client writes configuration files directly. Pending
3124
+ restart keys and reasons appear in status, console and dashboard. These requests and
3125
+ optional projections are additive; older daemons refuse unknown requests and the
3126
+ control protocol remains 16.
3127
+
3128
+ ### Reload authority and publication scope (#439 review amendment)
3129
+
3130
+ Malformed syntax, unknown keys and invalid values still refuse the complete candidate
3131
+ before any publication. A valid but unauthorized key is different: retain that key's
3132
+ accepted value, report its name and reason, and continue applying independently
3133
+ eligible changes. A refused key never wedges an unrelated setting write.
3134
+
3135
+ An individual setting write or undo publishes only its named registry path. Its
3136
+ preview and confirmation do not authorize other edits in either config file or either
3137
+ routing file. This includes catalog guidance: only the named peer is prepared (#295).
3138
+ Unapplied edits remain pending for a later explicit reload; accepting another key must
3139
+ not acknowledge them in the accepted source baseline.
3140
+
3141
+ Privacy tightening is automatic from tracked or untracked files: enabling local PII
3142
+ constraints/screening, adding PII patterns, removing nonholder role memberships and narrowing an explicit capability list cannot
3143
+ be mistaken for a raise. Deleting a restricted capability entry restores the default of all capabilities and is a guarded widening. Roster membership changes always use their named confirmation and peer lifecycle, even when removing a peer; generic reload never bypasses those steps. Registered floors and known semantic reductions in admission
3144
+ or permission likewise remain available without authorizing a wider policy. Other
3145
+ agent-relevant policy, including limits, supervision feed, inference, review and crash
3146
+ resume, receives a per-key authority check even outside the settings registry.
3147
+
3148
+ `ahub settings reload` is the explicit adoption path for guarded file edits. The daemon
3149
+ first returns the exact guarded keys and a confirmation token bound to the candidate
3150
+ bytes and accepted configuration revision. The person reviews that list and confirms
3151
+ from an interactive terminal; only then may the same candidate be adopted. Changed
3152
+ bytes or accepted state invalidate the token. An ordinary watcher or dashboard never
3153
+ confirms a raise; a settings session remains restricted to registry keys. Tracked or
3154
+ unverifiable MACHINE_LOCAL command and credential declarations cannot become trusted
3155
+ through confirmation. Refusal notices name each key and say to review and run
3156
+ `ahub settings reload` or revert the file; tracked machine-local declarations also
3157
+ require moving the declaration to an untracked machine-local source.
3158
+
3159
+ Coordination pinning is local to a daemon lifetime. A setting reload preserves each
3160
+ existing task's captured mode and existing cohort silence; a daemon restart re-pins
3161
+ retained task rows to the startup mode. This is an explicit compatibility ceiling,
3162
+ not durable task metadata or a migration.
3163
+
3164
+ Inheritance and undo use the actual destination source trust. They may restore an unchanged effective startup value after explicit consent, but a shadowed edit that was never authorized is not an accepted fallback. New lower-layer raises remain refused even when an unchanged local overlay previously hid them.
3165
+
3166
+ Reserved prototype path components are refused throughout nested routing extension tables before publication. Configuration path writes never traverse inherited object properties.
3167
+
3168
+ Switchyard targets/routes and hub-route dictionaries retain opaque quoted keys, including dots. Each dictionary is one guarded value for reload confirmation and publication; privacy fields and ordinary registry settings retain leaf-level decisions.
3169
+
3170
+ ### Settled authority and reviewable confirmation (#439 round-2 amendment)
3171
+
3172
+ A role-list subset is automatic only when the settled planner and conductor holder
3173
+ sets stay unchanged. Removing the last explicit planner can hand that authority to
3174
+ the automatic fallback; removing a settled holder therefore requires guarded
3175
+ confirmation even though the raw role list shrinks. The same pure role resolver
3176
+ serves publication and the authority comparison.
3177
+
3178
+ The console preview shows a complete bounded before -> after value for every guarded
3179
+ key, including full executable argv, and describes any settled holder change. Values
3180
+ stay out of notices and events. A value that cannot fit the review budget is retained
3181
+ with an actionable rejection, never silently truncated and authorized. Each before
3182
+ or after representation is at most 16 KiB, an effect description at most 2 KiB, and
3183
+ the complete confirmation at most 128 KiB.
3184
+
3185
+ The confirmation token proves candidate/state freshness. It does not independently
3186
+ prove a person's presence: console-role authority is the existing server trust
3187
+ boundary, while the CLI enforces interactive TTY, explicit y and the deadline.
3188
+ The roster exact-key mutation guard observes admission while teardown is held,
3189
+ before reload can repair a wrong whole-roster assignment. The roster authority seed
3190
+ covers the dashboard authority boundary; its separate leaf check is defence in depth.
3191
+
3192
+ Console undo binds its confirmation to the previewed setting key and the SHA-256
3193
+ of the exact undo record. A changed or missing record refuses without writing;
3194
+ same-key replacement also invalidates the preview. These optional request fields
3195
+ preserve protocol 16 for older direct CLI clients. The Settings panel never forces
3196
+ a busy roster removal: it names `ahub roster remove <peer> --now` and the active-turn
3197
+ stop/detach consequence so the person can make that choice explicitly in the CLI.
3198
+
3199
+
3200
+ ### Adapter registry A1 (#451)
3201
+
3202
+ A1 introduces API 1 definitions for the seven existing kinds and separates a peer
3203
+ id from its adapter kind through `kindOf`, `definitionOf` and `familyOf`. With no
3204
+ instance declarations, only builtin ids resolve. A suffix is never guessed. This
3205
+ phase does not enable instance configuration, account changes or new native modes.
3206
+ Existing external-client admission and lazy roster behaviour remain unchanged.
3207
+
3208
+ Qwen is the first migrated ACP kind. Its definition owns the existing headless
3209
+ launch/factory, exact 0.25.0 identity, permission-mode mapping and session rules.
3210
+ The direct `AcpPeer` `qwen025` option and public helper exports remain compatible;
3211
+ legacy benchmark ACP without that flag stays unmanaged. Other kinds retain their
3212
+ existing runtime paths until A2; their registry metadata is not proof of a running
3213
+ or authenticated native client.
3214
+ Unmigrated definitions delegate launch plans to the existing CLI and keep existing
3215
+ runtime permission handlers authoritative. Claude, Pi and local keep empty partial
3216
+ native-mode maps where API 1 cannot express their scoped write/edit hooks; this is
3217
+ an A1 compatibility ceiling, not an unmanaged policy or a refusal. A2 must migrate
3218
+ those handlers and their representation before interpreting a missing mapping.
3219
+ Display-only permission grants remain exact copies of the existing explanations.
3220
+ The bounded Qwen doctor CLI-version probe and its 0.25.0 pin remain unchanged in
3221
+ the transitional guard baseline. A2 moves all version probes together and amends
3222
+ `VersionContext` once; A1 adds no observed-version input or native readiness claim.
3223
+ The native Kimi mode-id constant moves to a dependency-free leaf while its public
3224
+ re-export remains intact, so either registry-first or definition-first imports work.
3225
+
3226
+ Two additive fields complete source inputs omitted from the A0 type sketch:
3227
+
3228
+ - `LaunchContext.nativeCommand?: readonly string[]` carries the already-validated
3229
+ native argv, including wrapper arguments. Only core config or the existing
3230
+ redacted preview supplies it; definitions never load daemon config or recover
3231
+ commands from environment text. Model tool schemas do not expose this field.
3232
+ - `permission.grants?: Partial<Record<PermissionMode, string>>` carries existing
3233
+ operator explanations as static data. It changes no approval decision, scope or
3234
+ native mode. The frozen `CreateContext` and transport-specific options stay intact.
3235
+
3236
+ The guard inventories AST comparisons, closed-list imports and vendor literals,
3237
+ including inline dashboard scripts, under stable file/symbol scopes. Its reviewed
3238
+ A1 baseline records the current source, rather than claiming the old A0 grep's
3239
+ 265 line matches equal AST node counts. A new group, count growth or stale entry
3240
+ fails; later phases may only shrink this baseline. Only real, unshadowed registry
3241
+ resolver imports exempt kind-aware comparisons. Native adapter implementations and
3242
+ explicit non-peer config semantics remain the narrow exceptions. Existing literal
3243
+ catalog exports used by older recovery source probes are retained until their
3244
+ replacement compatibility proof is available; a refactor must not silently make a
3245
+ Qwen-capable target appear unsupported.
3246
+
3247
+ The reviewed inventory distinguishes the historical grep from AST nodes: at
3248
+ `71253098`, the same AST scanner counts 364 sites in 142 groups (222 comparisons,
3249
+ 19 closed-list imports, 123 vendor literals). At A1's main base `4bcf62fa`, it counts
3250
+ 395 in 156 groups. The first A1 snapshot has 382 in 155 groups: thirteen Qwen/raw
3251
+ watch comparisons are removed, and the seven-entry role object becomes a
3252
+ seven-entry legacy-order list whose role values come from the registry. No raw
3253
+ Qwen comparison remains outside the native definitions. The initial baseline is
3254
+ reviewed data, never regenerated by the test; changes brought by a newer main
3255
+ must be reconciled explicitly before this first baseline ships.
3256
+
3257
+ Before the first A1 review, main `b9efa131` merged #463. Its recovery guidance and
3258
+ reattach logic add 33 sites in 16 groups, with 19 changed baseline entries. The
3259
+ same scanner reports 428/172 on that main and 415/171 on the combined A1 source.
3260
+ Every added or increased baseline entry matches that main-only delta; A1 still
3261
+ removes thirteen sites and one group. This explicit reconciliation precedes the
3262
+ first shipped baseline and does not permit later phases to grow it.
@@ -514,6 +514,7 @@ Cells show action -> next receipt status. Fresh-session eligibility is marked fr
514
514
  | Target stopped or changed | block -> unchanged |
515
515
  | Running target, other session not allowed | block -> unchanged |
516
516
  | Absent receipt | unstarted; initial launch is handled by the runtime outside this receipt table |
517
+ | Done, running target, no attached session, gone launchers and positively gone saved terminal (#463 supplemental evidence) | reattach -> failed; one recorded-session repair, no fresh-session choice |
517
518
 
518
519
  Running target, no attached session (either allowOther value):
519
520
 
@@ -658,3 +659,193 @@ front end to the commands above, never a second coordinator.
658
659
  - Out of scope: a hub-side interrupt of a running turn (the running source may
659
660
  be older and would not know the request), and answering approvals from the
660
661
  screens.
662
+
663
+
664
+ ### Post-restore detachment and recorded-session reattachment (#463)
665
+
666
+ A done restore receipt remains done for an offline peer unless both independent
667
+ proofs hold on the same running target instance: every relevant launcher is gone,
668
+ including older target instances, and the exact saved terminal is positively
669
+ orphaned or missing. Disconnection alone, an unreadable or truncated inventory,
670
+ unknown launch records, changed terminal identity and a different attached session
671
+ never authorize a replacement.
672
+
673
+ The pure restore table has one additional rule: done + running target + no attached
674
+ session + gone launchers + positively gone saved terminal proposes reattach ->
675
+ failed. The original 540 cells with no new evidence remain unchanged. Before
676
+ returning the block, the runtime saves a per-project, per-peer reattachment marker
677
+ with the accepted done binding, detection time, fixed cause `detached after restore`
678
+ and state `ready`, plus the failed restore receipt and `started` project phase.
679
+ The blocked operation identifies that project and peer structurally, never by
680
+ parsing error text.
681
+
682
+ Resume reuses the ordinary restore path with that accepted conversation, session
683
+ file, backend and model. Before any new terminal effect the marker becomes
684
+ `attempted`. Chosen waiting bindings remain durable and reuse the existing 600 s
685
+ attachment bound; an interruption cannot grant another create. A second detach or
686
+ an exhausted attempt blocks with its recorded cause. These repairs default to
687
+ recorded-session-only continuity: no automatic fresh/zero-turn replacement is
688
+ introduced. Only the explicit missing-history exception below permits a person
689
+ to select a replacement. Strict session/file checks remain for repairs;
690
+ ordinary verified-empty Pi attachments retain their pre-existing id-only rules.
691
+ When `recordRestart` retires a known done or waiting binding from a dead target,
692
+ it clears that binding's repair fence. The normal #225 relaunch preserves its
693
+ accepted conversation and a new target gets its own repair allowance. The additive
694
+ per-peer `repairedSessions: true` provenance survives this fence reset and repeated
695
+ restarts. It authorizes no creation: accepted done/retired bindings remain the
696
+ session source, and fresh-session choices and zero-turn substitutions remain
697
+ excluded automatically for that repaired conversation. A person may explicitly
698
+ choose `dispose --fresh-session` for a failed repaired Codex or Claude conversation only after
699
+ the coordinator records a typed positive missing-transcript/rollout observation
700
+ bound to the accepted session, and disposal rechecks that same recorded store as
701
+ missing before writing the loss and audit. Found, unreadable, malformed or absent
702
+ evidence never permits this choice. The choice records the accepted conversation
703
+ as lost; it does not run a terminal. The receipt also records
704
+ `freshOverride {peer, evidence, checked, at}`, exposed in person status and the
705
+ archive summary. New missing observations and overrides include `checkedPath`: the
706
+ exact Claude transcript file or recursively searched Codex sessions directory.
707
+ The lookup and display share the same captured-environment/default-home path
708
+ resolver; this is evidence of that checked location, not proof of every native
709
+ store layout. Refusals name the checked location as well. Resume retains the existing launcher fences,
710
+ close-before-create and waiver rules. An uncertain
711
+ creation with no durable selected binding does not gain a second creation by
712
+ merely losing the target. Database contention retains its typed retryable outcome.
713
+
714
+ Repaired missing-history disposal is never delegated under `--live-test`.
715
+ Because ordinary #408 fresh disposal uses the same argv and remains delegable,
716
+ the CLI first classifies the already-loaded receipt read-only. An unreadable,
717
+ unparseable or unclassifiable receipt, including a peer absent from its projects,
718
+ refuses delegation. A repaired override is refused before runner/lock acquisition
719
+ or coordinator mutation. Core repeats the trusted per-invocation delegation
720
+ check before the lock and after its under-claim read. No model/request field
721
+ can grant person authority, and no new public waiver flag is introduced.
722
+
723
+ Pi remains excluded from fresh-session under #215. For a positively missing
724
+ accepted Pi session file, blocked guidance prints the operation's
725
+ `recovery dispose <id> --stop-and-archive --reason <text>` command and then
726
+ `ahub --project <root> pi`. The normal Pi start retires a proven-unresumable
727
+ archived bookmark without falling back fresh in that same start; its notice
728
+ guides a subsequent normal start. The Pi fresh-session refusal itself prints
729
+ the same stop-and-archive and project-scoped start commands. Unreadable or invalid
730
+ evidence stays held.
731
+
732
+ The person-only `ahub recovery reattach <operation> <peer>` is admitted only for
733
+ that operation's current structured reattachment block. It claims the existing
734
+ runner fence, rechecks the held target and restores only the selected peer. It
735
+ accepts no session override, performs no release or installation, and leaves the
736
+ remaining operation for resume. Agent shells and live-test delegation cannot
737
+ invoke this person decision. Person status and block guidance list the recorded
738
+ Codex thread, Pi session file and Claude session with quoted commands from the
739
+ operation's coordinator.
740
+
741
+ Status guidance, the archive summary and the Pi continuity bookmark share one
742
+ accepted-binding resolver: restored done/waiting, then a validated reattachment
743
+ marker, then a decoded retired binding for this peer and project, then the plan.
744
+ A malformed retained binding is unavailable, never permission to fall back to an
745
+ older conversation. This includes the accepted Pi file, backend and model after
746
+ a #225 target restart.
747
+
748
+ Stop and archive retains the operation's accepted session identities. After a
749
+ confirmed owned target stop and snapshot archive, it may write one private,
750
+ project-bound Pi continuity bookmark. The next normal `pi.auto_start` passes that
751
+ recorded identity through the existing start-mode and lifecycle path; it never
752
+ falls back fresh because a bookmark is invalid or unreadable. The bookmark is
753
+ consumed only after authenticated attachment proves the same session and file,
754
+ not merely after opening a terminal. Atomic compare/consume cannot remove a newer
755
+ operation's bookmark. No global operation-directory scan or native probe is used
756
+ to discover sessions. The person summary distinguishes historical target startup,
757
+ plugin installation and the remaining global CLI installation, and continues to
758
+ say abandoned, not completed or rolled back.
759
+
760
+ A missing, expired, unreadable or foreign snapshot prevents a continuity bookmark,
761
+ not stop-and-archive itself. Disposal records a per-project continuity warning and
762
+ still releases its machine lock. An actual rename failure of this operation's own
763
+ snapshot retains the existing failure and retry path. Optional bookmark storage
764
+ failure is recorded as unavailable rather than blocking this last-resort exit.
765
+
766
+ A valid bookmark is archived with a structured reason under its exact CAS when a
767
+ different authenticated Pi session becomes the saved crash record, its recorded
768
+ session is proven unresumable, or a later recovery successfully releases the
769
+ project. Unknown I/O or provider failures do not prove an unresumable session.
770
+ Malformed or unverifiable bookmark evidence remains fail-closed. The TUI resume
771
+ argv carries `--session-file` when available, otherwise `--session-id`, never both.
772
+
773
+ ### Continuity retirement follow-up (#463)
774
+
775
+ An externally retired or replaced bookmark invalidates the daemon's cached copy.
776
+ A failed compare-and-swap re-reads the private bookmark; absence drops the old
777
+ in-memory selection, while newer or unreadable evidence remains distinct from
778
+ absence. Session recording writes `sessions.json` only when its serialized peers
779
+ change. Settlement may use an already durable unchanged crash record but may not
780
+ retire continuity before that record was successfully written. No offline-Pi event
781
+ forces a redundant write. A header whose session id disagrees with the selected
782
+ bookmark is `bookmark_mismatch` (bookmark inconsistent), not evidence that the
783
+ session itself cannot resume. Archival remains non-destructive and never starts
784
+ a fresh session.
785
+
786
+ Repeated Pi continuity settlement storage failures back off for 30 seconds for
787
+ the same bookmark digest and authenticated peer generation/metadata. A new
788
+ digest or authenticated identity can retry immediately; successful settlement
789
+ clears the failure. An unchanged failure logs once, without session-file churn.
790
+
791
+ ## Recovery presentation (#466)
792
+
793
+ Interactive upgrade and recovery screens reuse the console's Span tones, paint,
794
+ measured wrapping and resolveColor precedence. Auto uses TTY and environment
795
+ rules; explicit always has exactly the console's behaviour, including on a pipe.
796
+ Default and never retain existing piped, dry-run, status and dispose JSON bytes.
797
+ Raw JSON, including [j] and --json, bypasses paint and width handling. Human plan,
798
+ progress, error, menu and summary lines fit the measured terminal width.
799
+ The #272 simulated-TTY golden moves to this #466 presentation contract; its
800
+ restart identity, board and non-TTY byte assertions remain unchanged.
801
+
802
+ Only nextChoices supplies operation actions. Presentation may annotate a choice
803
+ as recommended or disabled, but cannot create an action, bypass a refusal or run
804
+ a driver. Enter defaults only to a read-only action; applying, resuming or
805
+ reattaching requires the explicit action key. Preserve the full human wait
806
+ condition from nextChoices, replacing only its retained status command in normal
807
+ output. Existing commands through io.run remain the only mutation path. A
808
+ destructive choice names its stop/abandon consequence before confirmation. Resume
809
+ really runs stage again, labelled "checking retained release"; the screen reports
810
+ only work observed on that attempt and keeps internal coordinator paths verbose.
811
+
812
+ Operation receipts may add read-only wait timing metadata with ISO waitStartedAt,
813
+ deadlineAt and waitEndedAt values. The coordinator records them at the actual
814
+ prepare and awaitAttachment wait boundaries. They do not set or extend any
815
+ deadline, change controls, alter the 540-cell transition oracle or its supplemental
816
+ matrix, or turn unknown evidence into a decision. Older receipts say "timing
817
+ unknown"; updatedAt is never substituted for the actual wait start.
818
+ Each new runner attempt clears the previous timing projection before observing
819
+ its own waits, so a resumed step cannot display a previous wait as current.
820
+
821
+ Preservation errors carry a typed cause from the exact queue, manual-pause,
822
+ task-board and budget integrity comparisons. What/Why/What-to-do is rendered from
823
+ that cause and recorded recovery guidance, never inferred by parsing a combined
824
+ error string. A read-only end-inspection port may supply current runtime state to
825
+ the human summary; a failed readback is unknown. Summary rendering performs no
826
+ lifecycle action and distinguishes recorded installation effects from current
827
+ runtime observations. Older readers ignore the optional presentation metadata.
828
+
829
+ Current native terminal, session, launcher, target and attachment-timeout guards
830
+ may record a closed presentation cause containing only the actual IDs, states
831
+ and wait window observed at that guard. A repair wrapper retains only a proven
832
+ inner presentation error. Generic errors and lookalike objects remain untyped;
833
+ their messages are never classification input. This metadata changes no guard,
834
+ error message, restoration receipt transition or permission to create a terminal.
835
+
836
+ Presentation timing writes are best-effort observations: retain their in-memory
837
+ values, log a fixed warning on a metadata write failure and continue. Ordinary
838
+ receipt/effect writes remain authoritative and fail normally. A newly observed
839
+ blocked or completed step with no measured start has unknown elapsed time, never
840
+ an invented zero. Waiting prints on a changed condition plus at most one elapsed
841
+ tick per minute. Screen-owned recovery children keep stdout quiet on capable
842
+ coordinators so the parent alone renders progress and outcome. All external
843
+ renderer values containing line breaks or controls are visibly quoted before
844
+ wrapping; they cannot become new column-zero guidance. Colour flags follow the
845
+ console grammar exactly: a single `--color=<mode>`, never a bare or repeated flag.
846
+
847
+ Recovery authorization and the presentation parser share the pure
848
+ `recoveryPresentationFlag` classifier. Authorization identifies the action after
849
+ skipping the accepted one-shot presentation flags (`--json`, `--verbose`, `--color=<mode>`). Such flags never hide
850
+ person-only reattachment from agent or live-test refusal checks; normalization
851
+ confers no authority and unknown flags still fail the command parser.
@@ -0,0 +1,54 @@
1
+ # 0.12.32 release verification
2
+
3
+ This record covers release preparation and source review. It does not claim publication, installation, a running-hub restart or native/live acceptance.
4
+
5
+ ## Candidate
6
+
7
+ Version 0.12.32, control protocol 16 (`src/hub/control-client.ts`), from merged main `2b2d6d2d67d3ed54a94fab19b5745e20a779b7d5`. The candidate includes all 9 PRs merged since `v0.12.31`: #465, #467, #468, #470, #471, #472, #473, #474 and #475. The exact first-party memory pin remains `@staix/agent-mem` 0.3.1.
8
+
9
+ - The upgrade runs with the target release's own coordinator (`bunx --package @staix/agent-hub@0.12.32 ahub upgrade`), so an upgrade into 0.12.32 already uses the #463 reattach and continuity changes and the #466 screens.
10
+ - #439 live settings reload ships with per-key trust: a write or undo publishes only its own key, guarded or machine-local file edits are adopted only by a confirmed terminal `ahub settings reload`, and a change of the settled planner or conductor holders is guarded. The native real-terminal console leg (#439 AC5) is not verified here.
11
+ - #451 A1 (adapter registry) is a refactor with no intended behaviour change; the registry guard baseline is 415 sites in 171 groups at the candidate.
12
+ - agent-mem main contains the curated shard migration (agent-mem#15 T2), which is not released. agent-hub still opens memory through `new MemoryStore()` (`src/hub/memory-profile.ts`); task #175 must land before any agent-mem release that ships T2, and the person must not run `amem migrate --shards` before then.
13
+ - Still open: a real Orca upgrade exercising `ahub recovery reattach` (#463), installed managed-Pi #418 AC8 (#142) and #438 AC7.
14
+
15
+ ## Document review
16
+
17
+ The initial `node scripts/check-docs.mjs --require-fresh` reported 13 stale documents. Each was compared against its covered source changes from its prior stamp through the candidate, then against the release metadata. Symbols and limits were checked in the source, not inferred from commit messages. No document review is deferred. The models note was already fresh and keeps its stamp.
18
+
19
+ | Document | Prior source stamp | Review result | Checked claims and correction |
20
+ | --- | --- | --- | --- |
21
+ | `README.md` | `6637a383c3f46ae173b14268d29c8b0d306eac95` | corrected | Status 0.12.32 and protocol 16; the Jcode MCP refresh is scoped to upgrades from 0.12.30 or earlier (`src/cli/jcode-mcp.ts` last changed in 0.12.31); live settings reload; the unreleased shard migration warning; the verification link and open legs. |
22
+ | `docs/quickstart.md` | `56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c` | corrected | `v0.12.32` examples, the target coordinator and `ahub recovery reattach`, `ahub settings reload` in the working-day table, and the dashboard reload button. |
23
+ | `docs/security.md` | `56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c` | corrected | Memory pin 0.3.1; the Pi continuity bookmark record; dashboard reload and ordinary-session floors; reload trust (watched files, per-key provenance, automatic privacy tightening, confirmed terminal reload only); live-test refusals for reattach and the repaired fresh-session dispose. |
24
+ | `docs/operations.md` | `56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c` | corrected | 0.12.32 header and upgrade examples, protocol 16 covering 0.12.20 through 0.12.32, the console Settings panel, the ordinary dashboard settings authority, the repaired-session fresh dispose and the Pi bookmark. |
25
+ | `docs/agent-notes/README.md` | `56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c` | unchanged | Console tab 6 and the settings editor do not affect the exact-row navigation rule; the cited tests and verification file exist. |
26
+ | `docs/agent-notes/adapters.md` | `56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c` | corrected | `KIMI_MODE_IDS` location; a reloaded permission default only through `applyPendingPermissionDefault`; adding a native peer through an `AdapterDefinition`; the registry guard baseline only shrinks; watchdog reload; typed Pi session failures. |
27
+ | `docs/agent-notes/benchmarks.md` | `56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c` | unchanged | The covered changes only move Qwen identity and mode ids into definitions and add Pi session error classes; the benchmark rules still match. |
28
+ | `docs/agent-notes/budget.md` | `56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c` | unchanged | The budget, statusline, journal, restart and context-window sources are unchanged; the bus and daemon changes do not touch budget rules. |
29
+ | `docs/agent-notes/bus.md` | `56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c` | corrected | Reloaded batching and queue limits only through `Bus.configureScheduling`, affecting later batching and admission only. |
30
+ | `docs/agent-notes/daemon.md` | `56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c` | corrected | `reloadConfig` as the only publication path with scoped writes, per-key trust, guarded holder changes, the reload token and undo identity; the Pi bookmark exception scoped to `pi.auto_start`; `reattachRecovery`; the #466 presentation rules. Four new source files added to its scope. |
31
+ | `docs/agent-notes/local-worker.md` | `56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c` | corrected (ASCII only) | One existing em-dash replaced; the sandbox, path and permission rules are unchanged. |
32
+ | `docs/agent-notes/tasks.md` | `56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c` | corrected | `resolveSettledRoles`; the coordination mode captured per task at creation, cohorts within one mode, and the restart re-pin; `src/hub/settled-roles.ts` added to its scope. |
33
+ | `docs/agent-notes/tests.md` | `56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c` | corrected | The registry guard scans `src/` against the committed baseline, and no test writes or regenerates it. |
34
+
35
+ `AGENTS.md` area notes and `docs/verified.json` paths now include `src/hub/config-reload.ts`, `src/hub/config-apply.ts`, `src/hub/recovery-continuity.ts` and `src/cli/recovery-presentation-options.ts` (daemon) and `src/hub/settled-roles.ts` (tasks). A separate manifest commit restamps the reviewed documents against the reviewed source; it does not stamp itself. The release PR must use a merge commit, and committed freshness is rerun on main before tagging.
36
+
37
+ ## Recorded checks
38
+
39
+ GitHub readback found a successful `check.yml` run at each PR's final head. Both OS check jobs, all four seeded shards and the `seeded guards` aggregate succeeded for every row. These prior PR gates do not replace the release candidate's own exact-head CI.
40
+
41
+ | PR | Final head | CI run |
42
+ | --- | --- | --- |
43
+ | [#465](https://github.com/STAIxBWLB/agent-hub/pull/465) | `fcb27ca4af74bef6b264af9bf9f3e0490a824971` | [39025787130](https://github.com/STAIxBWLB/agent-hub/actions/runs/39025787130) |
44
+ | [#467](https://github.com/STAIxBWLB/agent-hub/pull/467) | `94a52afb4638e687049c13ef0c27dc4a66483355` | [39027067759](https://github.com/STAIxBWLB/agent-hub/actions/runs/39027067759) |
45
+ | [#468](https://github.com/STAIxBWLB/agent-hub/pull/468) | `de30d9e3518da40546a900d3e0940dc882179e6d` | [39028179223](https://github.com/STAIxBWLB/agent-hub/actions/runs/39028179223) |
46
+ | [#470](https://github.com/STAIxBWLB/agent-hub/pull/470) | `17c593b7e04ee82f789525552b8b6e0f922d8c8f` | [39039356493](https://github.com/STAIxBWLB/agent-hub/actions/runs/39039356493) |
47
+ | [#471](https://github.com/STAIxBWLB/agent-hub/pull/471) | `04f55cd942533e7b49c00f5e2d941e42e448fbd5` | [39046673325](https://github.com/STAIxBWLB/agent-hub/actions/runs/39046673325) |
48
+ | [#472](https://github.com/STAIxBWLB/agent-hub/pull/472) | `e214fc9ec7306e88b9906ff3847fdda4f3227785` | [39049995436](https://github.com/STAIxBWLB/agent-hub/actions/runs/39049995436) |
49
+ | [#473](https://github.com/STAIxBWLB/agent-hub/pull/473) | `11fe040e500bf65d3e9c38792a2e05f5fd338bae` | [39056391496](https://github.com/STAIxBWLB/agent-hub/actions/runs/39056391496) |
50
+ | [#474](https://github.com/STAIxBWLB/agent-hub/pull/474) | `cfcd087452e8afe7215039168cbd535ef8088765` | [39063863001](https://github.com/STAIxBWLB/agent-hub/actions/runs/39063863001) |
51
+ | [#475](https://github.com/STAIxBWLB/agent-hub/pull/475) | `1abbaebe235ccfd4ea30ee2c6961ad55f51aec3a` | [39066256392](https://github.com/STAIxBWLB/agent-hub/actions/runs/39066256392) |
52
+
53
+ - Generated assets: `bun install --frozen-lockfile` and `bun run build` ran locally at `6883f4d8`. The only change to `plugins/agent-hub/server.js` and the plugin manifest is the version string 0.12.31 -> 0.12.32; the release PR's CI checks bundle freshness.
54
+ - The release PR's own exact-head CI and the release workflow's tag checks are recorded on the PR and the tag, not here.
@@ -2,7 +2,7 @@
2
2
  "schemaVersion": 1,
3
3
  "documents": {
4
4
  "README.md": {
5
- "verifiedAgainst": "6637a383c3f46ae173b14268d29c8b0d306eac95",
5
+ "verifiedAgainst": "cf3026feab218207f0c21b300552eada0d5be227",
6
6
  "paths": [
7
7
  "package.json",
8
8
  "src/",
@@ -11,14 +11,14 @@
11
11
  ]
12
12
  },
13
13
  "docs/security.md": {
14
- "verifiedAgainst": "56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c",
14
+ "verifiedAgainst": "cf3026feab218207f0c21b300552eada0d5be227",
15
15
  "paths": [
16
16
  "src/",
17
17
  "templates/"
18
18
  ]
19
19
  },
20
20
  "docs/operations.md": {
21
- "verifiedAgainst": "56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c",
21
+ "verifiedAgainst": "cf3026feab218207f0c21b300552eada0d5be227",
22
22
  "paths": [
23
23
  "package.json",
24
24
  "src/",
@@ -35,7 +35,7 @@
35
35
  ]
36
36
  },
37
37
  "docs/quickstart.md": {
38
- "verifiedAgainst": "56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c",
38
+ "verifiedAgainst": "cf3026feab218207f0c21b300552eada0d5be227",
39
39
  "paths": [
40
40
  "package.json",
41
41
  "src/",
@@ -43,7 +43,7 @@
43
43
  ]
44
44
  },
45
45
  "docs/agent-notes/adapters.md": {
46
- "verifiedAgainst": "56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c",
46
+ "verifiedAgainst": "cf3026feab218207f0c21b300552eada0d5be227",
47
47
  "paths": [
48
48
  "src/adapters/",
49
49
  "src/pi/",
@@ -62,7 +62,7 @@
62
62
  ]
63
63
  },
64
64
  "docs/agent-notes/benchmarks.md": {
65
- "verifiedAgainst": "56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c",
65
+ "verifiedAgainst": "cf3026feab218207f0c21b300552eada0d5be227",
66
66
  "paths": [
67
67
  "scripts/benchmarks/",
68
68
  "test/benchmarks/",
@@ -74,7 +74,7 @@
74
74
  ]
75
75
  },
76
76
  "docs/agent-notes/budget.md": {
77
- "verifiedAgainst": "56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c",
77
+ "verifiedAgainst": "cf3026feab218207f0c21b300552eada0d5be227",
78
78
  "paths": [
79
79
  "src/hub/budget.ts",
80
80
  "src/cli/statusline-tee.ts",
@@ -86,7 +86,7 @@
86
86
  ]
87
87
  },
88
88
  "docs/agent-notes/bus.md": {
89
- "verifiedAgainst": "56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c",
89
+ "verifiedAgainst": "cf3026feab218207f0c21b300552eada0d5be227",
90
90
  "paths": [
91
91
  "src/hub/bus.ts",
92
92
  "src/hub/envelope.ts",
@@ -98,7 +98,7 @@
98
98
  ]
99
99
  },
100
100
  "docs/agent-notes/daemon.md": {
101
- "verifiedAgainst": "56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c",
101
+ "verifiedAgainst": "cf3026feab218207f0c21b300552eada0d5be227",
102
102
  "paths": [
103
103
  "src/hub/daemon.ts",
104
104
  "src/hub/control-client.ts",
@@ -131,11 +131,15 @@
131
131
  "src/hub/start-mode.ts",
132
132
  "src/hub/terminal-open.ts",
133
133
  "src/hub/recovery-error.ts",
134
- "src/hub/db-timeout.ts"
134
+ "src/hub/db-timeout.ts",
135
+ "src/hub/config-reload.ts",
136
+ "src/hub/config-apply.ts",
137
+ "src/hub/recovery-continuity.ts",
138
+ "src/cli/recovery-presentation-options.ts"
135
139
  ]
136
140
  },
137
141
  "docs/agent-notes/local-worker.md": {
138
- "verifiedAgainst": "56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c",
142
+ "verifiedAgainst": "cf3026feab218207f0c21b300552eada0d5be227",
139
143
  "paths": [
140
144
  "src/adapters/local-worker.ts",
141
145
  "src/local/",
@@ -155,7 +159,7 @@
155
159
  ]
156
160
  },
157
161
  "docs/agent-notes/tasks.md": {
158
- "verifiedAgainst": "56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c",
162
+ "verifiedAgainst": "cf3026feab218207f0c21b300552eada0d5be227",
159
163
  "paths": [
160
164
  "src/hub/tasks.ts",
161
165
  "src/hub/board.ts",
@@ -168,11 +172,12 @@
168
172
  "src/hub/conductor.ts",
169
173
  "src/hub/supervision.ts",
170
174
  "src/hub/tool-refusal.ts",
171
- "src/hub/daemon.ts"
175
+ "src/hub/daemon.ts",
176
+ "src/hub/settled-roles.ts"
172
177
  ]
173
178
  },
174
179
  "docs/agent-notes/tests.md": {
175
- "verifiedAgainst": "56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c",
180
+ "verifiedAgainst": "cf3026feab218207f0c21b300552eada0d5be227",
176
181
  "paths": [
177
182
  "test/",
178
183
  "scripts/check.sh",
@@ -191,7 +196,7 @@
191
196
  ]
192
197
  },
193
198
  "docs/agent-notes/README.md": {
194
- "verifiedAgainst": "56ae16dfd69d3c72bcc1f4efdabbda1905f75b9c",
199
+ "verifiedAgainst": "cf3026feab218207f0c21b300552eada0d5be227",
195
200
  "paths": [
196
201
  "src/cli/console-state.ts",
197
202
  "src/cli/attention.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staix/agent-hub",
3
- "version": "0.12.31",
3
+ "version": "0.12.32",
4
4
  "description": "Native multi-agent hub: Claude Code, Codex, Kimi Code, Pi and local inference as peers in one project",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,7 +17,7 @@
17
17
  "bun": ">=1.4.2"
18
18
  },
19
19
  "dependencies": {
20
- "@staix/agent-mem": "0.3.0"
20
+ "@staix/agent-mem": "0.3.1"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@modelcontextprotocol/sdk": "^1.27.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-hub",
3
- "version": "0.12.31",
3
+ "version": "0.12.32",
4
4
  "description": "Channel between Claude Code and the agent-hub daemon: peer messages from Codex, Kimi and the local worker arrive as channel events; hub_send replies.",
5
5
  "author": {
6
6
  "name": "Young Joon Lee",