Skip to content

fix(T699): one liveness answer for agents, roster and send receipts - #375

Merged
kryptobaseddev merged 2 commits into
mainfrom
fix/t699-one-liveness
Oct 18, 2026
Merged

kryptobaseddev merged 2 commits into
mainfrom
fix/t699-one-liveness

Conversation

@kryptobaseddev

Copy link
Copy Markdown
Owner

OpenCode b4ece3c (base 65f9040, v0.5.48). agentmbx agents used the session-row predicate (liveAgents) and called a released lease whose provider still runs "live". mbx_agents and send receipts used the lease and called it "offline". Both were wrong for a T659/T688 wake target.

  • New src/liveness.ts composes identityAvailability, the live session row and the serve kind into one answer. A released lease whose session still runs reads idle with a reason naming the service or standalone serve and its pid (no schema change).
  • src/opencode-poller.ts: exported batched wakeBindingsByAgent. serveBindingLive and pollerWakeTargets are unchanged, so http.ts keeps its standalone-only meaning.
  • identity-status, receipts (idle → live-next-prompt, or live-wake when a wake path is proven and policy allows) and roster (prints the reason for idle/unknown rows) all use it.
  • The cli agents case prints state plus a trailing reason column. liveAgents() is removed; sessionAgents() (the */role audience) is untouched. Shell senders stay live ("shell sender, last seen N min ago").

New test/liveness-agreement.test.ts covers held, released+service, released+standalone-poller, released+dead and unknown: every surface returns the same token and reason. 235 tests across 24 related files green, tsc clean, no dist drift. CHANGELOG Unreleased only.

Limitation: a standalone poller registration lives in the daemon, so from an MCP/CLI process wakeable is false there (the receipt says live-next-prompt) while the token and reason match.

🤖 Generated with Claude Code

`agentmbx agents` read the session binding (liveAgents) while `mbx_agents`
and the send receipt read the identity lease. When OpenCode evicted an idle
MCP, the lease was released while the serve kept the session row alive, so
the CLI showed "live" and the receipt showed "offline (released)" for hours.

Liveness is now one answer (src/liveness.ts) composed from the lease, the
live session row and the serve kind:
- a released or expired lease whose session still runs is `idle` with its
  reason (claimable; wakeable when the T688 shared service or a registered
  T659 poller can start its next turn, which re-claims the mailbox);
- the reason text uses only evidence every process can read, so all three
  surfaces agree;
- `agentmbx agents` prints the shared state plus a trailing reason column and
  keeps shell senders visible as live;
- mbx_agents/mbx_identity list follow through listIdentityStatus, and the
  receipt reports live-next-prompt/live-wake instead of offline;
- the 30-minute lease idle TTL and the receipt's 3-minute heartbeat rule are
  unchanged.

Adds test/liveness-agreement.test.ts covering held, released+service,
released+standalone-poller, released+dead and unknown evidence.

Checks: tsc --noEmit, npm run build (dist committed), identity-status,
roster, opencode-poll-liveness, project-mailbox, liveness-activity,
opencode-poller-wake, recipient-truth, agents-directory, chosen-identity,
identity-cleanup, doctor-identities, delivery-guidance, cli-lease,
mcp-leases, hooks, doctor-sessions, stranded, codex-activity, wake-dispatch,
wake-contract, wake-project-mail, mcp-connection, mcp-lifecycle,
cli-identity-handover.
sessionRowLive reads the real process table, so the fixture's fabricated low
pid could be alive (EPERM) on CI. An expired holder whose session row still
names a live process is legitimately idle under T699, so the row kept its task
and lane and the T497 assertion failed with "idle" instead of "offline".
Point the session binding at a reaped pid so the fixture is offline on every
host. Test-only; no product change.

Checks: roster.test.ts (9/9 with liveness-agreement), identity-status,
agents-directory, tsc --noEmit.
@kryptobaseddev
kryptobaseddev merged commit 8306015 into main Oct 18, 2026
1 check passed
@kryptobaseddev
kryptobaseddev deleted the fix/t699-one-liveness branch October 18, 2026 00:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant