Skip to content

fix(dashboard): terminate SSE response heads immediately with ': open' comment frames - #57

Merged
webdevtodayjason merged 1 commit into
mainfrom
fix/w6-sse-open-comment
Jun 11, 2026
Merged

fix(dashboard): terminate SSE response heads immediately with ': open' comment frames#57
webdevtodayjason merged 1 commit into
mainfrom
fix/w6-sse-open-comment

Conversation

@webdevtodayjason

Copy link
Copy Markdown
Owner

W6 row ① fix-at-source (closet #428). Bun finalizes a streaming Response head only when the first chunk enqueues; frame-less-at-open SSE routes left their heads unterminated on the wire (spec-compliant clients wait — root-caused by w6-proxy, W6-A). Immediate : open comment frames in ReadableStream start() on the three lazy-headed routes (update/events + two audit/stream routes found in the same sweep). Complements the v4 proxy's SSE head grace (merge 9091a6c) — defense at both layers.

Orchestrator-verified: dashboard suite 196/0 in clean worktree; live bare-curl proof on both ports follows post-deploy.

🤖 Generated with Claude Code

…pen' comment frame

W6 row ① fix-at-source (v3 side; w6-proxy root-caused the proxy
symptom). Bun only finalizes a streaming response's head when the FIRST
chunk enqueues. /api/update/events enqueued nothing on open unless the
event buffer had content, so an idle stream's head sat unterminated on
the wire until the 15s keep-alive — bare curl hung, browsers
direct-to-v3 waited 15s for EventSource open, and the v4 reverse-proxy's
hyper client (correctly) refused to forward an unfinished head.

Enqueue an SSE-legal comment frame (': open\n\n', invisible to
EventSource) as the first chunk in start(). Swept every other
ReadableStream SSE route in server.ts for the same lazy-head shape and
fixed the three that had it conditionally:

- /api/logs/<id>/stream — snapshot enqueues immediately ONLY when the
  log file reads cleanly; missing/rotated file left the head hanging
  until append or the 25s keep-alive.
- /api/audit/<team>/stream — first enqueue was async (.then) AND gated
  on j.ok; empty/missing audit log hung the head until the 25s
  keep-alive.
- /api/auth/openai-codex/<alias>/events — a fresh auth session has an
  empty replay buffer; head hung until the first auth event or 15s
  keep-alive.

Verified NOT lazy (no change): master /events (components/evy/server.ts)
writes a 'connected' event synchronously in start() — the W4 evidence
holds. The two /api/master/* SSE passthroughs forward an upstream body,
so their head timing is the upstream's.

No test added: dashboard/server.ts starts Bun.serve + the
notify-listener at module top level, so the suite can't import it
cheaply, and a comment frame doesn't justify new harness machinery.

Proof (scratch server :18790, scratch HOME + SUBCTL_CONFIG_DIR, bare
curl with NO Accept header): HTTP 200 + ': open' frame,
time_starttransfer=0.000639s (was: hung to the 15s keep-alive / curl -m
timeout). Gate: bun test dashboard/__tests__/ — 196 pass / 0 fail.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@webdevtodayjason
webdevtodayjason merged commit e628dc0 into main Jun 11, 2026
@webdevtodayjason
webdevtodayjason deleted the fix/w6-sse-open-comment branch June 11, 2026 22:17
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