The Postgres E2E for fan-out surfaced two real bugs that the unit-stub
tests + PGLite tests couldn't catch:
1) **CRITICAL** — dispatchPerSource passed `maxWaiting: 1` to every
per-source queue.add. maxWaiting is per-(name, queue) — since all
per-source jobs share `name='autopilot-cycle'`, the second + third +
Nth source's submit silently coalesced into the FIRST source's
waiting job. Net result on a real worker: 1 job processed per tick,
not N. The entire fan-out feature was a silent no-op past the first
source.
Per-source idempotency_key (`autopilot-cycle:<source_id>:<slot>`)
already handles "two ticks for same source within slot" dedup, which
is the only thing maxWaiting was buying us. Dropping it fixes fan-out
without losing dedup.
New unit-stub regression test asserts maxWaiting is NOT in the per-
source submit opts so a future refactor that re-adds it gets caught
in 100x faster CI (test/autopilot-fanout.test.ts).
2) **postgres-engine.ts:updateSourceConfig** — initial impl used
sql.json() correctly but my mid-debug rewrite to executeRaw +
positional `$1::jsonb` produced JSONB STRING shape (not OBJECT)
because postgres-js double-encodes JS string params in unsafe mode.
`||` between JSONB object + JSONB string yields a JSONB ARRAY,
wiping every existing config key on update.
Same latent bug class exists at src/commands/sources.ts:482 (gbrain
sources federate/unfederate path); flagged for follow-up but
out-of-scope here.
Reverted to sql.json() inside the template tag (verified via direct
psql round-trip: jsonb_typeof = 'object'). Updated the e2e seed
helper to use sql.json() too — the executeRaw + JSON.stringify
pattern was producing string-shape JSONB at SEED time which made
the failure cascade harder to debug.
Coverage adds:
- test/e2e/list-all-sources-postgres.test.ts: 11 cases pin Postgres
parity for listAllSources + updateSourceConfig including jsonb_typeof
round-trip
- test/e2e/autopilot-fanout-postgres.test.ts: 6 cases end-to-end
including 3-source fan-out producing 3 distinct rows, idempotency
coalesce within slot, cap honored, legacy fallback path
- test/autopilot-fanout.test.ts: +1 regression guard on maxWaiting
This is the kind of bug that justifies the user's "fill test gaps then
run E2E" mandate. The unit tests + PGLite parity tests + typecheck all
passed cleanly; only the real-Postgres E2E found the coalesce.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>