SynapCores v1.14.5 — Your agent wasn't broken. It never got the event.
The report that started this was four words long: "it stopped firing."
Someone had a durable agent bound to a table:
CREATE AGENT churn_watcher
PERSONA 'analyst'
TASK 'Assess the account and record your finding.'
ON INSERT INTO churn_signals;
It worked when they tested it. It worked the next morning. Then, under real traffic, it started missing rows — not erroring, not logging, not retrying. Just not running.
The measurement
Same agent, same table, same INSERT. The only variable was whether the engine happened to be busy:
| user INSERT lands | binding fires? |
|---|---|
| engine idle | yes — every time |
| during an agent run | no — never |
Not flaky. Deterministic, in the worst possible direction: it worked in testing and failed in production, because testing is quiet and production is not.
Why
An agent's own writes must not re-fire event bindings. Otherwise an agent with write access whose INSERT matches its own trigger becomes an infinite, billable loop. So the engine tags writes made inside an agent run and skips bindings for them. That part is correct and necessary.
The problem was where the tag lived: a single process-wide flag, held for the entire duration of the run.
An agent run is dominated by waiting on a language model. Two seconds against a hosted API. Forty-five to a hundred and eighty seconds on a CPU-only host — which is what Community Edition ships as. For that whole window, every write in the process looked like it came from the agent. Your user's INSERT. Your webhook's INSERT. Everything.
The worse your hardware, the more events you lost. And nothing was logged, because from the engine's point of view nothing had gone wrong — it was doing exactly what it was told.
The fix
Write provenance is now per-task. It follows the statement that actually made the write, across await points and thread migration, and is carried explicitly across the internal boundary where the database spawns its write work.
The old process-global is still there, deliberately, as a backstop for any path that loses the marker. That asymmetry is the whole safety argument: a user write mistaken for the agent's only misses a firing, and you can re-run it. An agent write mistaken for a user's re-fires the agent's own binding, and that bills you until you notice.
Verified by running the same test against both binaries on live gateways, with the in-flight window confirmed open on both sides of the commit:
v1.14.4 (before) idle 2/2 fired in-flight 0/2 SUPPRESSED
v1.14.5 (after) idle 2/2 fired in-flight 2/2 BOTH fired
There is also a new runaway guard: more than 120 event fires per agent per minute are refused and reported. Far above anything the runtime can actually process — it exists to bound the damage if provenance is ever wrong on some path nobody has walked yet.
Three more, from the same family
Everything else in this release shares one property: it reported success while being wrong.
Recipes wrote to storage nobody could read. Recipe execution ran against the master handle with no tenant, while ordinary queries used the tenant's own container. Different trees. A recipe would create tables, report success, and those tables were invisible from the SQL console and the SDKs — so the recipe looked like it had done nothing. On multi-tenant deployments it was also an isolation hole.
Reloading any page froze the interface. A spinner, no error, and reloading only restarted the wait. The startup call that validates your session used the API client's defaults — a ten-minute timeout with three retries — so a gateway that was merely busy held the entire UI hostage for up to half an hour. Now it gives up after eight seconds and sends you to the login page, which at least is somewhere you can act.
The recipe editor opened blank. It was reading the recipe body from a listing endpoint that omits it, while the endpoint that returns it sat unused a few lines away.
And one error message
AI functions not supported in sync evaluation
That sentence names an internal component, never says which part of your query is at
fault, and offers nothing to do about it. The actual rule is small: an AI function can't go
directly in ORDER BY, because sort keys are computed somewhere that can't reach a model.
-- ✗ fails
SELECT id FROM t ORDER BY COSINE_SIMILARITY(a, b) DESC;
-- ✓ works: project it, sort by the alias
SELECT id, COSINE_SIMILARITY(a, b) AS score FROM t ORDER BY score DESC;
It now says exactly that. Worth fixing because of who reads it: an agent handed the failing
form re-issues the identical query, trips the loop guard, and its run ends stalled — which
looks like a bad model and isn't.
Upgrade
curl -fsSL https://get.synapcores.com | sh
docker pull synapcores/community:v1.14.5-ce
Drop-in. No migration, no configuration change.
Two things to know. Fresh installs seed 162 recipes rather than 164 — three agent recipes were pulled pending manual certification and will land on the recipe site shortly; existing installs are untouched. And six catalog recipes still fail certification, all of them pre-existing and unchanged from v1.14.4.
If you have been running agents on CPU-only hardware and quietly assumed the model was the problem, this is the release to take.