Skip to content

fix: make two processes sharing one mailbox visible (#161) - #173

Merged
yonidavidson merged 1 commit into
mainfrom
fix/161-mailbox-leases
Aug 9, 2026
Merged

yonidavidson merged 1 commit into
mainfrom
fix/161-mailbox-leases

Conversation

@yonidavidson

Copy link
Copy Markdown
Owner

Closes #161. (Supersedes #169, auto-closed by GitHub when its base branch merged; same commit, rebased onto main.)

A subagent inherits its parent's git identity and process tree, so it derives the parent's alias — and because reads consume, one agentcomm inbox from a subagent drains the mailbox its parent is waiting on. Silently, because the alias looks right.

The one suggestion not taken, and why

The issue proposes deriving the alias from something per-process (pid, spawn nonce). That would break the model deliberately: a session is a mailbox, and the sticky per-session fingerprint is exactly what fixed alias drift in #157 — making the name per-process would re-split every mailbox the moment a wrapper process appears. What was actually missing is visibility, which is the issue's own second and third suggestions.

What changed

  • src/session.ts — mailbox leases. While a process acts as an alias it leaves lease-<alias>-<pid>.json in the state dir; a lease whose pid is dead (or older than 30 min) is ignored and removed, never inherited. Local files, because two processes of one agent session on one machine is exactly the local case.
  • src/cli.tsguardMailbox classifies each command: a consuming read (inbox, ack) warns that it is taking mail addressed to a live holder, names what that process is doing, and gives the remedy (--as <alias>-<role>); a status write warns whose roster line it replaces; heartbeats, peek, wait and claim lease quietlywait because holding the mailbox is the whole point of a listener, claim because a shared queue is meant to have many claimers.
  • The guidance file written into repos now says a subagent derives the same alias as its parent.

Tests

test/mailbox-lease.e2e.test.ts: a real second process holds the alias while a consuming read runs (warns, with the remedy), a solo read stays silent and cleans up its lease, a status write reports whose line it takes while a heartbeat does not, and a dead process's lease is ignored and removed.

A subagent inherits its parent's git identity and process tree, so it
derives the parent's alias. Because reads consume, one `agentcomm inbox`
from a subagent drains the mailbox its parent is waiting on — silently,
since the alias looks exactly right. One did; it noticed only because the
CLI echoed the parent's name and the agent recognised it. The smaller
version of the same thing: a subagent's `register --status` overwrote the
parent's line on the shared roster.

Identity stays per-session on purpose — a session IS a mailbox, and the
sticky fingerprint that fixed alias drift depends on it. What was missing
is visibility, so while a process acts as an alias it now leaves a local
lease behind, and anything destructive another live process does to that
mailbox says so: a consuming read warns that it is taking mail addressed
to a live holder and names the remedy (--as <alias>-<role>), and a status
write warns whose line it is replacing. Heartbeats, peeks and queue claims
lease quietly — a shared queue is meant to have many claimers.

Leases are local files, because the case they cover — two processes of one
agent session on one machine — is exactly the local case. A lease from a
dead process is ignored and cleaned up, never inherited.
@yonidavidson
yonidavidson merged commit 27a22db into main Aug 9, 2026
2 checks passed
@yonidavidson
yonidavidson deleted the fix/161-mailbox-leases branch August 9, 2026 08:21
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.

Subagents silently inherit the parent's alias: they drain its inbox and overwrite its status

1 participant