Diagnose & fix the auto-flow bug #15
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
posta/chat#15
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What to build
The Live updates promise in
CONTEXT.mdis currently broken: inbound messages from a peer do not appear in the open thread without manual page refresh. Diagnose the failure point and fix it.Diagnostic recipe (the audit narrowed the candidates):
/events→ "EventStream" tab.event: thread-updatedframe arrives → server-sidepeerFromInboundDataininternal/web/events.golikely returns""because the upstreaminboundDTO doesn't carrypeerat the top level. Fix the extraction.sse:NAMEtrigger normalization vs. thelive:thread-updatedCustomEvent chain (seelive.js:138-145for the known workaround). Tighten the bridge./c/{peer}refetch.Surgical fix expected. If the diagnostic reveals a larger underlying issue, open follow-up issues rather than expanding scope here.
Acceptance criteria
Blocked by
None - can start immediately
Agent Brief
Category: bug
Summary: Inbound messages from peers do not appear in the open thread without manual refresh; the Live updates promise (CONTEXT.md) is broken end-to-end.
Current behavior:
When a peer sends a message and the user has the corresponding thread open, the new bubble does not appear in the DOM until the user manually refreshes. The sidebar's unread badge and last-message preview are similarly stale.
Desired behavior:
The Live updates promise from
CONTEXT.md § Live updates: within ~1s of the inbound event reaching chat.posta.no, the open thread shows the new bubble and the sidebar reflects the unread count + last-message preview, on every browser tab the user has open.Reproduction during triage already narrowed the failure surface:
Go-side tests for the translation layer pass with the canonical posta-server DTO
{"peer":"...","rowId":N,"direction":"in"}. Specifically the inbound → (contact-changed+thread-updated) translation and the peer extraction helper both behave correctly when fed contract-shaped input. Failure mode 1 — server-side peer extraction returning empty — is ruled out for the documented DTO shape.Two failure surfaces remain:
event: thread-updatedarrives on the wire but the DOM does not update. Suspect: htmx-1.9'ssse:NAMEnormalization interacts poorly with the bridge'slive:thread-updatedCustomEvent dispatch path. The bridge already has a workaround for this (rawEventSource.addEventListener), but the wiring may have a timing or rebind gap (e.g. the<main>swap replaces the element and the new element'shx-trigger="live:thread-updated from:this"does not get processed in time).Diagnostic order for the agent:
inboundframe from a real posta-server stream — confirm the actual DTO shape matches the test contract. If it doesn't, the bug is failure mode 1 after all and the fix is in the upstream-event-shape extraction.event: thread-updatedlands. If yes → mode 2. If no → mode 1 disguised by a non-contract upstream shape; treat as case 1.thread-updatedreceived → peer parsed → peer-match? → CustomEvent dispatched → htmx triggered → fetch issued → swap completed). Find the first step that doesn't fire./c/{peer}fragment refetch must see the new row. If it doesn't, that's a posta-server read-after-write race; the right fix is a small bounded retry on the fragment fetch.Key interfaces:
Live updates protocoltable inCONTEXT.mdis the authoritative wire mapping; do not duplicate it in code comments (see related issue on doc-comment cleanup).live.js. If the fix involves splitting the bridge into pure functions, that's the scope of a separate issue — not this one.Acceptance criteria:
Out of scope: