IntentSQL
Plain-English data access with an inspectable plan and guarded writes
- Role
- Sole developer: I did the design, implementation, testing and documentation
- Status
- Open source · public alpha
- Stack
- Python · FastAPI · SQLite · Jev decision model · Docker
00 · Summary
Ask a SQLite database a question in plain English, then inspect exactly how the answer was built: each semantic decision, the typed plan, the SQL and its bound parameters. Inserts, updates and deletes are previewed on an isolated copy and need explicit confirmation.
01 · The problem
When a model writes SQL directly, its failures are hard to see. A fluent query can quietly drop a filter, invent a column or touch rows nobody meant to change. To trust it with anything beyond a demo, a team needs to know why each query was produced, and writes must be impossible without review.
02 · The idea
Treat the model as a source of small, bounded judgments rather than as the author of the query. Code inspects the database and offers only real candidates: tables, columns, relationships, values and legal operations. A decision model (TypeSafe’s Jev) chooses among them, and each choice narrows the next decision. Ordinary code compiles the SQL.
03 · How it works
- 01
Inspect
Schema, relationships and values become the candidate space.
- 02
Decide
Bounded choices, yes/no and score judgments update a typed state.
- 03
Compile
Deterministic SQL with bound parameters and structural checks.
- 04
Review
Whole-request coverage checks, then targeted repair or refusal.
- 05
Execute
Reads run. Writes are previewed, vetted and confirmed, then committed with undo.
03b · A replay
Three kinds of request, step by step: the model picks from options the code has already checked, the code verifies the choice, and the result runs, waits for approval or is refused.
-
01 Request
“Which five districts spend the most per pupil?”
-
02 Valid options
- districts.name
- schools.enrollment
- finances.per_pupil
- finances.total_budget
-
03 AI choice
choice · order by
finances.per_pupil DESC
p = 0.94 -
04 Code checks
- schema: columns exist
- limit 5 ← goal “five”
- policy: read-only
-
05 Result
Executed
SELECT … LIMIT ? → 5 rows
04 · The hard part
Knowing when to say no
A wrong answer that looks right is worse than a refusal. Unsupported shapes, such as per-group ranking or multi-hop joins, are refused before any partial query runs. Refusals are counted separately from correct answers, so the benchmark cannot flatter the system.
05 · What I built
- FastAPI application and UI exposing the exact questions, answers, probabilities, typed plan, SQL, parameters and token usage
- Write path with isolated-copy preview, a 100-change cap that includes cascades and trigger effects, transactional commit and guarded undo
- Import of any SQLite database as a working copy; originals are never modified
- Benchmark harnesses against an internal corpus and a frozen subset of the Spider dataset
- Docker image and Python install paths for Linux, macOS and Windows
06 · Results
- 30/40 on a frozen, originally unseen Spider subset, checked on execution and typed plan. 5 of the other 10 were safe refusals. Not an official Spider score, and recorded before later safety fixes.
- 80/80 on the internal development corpus in one recorded run, including 19 expected rejections.
- 379 offline tests recorded at the final pre-release check.
Known limits
A local, single-user alpha. Not every phrasing is supported, and probabilistic coverage does not prove an interpretation correct. The documentation says this plainly, and the interface is built around inspecting results.
07 · Why it matters
This is the pattern most teams need when they put AI in front of real data: the model contributes judgment, code keeps control of what actually executes, and every step can be audited afterwards.