SynapCores v1.14.2 — Your agent worked on run 1 and quietly stopped by run 10
The worst kind of bug isn't the one that crashes. It's the one that keeps reporting success.
We found this one the honest way: by building a real three-agent compliance pipeline against the shipped image and running it ten times in a row. Run 1 did exactly what it was told — read the deal, check the watchlist, write a ruling into an append-only ledger. By run 10 the agent was answering in prose and writing nothing. Every run still reported status = success.
Agents were being poisoned by their own history
A durable agent replayed a shared, per-tenant conversation transcript into every run. When the engine saved that transcript, it stripped the tool evidence — the calls, the arguments, the results.
So what each new run actually read was a doctored record of its own past: a conversation where the assistant answered questions without ever calling a tool. Small models are excellent few-shot learners. They copied it.
Nothing in the product made this visible. The audit table said success, because the run had completed and produced text.
Durable agents are now stateless by default. Run N is no longer primed by run N-1's phrasing. Working memory is a per-run scratchpad. If you want continuity you opt into memory = 'persistent' — and then tool evidence round-trips faithfully and stays isolated per (agent, subject), so two agents sharing a persona can't teach each other bad habits.
Failure is loud now
The deeper problem was that a broken agent looked identical to a working one. _system_agent_runs now distinguishes them:
SELECT agent_name, exit_reason, tool_calls_made, iterations_used
FROM _system_agent_runs
ORDER BY started_at DESC;
A run that finished without calling a single tool reports completed_no_tools, not success. A model stuck re-issuing the same call reports stalled instead of grinding to the iteration ceiling. _system_agent_transcripts keeps tool_name, tool_args and tool_result per turn, so you can read what actually happened rather than what the summary claims.
Unknown personas are rejected at CREATE AGENT instead of being silently downgraded to a generic prompt. Models that can't call tools are refused at creation rather than failing mysteriously at 3am.
A five-word prompt beat a carefully written one
Personas are first-class objects now — CREATE, ALTER, DROP, SHOW, DESCRIBE PERSONA — and building the pipeline taught us something we didn't expect.
Two personas, identical task, identical model, identical engine. The only variable was the prompt.
| persona | executed the instructed statement |
|---|---|
'You are a compliance reviewer.' |
3 / 3 |
| the conversational default | 0 / 3 |
The conversational one greeted the agent, asked what its name was, offered to help further, and ended the run having done nothing at all. It's a good chat prompt. Attached to an unattended agent it's a liability, because there is no human on the other end to answer "could you let me know your name?"
If you're driving an unattended agent, keep the prompt task-shaped. Tell it to do the work and report the value. That's the whole trick.