fix(delivery): preserve exact identity pairs in check-inbox - #721
Open
suiren wants to merge 1 commit into
Open
Conversation
suiren
force-pushed
the
fix/check-inbox-exact-identity-pairs
branch
from
August 16, 2026 08:53
d937e54 to
e837f05
Compare
check-inbox.sh derived its delivery targets from whoami.sh's human-readable output, which flattens the exact (team, agent) rows into independent agents= and teams= lists. With multiple identities the hook then polled the first agent against every team — including (team, agent) pairs that were never registered — and marked their inboxes read. Consume identities.sh's team/agent TSV directly instead: keep the existing first-agent policy, but subscribe only to that agent's actual team rows, so no cross-product pair is ever queried or marked read. The whoami.sh path also resolved the invocation path to the registered project root before the lookup; keep that by calling agmsg_resolve_project first — identities.sh itself is an exact registry lookup by design. Empty or malformed identity output delivers nothing, matching the previous not_joined/suggest behavior. Regressions: with (alpha, alice) and (beta, bob) registered for the same project and type, only (alpha, alice) is displayed and marked read — the nonexistent cross pairs and the second agent's row stay unread. A nested-subdirectory invocation still resolves to the registered project root and delivers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
suiren
force-pushed
the
fix/check-inbox-exact-identity-pairs
branch
from
August 16, 2026 10:41
e837f05 to
3643e3d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Derive
check-inbox.sh's delivery targets fromidentities.sh's exact(team, agent)rows instead ofwhoami.sh's flattened human-readableoutput, so the Stop hook never polls — or marks read — a
(team, agent)pair that was never registered.
Problem
identities.shreturns the registered pairs asteam<TAB>agentrows:whoami.shflattens those rows into independent lists for itshuman-readable output:
check-inbox.shparsed that output, taking the first agent andevery team. With multiple identities registered for the same
(project, type) it therefore polled the cross product — here
(alpha, alice)and(beta, alice)— although(beta, alice)wasnever registered. Any message row matching such a phantom pair is
displayed to the wrong session and marked read, so its actual
addressee never sees it.
Change
Consume
identities.sh's TSV directly:agent's actual team rows — no cross-product pair is ever queried or
marked read.
internally:
agmsg_resolve_projectruns before the lookup, sinceidentities.shitself is an exact registry lookup by design (itsother callers depend on that). Without it, a session started from a
nested subdirectory or a sibling worktree would silently stop
receiving messages.
previous
not_joined/suggestbehavior.Unchanged: the cooldown marker stays keyed by the selected agent, the
per-pair actas exclusivity check still runs inside the team loop, and
the #653 loop-failure capture (
CLAIM_RC) is untouched.The empty-array expansion in the dedup loop is guarded with the
${arr[@]+...}idiom already used inresolve-project.sh, since thescript runs under
set -uand macOS CI runs bash 3.2.Test plan
Two regression tests in
tests/test_inbox.bats:(alpha, alice)and(beta, bob)registered for the sameproject and type, only
(alpha, alice)is displayed and markedread; both cross pairs and the second agent's row stay unread.
Reverting the fix turns it red: the old parser polls
(beta, alice)and falsely marks it read.nested subdirectory still resolves to the root and delivers —
guarding the resolution step, which no existing test exercised at
the check-inbox call site.
Honest status: the suite is expected to run in this repo's PR CI; it
was not executed locally on our side (Windows dev machine, as with
#613).
Note for integration/remote
The same flatten-and-cross-product block exists unchanged on
integration/remote(the storage rework there did not touch theidentity derivation), so this fix will want a small port when that
branch lands on main. Both regression tests should carry over as-is.
🤖 Generated with Claude Code