SynapCores v1.14.4 — Every one of these bugs passed its own health check
An operator wrote in with a query that was returning too much:
SELECT * FROM telemetry_events
WHERE received_at > '2026-08-18'
AND event_type = 'installation_created'
Forty rows came back. Ten were correct. No error, no warning — just a wider result set
than the query had asked for. And here is the part that made it genuinely nasty:
COUNT(*) over the identical WHERE clause returned 10. Adding ORDER BY also
returned 10. Only SELECT * was wrong.
That inconsistency is the whole shape of this release. Ten bugs, and not one of them produced a stack trace.
What was happening
The index-scan operator splits a WHERE clause into the conjuncts an index can answer
and the ones it cannot. On the index-hit path it looked up matching row ids, fetched
each row, and handed them to the caller — never evaluating the leftovers.
ORDER BY appeared to fix it because a sort makes the optimizer emit
TableScan → Filter instead, and Filter evaluates the whole conjunction. COUNT(*)
was right for the same reason. So every cross-check an engineer would reach for to
confirm the bug quietly disagreed with it.
Both fallback paths — index empty, index not yet populated — chained the predicates correctly and had been audited a release earlier. The success path never was. The failure mode of a correctness audit is that it stops at the first path that looks right.
Why the index fix ships in the same release
While reproducing that bug, a second one surfaced: CREATE INDEX never reached disk.
Index definitions lived in memory for the life of the process. Every restart discarded
them and silently reverted the instance to full table scans. Answers stayed correct —
a table scan answers the same question — so the only symptom was an index that quietly
stopped working, while CREATE INDEX kept reporting success and SHOW INDEXES never
listed secondary indexes at all.
Everything needed to recover already existed: a persistent catalog that writes definitions to disk, and a boot path that reads them back and rebuilds. It was a complete read path with no writer.
The two bugs are entangled. The residual-predicate bug only bites when an index is live in memory — so restarts kept wiping the evidence, which is why it was so hard to reproduce. Fixing durability makes the wrong-results bug more likely to fire. They had to ship together, and that is worth saying out loud rather than burying in a changelog.
The one that broke first-run
The installer wrote this into every gateway.toml:
[query]
default_timeout_ms = 30000
The engine's own default is 300000 — raised deliberately, years ago, because AI work
runs through the same query path as OLTP SQL. So an install that followed our documented
path got a stricter timeout than an install with no config file at all.
On a CPU-only host a cold GENERATE() takes about 53 seconds. Every LLM-backed
statement — GENERATE, AGENT_RUN, NL2SQL — failed with Operation timeout on a fresh
install. Our own SQL manual had been publishing default_timeout_ms = 300000 the entire
time. The installer contradicted our documentation, and only a canary that boots with
the documented operator config would ever have caught it.
Six in the interface
The same theme, in the browser:
- A
Vector Searchpage in the navigation was a placeholder reading "will be implemented here" — while vector search has shipped for a year asCOSINE_SIMILARITY(EMBED(a), EMBED(b)). Removed; the capability was never missing. - The Agents tab crashed the entire Settings page — on an empty database, because a list
endpoint returns
{"agents": []}and the client expected a bare array. - Modals rendered white text on a white background. The shared component defaulted to a light panel and only went dark if a caller opted in. Three did. A dozen did not.
- The Settings page announced "Native in-process vision is active" whenever no external provider was configured — which is every fresh install, and a fresh install pulls the embedding and chat models only. It now reports whether a vision model actually exists.
- The streaming page showed zero streams while streams were running.
- In-app PDF preview was blocked by our own Content-Security-Policy, in every browser. It was reported as a Safari problem; Safari was just the one that said so out loud.
What we checked before shipping
| Gate | Result |
|---|---|
| Feature validator, against the published artifact | 187 / 187 |
| Recipe certification, pristine data directory | 162 / 162 |
| AVX-512 audit | 2,018 uses, all in a runtime-dispatched hash, none in inference |
| Non-AVX-512 canary (i5-10400F) | boot 3s · EMBED 384 dims · GENERATE OK · zero SIGILL |
One methodological note, because it nearly bit us. The first validator run against the published binary reported two failures. Both were client-side timeouts, not assertion failures — and the cause was that an earlier abandoned request had left inference running server-side, saturating the engine. A client disconnect does not cancel work already in flight. The result on a quiet box, single engine, one run: 187 of 187.
We report the clean number, and we mention the dirty one, because a benchmark taken on a loaded machine is not a benchmark.
Upgrading
Drop-in. No migration, no schema change, no config change.
Two notes for existing installs:
- If your
gateway.tomlcame from an older installer, raise[query] default_timeout_msto300000. New installs get it automatically. - Secondary indexes are durable now. Any index created before this release was never persisted and will not reappear — recreate it once, and it stays.
docker pull synapcores/community:latest