feat(F-139): completed feature
This commit is contained in:
14
work/artifacts/F-139/architect.md
Normal file
14
work/artifacts/F-139/architect.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# F-139 — Architect (bug fix)
|
||||
|
||||
## Bug
|
||||
Admin `/admin/logs/stream` SSE connection drops with `ERR_NETWORK_IO_SUSPENDED`.
|
||||
|
||||
## Root causes
|
||||
1. **Proxy** (`apps/admin/src/app/api/[...path]/route.ts`): did not set `X-Accel-Buffering: no`, which causes intermediate proxies (nginx) to buffer the SSE stream and kill it.
|
||||
2. **Client** (`ServerLogViewer.tsx`): `connect()` goes to `reconnecting` status on drop but never actually reconnects — no retry loop.
|
||||
3. **`LogBroadcaster.stream()`**: dead code — never used by the SSE route (uses `registerClient()` instead).
|
||||
|
||||
## Fixes
|
||||
1. Proxy: add `X-Accel-Buffering: no` header; remove explicit `Connection: keep-alive` (default for HTTP/1.1).
|
||||
2. Client: add exponential backoff reconnection loop (1s → 2s → 4s … max 30s).
|
||||
3. Backend SSE endpoint already correct with proper headers.
|
||||
4
work/artifacts/F-139/documenter.md
Normal file
4
work/artifacts/F-139/documenter.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# F-139 — Documenter evidence
|
||||
|
||||
## Scope of documentation change
|
||||
Bug fix (ERR_NETWORK_IO_SUSPENDED). No new features; no user-facing changes beyond improved reliability. No docs update needed.
|
||||
20
work/artifacts/F-139/implementer.md
Normal file
20
work/artifacts/F-139/implementer.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# F-139 — Implementer evidence
|
||||
|
||||
## What
|
||||
F-139 build evidence: fixed SSE streaming bug. tsc 0, verify.sh verde.
|
||||
|
||||
## Files
|
||||
- `apps/admin/src/app/api/[...path]/route.ts` — proxy adds `X-Accel-Buffering: no`, uses `Headers` API, removes `Connection: keep-alive`.
|
||||
- `apps/admin/src/components/ServerLogViewer.tsx` — added exponential backoff reconnection loop (1s → 2s → 4s … max 30s); calls `reader.cancel()` on abort; resets backoff on success.
|
||||
|
||||
## Verification
|
||||
- `npm run build` → 0 TypeScript errors.
|
||||
- `check-module-boundaries.mjs src` → 0 NEW violations.
|
||||
- `./scripts/verify.sh` → green (F-139 in_progress, runtime-consistent).
|
||||
|
||||
## Root causes fixed
|
||||
| Cause | Fix |
|
||||
|-------|-----|
|
||||
| Proxy missing `X-Accel-Buffering: no` | Added header to proxy SSE response |
|
||||
| Client never reconnects | Exponential backoff retry loop in `connect()` |
|
||||
| Dead `LogBroadcaster.stream()` | No-op — never used by SSE endpoint |
|
||||
12
work/artifacts/F-139/leader-close.json
Normal file
12
work/artifacts/F-139/leader-close.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"feature_id": "F-139",
|
||||
"agent": "leader",
|
||||
"stage": "close",
|
||||
"verdict": "APPROVED",
|
||||
"summary": "F-139 closed: SSE streaming bug fixed (proxy X-Accel-Buffering header + client exponential backoff reconnection). tsc 0, verify.sh green.",
|
||||
"checks": [
|
||||
{"item": "Gates approved", "ok": true, "evidence": "reviewer.json, security.json, qa.json -> APPROVED"},
|
||||
{"item": "verify.sh", "ok": true, "evidence": "exit 0"}
|
||||
],
|
||||
"issues": []
|
||||
}
|
||||
12
work/artifacts/F-139/qa.json
Normal file
12
work/artifacts/F-139/qa.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"feature_id": "F-139",
|
||||
"agent": "qa",
|
||||
"stage": "qa_gate",
|
||||
"verdict": "APPROVED",
|
||||
"summary": "tsc 0, verify.sh green. No regressions.",
|
||||
"checks": [
|
||||
{"item": "tsc 0", "ok": true, "evidence": "npm run build 0 errors"},
|
||||
{"item": "verify.sh", "ok": true, "evidence": "exit 0"}
|
||||
],
|
||||
"issues": []
|
||||
}
|
||||
14
work/artifacts/F-139/reviewer.json
Normal file
14
work/artifacts/F-139/reviewer.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"feature_id": "F-139",
|
||||
"agent": "reviewer",
|
||||
"stage": "review_gate",
|
||||
"verdict": "APPROVED",
|
||||
"summary": "SSE streaming bug fixed: proxy adds X-Accel-Buffering: no; client reconnects with exponential backoff (1s→30s). Backend headers already correct.",
|
||||
"checks": [
|
||||
{"item": "Proxy X-Accel-Buffering header", "ok": true, "evidence": "apps/admin/src/app/api/[...path]/route.ts sets header for SSE path"},
|
||||
{"item": "Client reconnection loop", "ok": true, "evidence": "ServerLogViewer.tsx connect() with scheduleRetry() + exponential backoff; MAX_DELAY=30s; reset on success"},
|
||||
{"item": "No Connection: keep-alive", "ok": true, "evidence": "Explicit Connection header removed from proxy"},
|
||||
{"item": "tsc/verify", "ok": true, "evidence": "npm run build 0 errors; verify.sh green"}
|
||||
],
|
||||
"issues": []
|
||||
}
|
||||
12
work/artifacts/F-139/security.json
Normal file
12
work/artifacts/F-139/security.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"feature_id": "F-139",
|
||||
"agent": "security",
|
||||
"stage": "security_gate",
|
||||
"verdict": "APPROVED",
|
||||
"summary": "Bug fix: no new auth, no new routes, no secrets. SSE proxy headers only. Client reconnection is client-side only.",
|
||||
"checks": [
|
||||
{"item": "No new auth", "ok": true, "evidence": "Same auth flow as before; proxy does not modify credentials"},
|
||||
{"item": "No new secrets", "ok": true, "evidence": "No new env vars or credentials"}
|
||||
],
|
||||
"issues": []
|
||||
}
|
||||
Reference in New Issue
Block a user