A director asks the analytics assistant which properties had the most maintenance jobs last quarter. The model writes a query, the database answers, the director gets a table. Useful. But somewhere in that exchange the model also held a live connection to the production database — the same database that stores leases, complaints, contractor jobs and resident records. The interesting question is not whether the assistant answered well. It is what would have happened if a malformed prompt, an injected instruction or a confident hallucination had produced an UPDATE or a DELETE instead of a SELECT.
The usual answer is "we told it not to." We instructed the model to only read, listed the tables it may touch, and reviewed the prompt. That is a control made of words, and words are exactly what a language model is good at ignoring. On a property operations system we built, we took a different position: the database itself should refuse to be written to during analytics, regardless of what the model produces. Read-only by construction, not read-only by instruction.
Key takeaways
- A system prompt telling the model to only read is guidance a prompt-injection payload can override; a database transaction physically incapable of writing is the control the model cannot argue with.
- PostgreSQL's
transaction_read_only = onmakes the engine reject any INSERT, UPDATE or DELETE at execution; it is enforced by the engine, fails closed, and is legible to an auditor in under a minute. - Read-only is one control among several and should sit alongside a least-privilege role, a statement timeout, parameterised inputs and tenant isolation — not the whole of database security.
- A 0.6 confidence gate on image verification stops the model acting on a guess, with deterministic code, not the model's self-assurance, deciding what counts as certain.
- A £200 cost-approval gate routes any job over the threshold to a named human, so the AI cannot commit money on its own and you can show who approved what and when.
The control that matters is the one the model cannot talk its way past
There is a hierarchy of controls, and it is worth being honest about where each one sits.
- A system prompt that says "you are a read-only analytics assistant" is guidance. The model usually complies. It is not a guarantee, and a prompt-injection payload in the underlying data can override it.
- A query allow-list or a parser that inspects generated SQL is stronger, but you are now in an arms race with every syntax variant, comment trick and nested statement the model might emit.
- A database transaction that is physically incapable of writing is the one a model cannot argue with. If the engine rejects the write, the model's intent is irrelevant.
We want the load-bearing control to be the last kind. The first two are still worth having — defence in depth — but they are not the thing you stake the board's risk appetite on.
This is the difference between responsible AI in principle and responsible AI you can demonstrate in a code review. When a non-executive director asks "could your AI change our records?", the defensible answer is not "it is instructed not to." It is "the database connection it uses cannot, and here is the function that enforces it."
A Postgres read-only transaction makes the database refuse the write
PostgreSQL has a session setting, transaction_read_only. When it is on, the engine rejects any statement that would write data — INSERT, UPDATE, DELETE, CREATE, and so on — at the point of execution, before anything reaches a table. It is part of Postgres's documented client connection defaults, not a bolt-on.
On the property system, the analytics path runs every model-generated query inside a database function that sets the transaction to read-only first. The model can compose whatever it likes. If what it composed is a write, Postgres raises an error and the transaction aborts. No row changes. The model never had the capability in the first place; it only ever had a window to look through.
Three properties make this worth doing rather than merely relying on connection-level permissions:
- It is enforced by the engine, not the application. The guarantee does not depend on our middleware being bug-free. It depends on Postgres behaving the way Postgres is documented to behave.
- It fails closed. The default state of the transaction is the safe state. A code path that forgets to do something does not silently grant write access; the absence of a write is the natural outcome.
- It is legible to an auditor. You can point to the function, show the setting, and a reviewer who has never seen our codebase can understand the guarantee in under a minute. That legibility is itself a governance asset.
One honest caveat, because precision matters more than reassurance here: read-only at the transaction layer is one control among several. It should sit alongside a least-privilege database role, a short statement timeout to stop runaway queries, parameterised inputs, and tenant isolation. We treat read-only-by-construction as the floor that catches the catastrophic case — the model writing to data it should only read — not as the whole of database security.
Reading data is not the same as acting on it — so two more gates sit above the model
Read-only protects the database. It does nothing about the two other ways an AI system causes harm: acting on a low-quality interpretation, and acting on a decision that should have been a human's. The same property build addresses both with controls that, again, do not depend on the model choosing to behave.
A confidence gate stops the model acting on a guess
The inspection layer of the system turns room-check photographs into structured maintenance or customer-service jobs. A model looking at a photo can be wrong — a shadow read as damp, a scuff read as damage. So image verification carries a 0.6 confidence threshold: below it, the result does not flow through as a confident finding. The deterministic code, not the model's self-assurance, decides what counts as certain enough to act on.
The reasoning here is the same as the read-only one. We do not ask the model to be honest about its own uncertainty and trust the answer. We set the bar in code and let the code enforce it. We have written separately about why a confidence floor and reason codes should be allowed to overrule the model; the property system applies the same discipline to vision.
A cost-approval gate keeps a human on the financial decisions
The system coordinates contractors and maintenance, which means it brushes up against spending. The rule in code is plain: any job whose cost crosses a £200 landlord-approval threshold is escalated to a named human rather than progressed automatically, and residents never see cost figures at all. Refunds and discounts are governed by database-backed policy the model cannot rewrite. The AI assists; a person decides; and because the gate is in the data model, you can show who approved what and when.
This is the human-in-the-loop principle expressed as a control rather than a slogan. The model does not get to decide it is confident enough to commit money. The threshold is a number in the code, and crossing it routes the decision to someone accountable.
How the three controls divide the work
Each gate answers a different question, and none of them relies on the model's cooperation.
| Control | What it prevents | Where it is enforced | What it does not do |
|---|---|---|---|
Read-only transaction (transaction_read_only = on) |
The AI writing to data it should only read | PostgreSQL engine | Replace least-privilege roles, timeouts or tenant isolation |
| Confidence gate (0.6 on image verification) | Acting on a low-quality interpretation | Application code, deterministically | Improve the model; it filters output, not reasoning |
| Cost-approval gate (£200 threshold) | The AI committing money without a person | Data model + routing logic | Remove the human; it routes to a named decision-maker |
The pattern across all three: the governance lives below the model, in places the model cannot reach. That is what we mean by engineered in, not bolted on.
Why this matters to a board, not just an engineer
UK organisations are not governed by a single AI statute. Governance is principles-based and regulator-led, built on the government's five pro-innovation principles — safety, transparency, fairness, accountability and contestability — applied through existing regulators. Two of those principles, safety/security/robustness and accountability, are precisely what a read-only transaction and a human approval gate let you evidence.
Where personal data is involved, the binding regime is already here: UK GDPR and the Data Protection Act 2018, with the Information Commissioner's Office as lead regulator. Article 5's integrity-and-confidentiality and accuracy principles are easier to defend when the AI demonstrably cannot mutate records and demonstrably stops below a confidence floor. The ICO's updated guidance on automated decision-making is, as of late May 2026, draft — its consultation closed on 29 May 2026 with final guidance expected in summer 2026 — but the direction is clear: where a decision is significant, a person must be able to review and contest it. A £200 gate that routes to a named human is that requirement made concrete. For the framework most often used to formalise this, see our explainer on what ISO/IEC 42001 requires of a board, and why your AI risk register should be living evidence rather than a static document.
The general point: a control written in code and enforced by infrastructure is evidence. A control written in a policy and trusted to the model is an intention. Auditors, regulators and a careful board can tell the difference.
Build the guarantee where the model cannot reach it
If you take one thing from the property build, take this: decide which failure would be catastrophic, then move the control for it below the model — into the database engine, the type system, the routing logic — so the model's behaviour becomes irrelevant to whether the guarantee holds. Read-only by construction is the clearest example, because the database does the enforcing and you do not have to trust anything you cannot inspect.
Last reviewed: 29 May 2026.
If you are putting an AI assistant near production data and want the read-only guarantee to be structural rather than instructional, we are happy to talk through how we build it. You can also see how we build these controls into the systems we ship.



