Skip to content

fix(plugin/tether): don't drop replies on async parse; add ask (email-and-wait)#355

Merged
jiashuoz merged 1 commit into
mainfrom
fix/tether-parse-race-and-ask
Jul 1, 2026
Merged

fix(plugin/tether): don't drop replies on async parse; add ask (email-and-wait)#355
jiashuoz merged 1 commit into
mainfrom
fix/tether-parse-race-and-ask

Conversation

@jiashuoz

@jiashuoz jiashuoz commented Jul 1, 2026

Copy link
Copy Markdown
Member

Follow-up to #354, from a live run of the harness.

1. Parse-race reply loss (bug)

e2a parses inbound email asynchronously — a just-arrived reply briefly has empty parsed/body, then populates. The old poll advanced a time-cursor to "now" every call, so a reply caught in that window was skipped permanently (a real emailed question was silently lost in testing).

Fix: dedup by message-id (a seen set in state); the last_poll watermark only advances through the contiguous processed prefix, and an unparsed message is retried (until a max age) rather than skipped. Replies can no longer be dropped or double-delivered.

2. Questions stalled the session (the AFK problem)

An AFK user can't answer a terminal prompt, so any agent-initiated question (AskUserQuestion / bare prompt) would hang tether.

Fix: new tether.sh ask "<question>" — emails the question into the thread and blocks until the user replies, then prints the answer. SKILL.md makes it the rule: while tethered, every question goes over email, never the terminal. For permission prompts (which an emailed reply can't answer natively), the guidance is to pre-authorize the session; the Notification hook stays as the alert/safety-net.

Testing

  • install.sh _selftest green (syntax + unconfigured no-op).
  • Offline stub-curl: unparsed reply is retried not consumed → delivered once when parsed → never repeated (seen=['msg_r1']).
  • Offline ask: sends question, blocks, returns the emailed answer.
  • validate-plugin.mjs: 3 skills, version 0.4.3, manifests in sync.

Bumps plugin to 0.4.3.

🤖 Generated with Claude Code

…il-and-wait)

Two fixes surfaced by a live run:

1. Parse-race reply loss. `poll` advanced a time-cursor to "now" on every call,
   so a reply picked up in the brief window before e2a finished parsing it
   (empty parsed/body) was skipped permanently — a real emailed question was
   lost. Replies are now deduped by message-id (a `seen` set) and the watermark
   only advances through the contiguous processed prefix; an unparsed message is
   retried (up to a max age), never dropped or repeated.

2. Questions stalled the session. An AFK user can't answer a terminal prompt, so
   any agent question would hang tether. New `tether.sh ask "<q>"` emails the
   question into the thread and blocks until the reply, then prints the answer.
   SKILL.md makes it a rule: while tethered, ask by email, never the terminal —
   and documents that CLI permission prompts must be pre-authorized (an emailed
   reply can't answer them; the Notification hook remains the alert).

Bumps plugin to 0.4.3 across all manifests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jiashuoz jiashuoz merged commit 6019fe2 into main Jul 1, 2026
14 checks passed
@jiashuoz jiashuoz deleted the fix/tether-parse-race-and-ask branch July 1, 2026 06:39
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