Collapse three byte-identical response-parsing blocks (getRelay, postRelay,
and the tts error path) into one handleRelayResponse helper. pingBalance is
deliberately left out: it records a relay error even on a parsed envelope,
a different contract from the other three (updateRelayState clears lastError
while recordRelayError sets it), so folding it in would change observable
state.
Collapse the six operator-to-relay calls into operatorPost / operatorGet,
preserving their intentional split: writes (tier grant, invoice, order)
throw on misconfig or non-OK so the operator action surfaces the failure;
reads (tier, plans, expiring subs) return null so the caller falls back to
a default. Per-function signatures, body shapes, error messages, and the
throw-vs-null behavior are unchanged.
Add server/test/relay.test.js (first fetch-mock harness for relay.js):
14 tests covering the tts error-path control flow, handleRelayResponse's
envelope parsing and error-recording rule, and the operator throw-vs-null
contract including the missing-config branch. 158 tests pass.
ROADMAP gains the deferred refactor-survey items (subscription engine,
/api/process pipeline, sweep middleware, transcript coalescers) and notes
the relay-test coverage against the existing known-debt entries.
Phase 2 of the design-contract cleanup:
- 346 inline-style hexes (+7 #475569, mapped by property) -> var(--token),
scoped to CSS-value position so JS-logic/quoted hex, the meta theme-color,
SVG attrs, and the no-:root share-export region stay literal; #fff and
no-token hexes left as-is.
- Snap off-scale font sizes (9/10.5->10, 11.5/12.5->12, 15->16, 24->22) and
radii (3->4, 5->6, 7->6, 11->12, 9->8|10) to the scale.
- Bump to 0.2.161, which also ships the previously-uninstalled 0.2.160
share-page HTML export.
Phase 1 of the design-contract conformance cleanup. Add a canonical
:root token block (single source of truth, mirroring
design/tokens.tokens.json) to public/index.html's stylesheet and migrate
the whole <style> block to var(--token); give public/auth.html its own
subset :root and migrate it too.
Fix all color + weight drift across every surface (stylesheet, inline
styles, JS handlers, the SHARE_PAGE_CSS export):
- legacy indigos #6366f1/#4f46e5/#4338ca + rgba(99,102,241) ->
#818cf8/#a5b4fc/rgba(129,140,248)
- blue #3b82f6 interactive buttons (incl. the whole auth screen) -> indigo
- legacy darks #0a0e17/#0b1120/#020617/#121828/#1f2942 -> the surface ladder
- #f5f9ff -> #f1f5f9, #312e81 -> #1e293b, weights 650->600 / 680->700
The meta theme-color stays a literal #0a0e1a. Verified: 144 tests pass,
both pages serve 200, all var() references resolve. Phase 2 (var-ifying
the long-tail inline styles, snapping off-scale font/radius) is in
ROADMAP.md.
Inventory the as-built recaps.cc look and distill it into a durable,
vendor-neutral design contract: design/DESIGN.md (nine-section brand
brief) + design/tokens.tokens.json (W3C DTCG tokens), plus brand icon
and provenance notes. Canonical calls reconciled with the owner:
indigo #818cf8 as the single interactive accent, purple #a855f7 for
premium only, the #0a0e1a->#111827->#0f172a surface ladder, and a
normalized type scale. Wire the AGENTS.md Design line and record the
contract-vs-code drift as a cleanup backlog in ROADMAP.md.
Triaged from the cross-project inbox. Needs a research pass to confirm
available stable Gemini versions before wiring; flag the server+client
model-list duplication and the matching relay-side capture.
Refresh AGENTS.md conventions (client IP via req.ip; safeFilename exported),
rewrite Current state to a lean snapshot, move the P2 known-debt detail to
ROADMAP.md.
- Arbitrary file write (P0): validate import keys in /api/library/import via
a now-exported safeFilename(); a ../../ key is skipped, not written out of
the scope dir.
- SSRF (P0): guard downloadPodcastAudio — reject non-HTTP(S) schemes, block
IP-literal and DNS-resolved private/link-local/loopback/reserved/multicast
and embedded-IPv4 IPv6 targets (closes DNS rebinding), cap + resolve redirects.
- ESM require (P1): top-level import of randomBytes in license-purchase.js
(the inner require threw on the anon purchase-settle path).
- Concurrency lock (P1): skip the process-global free-tier slot in multi-mode
so it no longer serializes every cloud tenant onto one job.
- X-Forwarded-For bypass (P1): set Express trust proxy from
RECAP_TRUSTED_PROXY_HOPS (default 1); getClientIp now reads req.ip instead
of a client-spoofable XFF entry.
Tests added for safeFilename, the SSRF guard, and getClientIp (119 pass).
Registry blockers deferred (ROADMAP); leaked-key history purge queued.
Defer the low-severity full-eval findings (request caps, invoice-ID claim,
root container, rate-limit buckets, repo hygiene, StartOS polish, bulk doc
reconciliation) for later batching. P0/P1 and P2 live in AGENTS.md.