Skip to content

fix: mail to an app connected through Reason reads as queued, not delivered - #163

Open
svemyh wants to merge 1 commit into
mainfrom
fix/through-reason-queued
Open

svemyh wants to merge 1 commit into
mainfrom
fix/through-reason-queued

Conversation

@svemyh

@svemyh svemyh commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Problem

A coding agent (or a person with reason-network send) messaging an app connected through Reason (a hosted Grok Bot / Muse / ChatGPT connection whose mail Reason keeps until it calls check_inbox) is told delivered: the session was waiting for messages. The app hasn't seen it: the wait that made it "delivered" is the Reason CLI's relay (cli/ask-relay.ts read(), 300 s waits), which only hands the mail to Reason's inbox for the app. The app sees it at its next check_inbox, or when its wake webhook starts it.

Reason's own send_message already corrects this for senders that go through Reason (reason-machines/monorepo#29173), but the engine says delivered to everyone talking to it directly: the reason network CLI and agents on the engine's own MCP tools, on this machine or a teammate's (a remote send's receipt is this deliver()'s answer on the recipient's machine).

Where on main: src/daemon/mail.rs deliver(), the g.polling.get(key) branch (line 318 before this change) returns delivered for any open wait.

Change

  • HookCall gets through_reason (serde default false, skipped when false). The Reason CLI's relay sends it on its hooks for the sessions it carries (companion monorepo PR). Older clients leave it out; older engines ignore the field (no deny_unknown_fields).
  • The daemon keeps it on the live session (sticky), keeps such a session at tier pull (hooks no longer raise it to turn/push by agent kind), and deliver() answers queued with Reason's wording before any channel or wait check:
    queued: this agent is connected through Reason and only sees it the next time it calls check_inbox (or its wake webhook starts it); it hasn't read it yet
  • DESIGN.md's delivery table gets a row for it.

Guarantees

  • Delivery itself is unchanged: the mail is stored unread and arrived still wakes the relay's wait, which reads and hands it over as before (verified below). Only the receipt and the shown tier change.
  • Sessions without the flag are untouched, including real agents waiting in check_inbox (still delivered).
  • No wire identifiers in net.rs / team.rs / invite.rs change. The new field rides the local socket only.

Verification (run)

  • cargo test: 254 + 2 passed. cargo clippy --all-targets: no warnings. cargo fmt --check: clean.
  • Ran the built daemon in a throwaway REASON_NETWORK_HOME and drove its socket: a grok session registered by hooks holds a 10 s inbox wait, a second session sends to it.
    • With through_reason: true: receipt queued + the note above; the wait still got the message; who tier pull.
    • Without (today's relay): receipt delivered: the session was waiting for messages; tier turn.

Callers / rollout

  • Companion: monorepo cli/ask-relay.ts passes throughReason: true to AgentNetwork.session(), which adds through_reason to its hooks. It is harmless on 0.12.13.
  • Reaches customers when this is released (0.12.14), published with scripts/publish-network-engine.ts, and the CLI's ENGINE_VERSION / digests pin moves to it, plus a CLI release carrying the relay flag. For remote senders the recipient's machine must run both.

Uncertainty

  • since for these sessions is still the relay's registration time on the engine; Reason's list_team fixes it server side, the engine has no record of the app's last check_inbox.
  • Not exercised against a live relay + real hosted app end to end.

🤖 Generated with Claude Code

…ivered

The Reason CLI's relay holds check_inbox waits on a hosted assistant's session
only to hand its mail to Reason's inbox; the assistant sees it at its next
check_inbox there. The relay now marks those sessions through_reason on its
hooks, and deliver() answers queued with Reason's own send_message note,
and list_team shows them pull.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Sven Myhre <sven@mac.lan>
@cursor

cursor Bot commented Oct 27, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@larstalian

Copy link
Copy Markdown
Member

Review of f240799 (independent, full suite): changes needed, mostly because main moved.

  1. It doesn't build on current main (0.12.17). feat: measure network usage without changing encrypted peer delivery #174 already added through_reason: Option<bool> to HookCall (src/proto.rs:61) and Live (src/daemon/mod.rs:175). This PR adds a second field with that name as a bool, so the merged tree fails with 20 errors. GitHub shows it as mergeable only because the text merges cleanly. The rebase should reuse main's field.
  2. A hazard in that rebase. Main sets through_reason: Some(true) for every Reason session registered without a connection (sessions.rs:134), and those are delivered by reason session send (mail.rs:510). If the early queued return moves onto == Some(true), mail to Reason sessions is never sent, and the resend in reason.rs:162 hits the same return. The check has to apply only to the relay's sessions (the flag as reported by hooks, or agent != "reason").
  3. No test for the new behaviour. Please add a unit test for: the queued reply while the relay is waiting; the tier staying pull across later hooks; and the message still reaching the relay's wait.
  4. Minor: re-registering the same session can still raise its tier (sessions.rs:104; not reachable with today's relay), and FYI mail to these apps now gets the "through Reason" note instead of "queued as FYI".

Compatibility looked good on the head: a 0.12.13 daemon ignores the flag and still replies delivered, and the head daemon without the flag behaves like 0.12.13. One note for the squash: the commits carry a Co-Authored-By trailer and the sven@mac.lan author email.

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.

2 participants