Skip to content

feat(inbound-delivery): inbound-queue loss notices reach the originating topic (F3)#1282

Merged
EchoOfDawn merged 1 commit into
mainfrom
echo/inbound-delivery-sacred
Jun 26, 2026
Merged

feat(inbound-delivery): inbound-queue loss notices reach the originating topic (F3)#1282
EchoOfDawn merged 1 commit into
mainfrom
echo/inbound-delivery-sacred

Conversation

@EchoOfDawn

@EchoOfDawn EchoOfDawn commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

What

The durable inbound holding-queue's loss notices ("I didn't get to your messages") were delivered to a single agent-attention-topic and silently dropped when that was unset — so a held inbound user message could expire AND the user never be told (postmortem Failure 3, the "why aren't you responding?" failure).

This routes each loss notice to the originating topic (every loss item carries its sessionKey = the topic id the user messaged from), on the proven Telegram path; and surfaces loudly (console.error) the one residual case where a loss has no resolvable topic and no attention topic is configured. A lost inbound message is now never silently expired.

Second F-series tooth for the proposed constitutional standant The User Experience Is the Product (sub-standard #3; PR #1280).

Key finding (scoping)

The fix is narrow — a codebase sweep found the queue's loss-detection and the fail-OPEN direct-inject fallback already exist and are comprehensive. The only gap was the loud-failure channel (where the notice gets delivered). So this changes routing, not the queue engine.

Change

  • planInboundLossNotices(items) — pure, unit-tested router (src/core/inboundLossRouting.ts): groups loss items by Number(sessionKey) → per-topic + unresolved.
  • notifyInboundLoss(...) helper in server.ts: per-originating-topic notice + loud fallback for the unroutable case.
  • Applied to all 5 inbound-queue loss sites (boot-sweep ×2, no-mesh-identity, drain-loop ×2). The stuck-recovery notice already routed per-topic — unchanged.

Safety

Inert while the inbound queue is dark (inboundQueueConfig enabled:false, the default) — zero behavior change on the fleet; it hardens the channel for when the queue is live. No new blocking authority (delivery-routing only).

Tests

6 unit tests for the pure router (originating-topic routing, unresolved counting, zero/negative/non-numeric → unresolved, deterministic order); full npm run lint (tsc + ~20 lints) exits 0.

Tier-1 instar-dev (ELI16 + spec + side-effects review; second-pass not-required — no block/allow decision). Side-effects: upgrades/side-effects/inbound-delivery-sacred.md.

🤖 Generated with Claude Code

ELI16

When you send me a message and I can't hand it to a live session right away, it can go into a small durable holding queue so it isn't lost. The queue does its job — but the last step, telling YOU if it ever had to give up on a message, was broken: that "I didn't get to your messages" notice went to one internal channel, and if that channel wasn't set up, the notice was silently dropped. So your message could be lost AND you'd never be told — exactly the "why aren't you responding?" failure.

This makes the notice come back to you, in the actual conversation you sent the message from (every held message remembers which conversation it came from). And for the rare case where a lost message can't be tied to a conversation and there's no fallback channel, instead of dropping it silently I make it loud in my error log. A message you send me either gets through, or you're told it didn't — never silence.

It ships inert (the holding queue is off by default); this hardens the channel for when it's turned on.

@vercel

vercel Bot commented Jun 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
instar Ready Ready Preview, Comment Jun 26, 2026 9:41am

Request Review

…nating topic (F3)

A held inbound message's loss notice ('I didn't get to your messages') went to a
single attention-topic and was SILENTLY DROPPED when that was unset — a lost
message AND a silent user (postmortem Failure 3). Now each loss routes to the
ORIGINATING topic (sessionKey = topic id) on the proven Telegram path; an
unroutable loss with no attention topic surfaces LOUDLY (console.error), never
silent. Pure unit-tested router (planInboundLossNotices) + notifyInboundLoss
applied to all 5 inbound-queue loss sites (stuck-recovery already per-topic).
Inert while the queue is dark. Tier-1 instar-dev. 6 unit tests + full lint green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@EchoOfDawn EchoOfDawn force-pushed the echo/inbound-delivery-sacred branch from 89da28c to 28dd07d Compare June 26, 2026 09:41
@EchoOfDawn EchoOfDawn enabled auto-merge (squash) June 26, 2026 09:42
@EchoOfDawn EchoOfDawn merged commit 5fd9a53 into main Jun 26, 2026
22 checks passed
@EchoOfDawn EchoOfDawn deleted the echo/inbound-delivery-sacred branch June 26, 2026 09:53
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