Low (observability) · 2026-06-25 review backlog · scale to hobby (console.warn/console.error with context — no APM needed). Detail: docs/reports/2026-06-25-root/.
Bundle of cheap, mostly one-line logging fixes that make the hard-to-diagnose networked failures visible:
reliability-002 + observability-002 — rate-limit fail-open (_shared/mod.ts:90-93) logs a bare string; a chronically-degraded limiter silently disables all per-IP limiting. → structured rate_limit: fail-open log with {bucket, ip, error} (optional circuit-breaker after N consecutive errors).
observability-003 — submit_action 409 seq-conflict path emits no log; a conflict flood is invisible. → info-level log with roomId + anonymized playerId.
observability-007 — edge console.error calls omit the in-scope roomId/playerId, so one broken room can't be isolated. → thread roomId into the error logs.
secrets-001 — 9/10 functions log the full Supabase error object (Postgres internals) instead of error.message (the correct pattern already at _shared/mod.ts:91). → log error?.message. (Same lines as observability-003/007 — do together.)
observability-006 — the "Not your turn" rejection is explicitly excluded from logging though it's the canonical local-vs-referee desync signature. → console.warn with {roomId, localActivePlayerId}, no user surface.
observability-008 — no diagnostic when pendingActions buffers behind a missing seq (Realtime gap). → warn when the buffer exceeds a small threshold / a gap persists, logging expected seq + buffered keys.
Acceptance
- Fail-open events, 409 conflicts, and "Not your turn" rejections each emit a distinguishable, room-correlated log line.
- Edge functions log
error.message (not the full object) and include roomId where in scope.
Low (observability) · 2026-06-25 review backlog · scale to hobby (
console.warn/console.errorwith context — no APM needed). Detail:docs/reports/2026-06-25-root/.Bundle of cheap, mostly one-line logging fixes that make the hard-to-diagnose networked failures visible:
reliability-002+observability-002— rate-limit fail-open (_shared/mod.ts:90-93) logs a bare string; a chronically-degraded limiter silently disables all per-IP limiting. → structuredrate_limit: fail-openlog with{bucket, ip, error}(optional circuit-breaker after N consecutive errors).observability-003—submit_action409 seq-conflict path emits no log; a conflict flood is invisible. → info-level log withroomId+ anonymizedplayerId.observability-007— edgeconsole.errorcalls omit the in-scoperoomId/playerId, so one broken room can't be isolated. → threadroomIdinto the error logs.secrets-001— 9/10 functions log the full Supabase error object (Postgres internals) instead oferror.message(the correct pattern already at_shared/mod.ts:91). → logerror?.message. (Same lines asobservability-003/007— do together.)observability-006— the "Not your turn" rejection is explicitly excluded from logging though it's the canonical local-vs-referee desync signature. →console.warnwith{roomId, localActivePlayerId}, no user surface.observability-008— no diagnostic whenpendingActionsbuffers behind a missing seq (Realtime gap). → warn when the buffer exceeds a small threshold / a gap persists, logging expected seq + buffered keys.Acceptance
error.message(not the full object) and includeroomIdwhere in scope.