Validate AI-generated SQL for semantic correctness
sqlsure catches semantically wrong SQL - fan-out double counting, averaged rates, exposed PII - deterministically in 0.1ms, before it runs.
Why it matters
Ensure AI-generated SQL queries are semantically correct before execution by catching silent logic errors-double-counted joins, improperly summed averages, exposed sensitive data-that databases and linters miss, preventing wrong results from reaching production.
Outcomes
What it gets done
Detect fan-out joins that silently multiply revenue or counts before aggregation
Flag non-additive measures (rates, averages, balances) being incorrectly summed
Identify sensitive PHI/PII columns exposed in query output
Generate machine-actionable fixes that AI agents apply to self-repair failed queries
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/sqlsure-sqlsure | bash Overview
Sqlsure
sqlsure deterministically checks SQL for semantic errors that run without error but return silently wrong numbers - fan-out double counting, summed averages, exposed PII - by judging queries against a semantic model built from dbt tests, PK/FK declarations, or database introspection, in about 0.1ms with no LLM calls. Use it as a CI gate, MCP server, or library check on any AI-generated or text-to-SQL query before execution or merge; it parses query text only and never connects to a database, so it needs a declared or introspectable semantic model to check against.
What it does
sqlsure catches SQL that is perfectly valid, runs without error, and returns a number that is silently wrong - revenue double-counted by a join, an average summed instead of weighted, a patient identifier exposed - the kind of bug that databases, linters, and an LLM reviewing its own SQL all miss. sqlsure catches it deterministically, in about 0.1ms, before the query runs, by judging SQL against facts a team has already declared: dbt unique tests become grain, relationships tests become join cardinality, and one-line meta tags mark what's safe to sum. There's no new modeling language to learn and no model to maintain by hand - the rules are dictionary lookups against a SemanticModel, not LLM calls, so the same SQL and the same rulebook always produce the same verdict, offline.
Nine rules ship in v0.1: FANOUT (SUM/COUNT of an additive measure after a one-to-many join), CHASM (two or more fan-out joins multiplying each other), ADDITIVITY (summing a non-additive measure like a rate or average), SEMI_ADDITIVE (balances or censuses summed across their snapshot dimension), JOIN_KEY (a join on columns matching no declared relationship), and CROSS_JOIN (a join with no predicate) as errors; WEIGHTED_AVG (an AVG silently re-weighted by fan-out) and UNDECLARED_JOIN (a join with no declared relationship - unverifiable, not assumed safe) as warnings; and SENSITIVE_COLUMN (a PHI/PII column exposed in output) as a policy flag. When sqlsure can't verify something against the declared model, it reports "can't verify," never "looks fine" - honest uncertainty is treated as a feature, not a gap to paper over.
Every rejection carries a machine-actionable fix, so an AI agent can self-repair in a draft-check-fix-check-execute loop; the source reports that applying the suggested fix verbatim produced a passing query 10 out of 10 times in its benchmark. Run over the gold-answer sets of the two benchmarks text-to-SQL models are graded on (Spider and BIRD), sqlsure flagged 45 issues across 2,568 expert-written queries with zero false alarms - including one BIRD dev gold answer provably wrong by 8x from exactly the bug class sqlsure targets, and a schema defect now filed upstream against the benchmark itself.
When to use - and when NOT to
Use sqlsure wherever SQL is generated by an AI agent or a text-to-SQL product and needs a deterministic semantic check before execution or merge - as a CI gate blocking a PR that double-counts, as an MCP server an agent must pass inspection through before running a query, or embedded as a library (check()) inside a text-to-SQL product or agent framework, including drop-in wrappers for Vanna/WrenAI-style generators. It's also useful standalone, auditing an entire dbt repo for latent semantic risk (python -m sqlsure.scan path/to/dbt-repo --report report.md).
It is not a data-access or execution-correctness tool: it parses query text only, never connects to a database, and it validates semantics against a declared model rather than checking whether a query is syntactically valid or returns the "right" row count. It also depends on having (or being able to introspect) a semantic model - dbt tests, PK/FK declarations, or a live database catalog - so a schema with no declared relationships and no introspectable catalog gives it nothing to check against beyond the rules that don't require declared joins.
Inputs and outputs
Install and check a query against a semantic model:
pip install sqlsure
from sqlsure import SemanticModel, check
violations = check(sql, model) # [] means semantically safe
Input is a SQL query plus a SemanticModel, sourced from dbt's manifest.json/schema.yml (works today, zero extra config), plain PK/FK declarations, hand-written JSON (model.example.json), a live database's own catalog via sqlsure.introspect (model_from_sqlite() for SQLite PRAGMAs, or information_schema for Postgres/MySQL), or OSI/WrenAI MDL loaders. Output is a list of violations (empty means semantically safe), each carrying a rule name, severity (error, warning, or policy), and a machine-actionable fix suggestion. The CLI (python -m sqlsure.cli --model model.json query.sql) exits 1 on violations for CI gating, and python -m sqlsure.scan produces a Markdown audit report across a whole dbt repository.
Integrations
sqlsure runs as a CI gate, an MCP server (claude mcp add sqlsure -- python -m sqlsure.mcp_server --model /abs/path/model.json) that an AI agent must pass before executing a query, a Python library for embedding check() inside any text-to-SQL product, or a standalone Agent Skill (a single SKILL.md an agent can load directly with no server process). It reads semantic models from dbt, plain PK/FK declarations, live database introspection (SQLite, Postgres, MySQL), hand-written JSON, and working loaders for the OSI spec and WrenAI's MDL format; Cube and Snowflake Semantic Views adapters are on the roadmap. Documented integration points include a GitHub Action, pre-commit hook, Snowflake UDF / Cortex Agent tool, and query-history audit.
Who it's for
Teams building or operating AI agents and text-to-SQL products who need a deterministic, offline check that a generated query is semantically correct - not just syntactically valid - before it runs or merges, especially where a wrong-but-plausible number (double-counted revenue, an improperly averaged rate, an exposed PII column) would be a real business or compliance risk that no linter or self-review by the generating LLM would catch. It is licensed under Apache-2.0.
Source README
sqlsure
AI writes your SQL. sqlsure makes sure it's right.
A query can be perfectly valid, run without error, and return a number
that's silently wrong - revenue double-counted by a join, an average
summed, a patient identifier exposed. Databases don't catch this.
Linters don't catch this. LLMs reviewing their own SQL don't catch this.
sqlsure does - deterministically, in 0.1 ms, before the query runs.
Proof, not promises: we ran sqlsure over the gold answers of the two
benchmarks every text-to-SQL model is graded on. 2,568 expert-written
queries, 45 flags, zero false alarms - including a BIRD dev gold answer
that is provably wrong by 8× from the exact
bug class sqlsure targets, and a schema defect
now filed upstream.
How it works
sqlsure judges SQL against facts your team already declared - dbt unique
tests become grain, relationships tests become join cardinality, one-linemeta tags mark what's safe to sum. No new language to learn, no model to
maintain by hand. Rules are dictionary lookups, not LLM calls: same input,
same verdict, every time, offline.
Every rejection carries a machine-actionable fix, so AI agents
self-repair: draft → check → fix → check → execute. In our benchmark,
applying the fix verbatim produced a passing query 10/10 times.
Quick start
pip install sqlsure
from sqlsure import SemanticModel, check
violations = check(sql, model) # [] means semantically safe
Or clone and run the 30-second demo:
python check.py # 5 wrong queries rejected, 1 approved — with fixes
python -m sqlsure.scan path/to/dbt-repo --report report.md # audit any dbt repo
Three doors, one engine
1. CI gate - blocks the merge when a PR double-counts:
python -m sqlsure.cli --model model.json query.sql # exit 1 on violations
2. MCP server - your AI agent must pass inspection before executing:
claude mcp add sqlsure -- python -m sqlsure.mcp_server --model /abs/path/model.json
See docs/MCP.md for tool reference and agent-loop patterns.
3. Library - embed check() inside any text-to-SQL product or agent
framework. A drop-in SemanticGate wraps
Vanna/WrenAI-style generators; a
semantic eval metric scores NL2SQL output
where execution-accuracy is blind.
Also available as an Agent Skill -
a single SKILL.md your agent loads directly; no server process needed.
The rules (v0.1)
| Rule | Severity | Catches |
|---|---|---|
| FANOUT | error | SUM/COUNT of additive measure after one-to-many join |
| CHASM | error | two+ fan-out joins multiplying each other |
| ADDITIVITY | error | SUM of a non-additive measure (rates, averages) |
| SEMI_ADDITIVE | error | balances/censuses summed across their snapshot dimension |
| JOIN_KEY | error | join on columns matching no declared relationship |
| CROSS_JOIN | error | join with no predicate |
| WEIGHTED_AVG | warning | AVG silently re-weighted by fan-out |
| UNDECLARED_JOIN | warning | join with no declared relationship (unverifiable ≠ safe) |
| SENSITIVE_COLUMN | policy | PHI/PII column exposed in query output |
When sqlsure can't verify something, it says "can't verify" - never "looks
fine." Honest uncertainty is a feature.
Trust properties
- Deterministic - same SQL + same rulebook = same verdict, always;
rules are dictionary lookups, auditable line by line - Offline - zero network calls; your SQL never leaves your machine
- No data access - parses query text; never connects to a database
- No telemetry - nothing collected, ever (SECURITY.md)
- Supply chain - releases ship exclusively via PyPI Trusted Publishing
(OIDC) from tagged commits with public CI runs; two runtime deps
Where the rulebook comes from
dbt (works today):
manifest.jsonorschema.yml- the tests teams
already wrote become enforceable semantics, zero configPlain PK/FK declarations (works today - powered the benchmark audits)
The live database itself (works today): no semantic layer at all?
sqlsure.introspectbuilds the rulebook from the catalog - SQLite
PRAGMAs orinformation_schemaPK/FK (postgres/mysql). Introspecting
BIRD's own database files recovered 2 foreign keys missing from the
benchmark's published schema
(bird-bench/mini_dev#37)from sqlsure.introspect import model_from_sqlite model = model_from_sqlite("app.db") # PK -> grain, FK -> join edgesHand-written JSON - model.example.json
OSI and WrenAI MDL (working loaders in
integrations/): OSI
demonstrated on the spec's published examples;
WrenAI MDL demonstrated on WrenAI's own
shipped example manifest -primaryKey→ grain, relationshipjoinType+condition→ join edges, cube measures → additivityCube, Snowflake Semantic Views - adapters on the roadmap; the
engine only ever sees oneSemanticModel
Validated on
- 16/16 rule tests, 100% recall / 0% false positives on the paired
benchmark (docs/METRICS.md) - Real production repos (Mattermost's warehouse, Fivetran packages,
dbt's jaffle shop) - docs/TEST-REPORTS.md - Spider + BIRD gold queries - the zero-noise external audit above
Learn more
- docs/EVIDENCE.md - what it does for you, every
claim linked to a rerunnable measurement - docs/ARCHITECTURE.md - how it physically works,
ELI5 → god level, with real intermediate outputs - docs/FOR-DUMMIES.md - every concept from zero
- docs/INTEGRATIONS.md - GitHub Action, pre-commit,
MCP, Snowflake UDF / Cortex Agent tool, query-history audit - docs/MCP.md - MCP server documentation
- CONTRIBUTING.md - adding rules and loaders
Apache-2.0 · sqlsure.ai
mcp-name: io.github.sqlsure/sqlsure
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.