SynapCores v1.14.4 — Every one of these bugs passed its own health check

Published on August 21, 2026

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 Search page in the navigation was a placeholder reading "will be implemented here" — while vector search has shipped for a year as COSINE_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.toml came from an older installer, raise [query] default_timeout_ms to 300000. 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