Skip to content

fix(delivery): preserve exact identity pairs in check-inbox - #721

Open
suiren wants to merge 1 commit into
fujibee:mainfrom
suiren:fix/check-inbox-exact-identity-pairs
Open

fix(delivery): preserve exact identity pairs in check-inbox#721
suiren wants to merge 1 commit into
fujibee:mainfrom
suiren:fix/check-inbox-exact-identity-pairs

Conversation

@suiren

@suiren suiren commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Derive check-inbox.sh's delivery targets from identities.sh's exact
(team, agent) rows instead of whoami.sh's flattened human-readable
output, so the Stop hook never polls — or marks read — a (team, agent)
pair that was never registered.

Problem

identities.sh returns the registered pairs as team<TAB>agent rows:

alpha	alice
beta	bob

whoami.sh flattens those rows into independent lists for its
human-readable output:

multiple=true agents=alice,bob teams=alpha,beta

check-inbox.sh parsed that output, taking the first agent and
every 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) was
never 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:

  • Keep the existing first-agent policy, but accumulate only that
    agent's actual team rows — no cross-product pair is ever queried or
    marked read.
  • Keep the project-root resolution the whoami path performed
    internally: agmsg_resolve_project runs before the lookup, since
    identities.sh itself is an exact registry lookup by design (its
    other callers depend on that). Without it, a session started from a
    nested subdirectory or a sibling worktree would silently stop
    receiving messages.
  • Empty or malformed identity output delivers nothing, matching the
    previous not_joined/suggest behavior.

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 in resolve-project.sh, since the
script runs under set -u and macOS CI runs bash 3.2.

Test plan

Two regression tests in tests/test_inbox.bats:

  1. With (alpha, alice) and (beta, bob) registered for the same
    project and type, only (alpha, alice) is displayed and marked
    read; 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.
  2. With a registration at the project root, an invocation from a
    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 the
identity 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

@suiren
suiren force-pushed the fix/check-inbox-exact-identity-pairs branch from d937e54 to e837f05 Compare August 16, 2026 08:53
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
suiren force-pushed the fix/check-inbox-exact-identity-pairs branch from e837f05 to 3643e3d Compare August 16, 2026 10:41
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