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.

  1. The SQL must parse as exactly one statement. If it does not parse, it is refused.
  2. The statement must be a read.
  3. 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 plain DELETE, and a DELETE … RETURNING nested inside a WITH. 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.
Book a demo