Tool

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.

Works with dbtgithubsqlitepostgresmysql

90
Spark score
out of 100
Updated 15 days ago
Version 0.1.1
Models
universal

Add to Favorites

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

01

Detect fan-out joins that silently multiply revenue or counts before aggregation

02

Flag non-additive measures (rates, averages, balances) being incorrectly summed

03

Identify sensitive PHI/PII columns exposed in query output

04

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

CI
PyPI
License: Apache-2.0
Python

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-line
meta 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.json or schema.yml - the tests teams
    already wrote become enforceable semantics, zero config

  • Plain PK/FK declarations (works today - powered the benchmark audits)

  • The live database itself (works today): no semantic layer at all?
    sqlsure.introspect builds the rulebook from the catalog - SQLite
    PRAGMAs or information_schema PK/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 edges
    
  • Hand-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, relationship
    joinType + condition → join edges, cube measures → additivity

  • Cube, Snowflake Semantic Views - adapters on the roadmap; the
    engine only ever sees one SemanticModel

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

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.