Dia · Oct 17, 2026
Three hidden writes, three refusals
Every query Dia's chat writes must be a single read. Code refuses anything that writes, even a DELETE hidden inside a larger query. Each query also runs in a read-only transaction that is always rolled back. 75 automated cases cover the rest.
- Hidden write commands blocked in the test (stacked, direct, nested)
- 3 of 3
- Dia pull request #104
- The same commands blocked on a live database
- 3 of 3
- Dia pull request #104
- Automated cases in the gate's test suite
- 75
- Dia backend, test_sql_safety_gate.py
The problem
Telling an AI to "only read" is a request, not a control. The SQL it writes can still delete data, or hide a change inside a larger query.
Method
The check has three layers. All of them are code, outside the AI's reach.
- The SQL must parse as exactly one statement. If it does not parse, it is refused.
- The statement must be a read.
- Nothing in the parsed query may insert, update, delete, merge, create, drop, alter or truncate. That includes nested sub-queries (common table expressions).
The query then runs in a read-only transaction, where the database supports one. The transaction is always rolled back.
Data
A temporary SQLite database for the unit test. A live database on our own servers for the end-to-end check, with every write guarded by WHERE false so nothing could change.
Results
- The test allows one SELECT and refuses three hidden writes:
SELECT 1; DROP TABLE …, a plainDELETE, and aDELETE … RETURNINGnested inside aWITH. It then confirms the table is unchanged. - The same three writes were refused through the live chat.
- The gate's own suite has 75 automated cases, and the test suites touched by the change (47 tests in four files) pass.