Read-only X-ray of an SSRS estate or a SQL Server database. It finds the reports that duplicate each other, the ones that compute the same metric differently, what breaks if something is removed, and what is safe to cut. Every finding cites the report, dataset and query lines it came from.
Status: all milestones in
docs/SPEC.mdare built and tested against a synthetic estate. It has not yet been run against a real SSRS instance or a live LLM; treat results from a first real engagement as a pilot.
One run writes four files to xray-out/<run-id>/:
| File | For |
|---|---|
report.html |
The client. One self-contained file (no external calls) with contradictions, duplicate clusters, risks, the decision list, a catalog, Power BI Service readiness, and the method and limits. Citations link to the exact lines of code. |
review.html |
You. The same report plus every AI claim that failed verification, with the reason. Don't send it. |
decisions.csv |
Working through it with the client: keep, consolidate, retire or review for every report and procedure, each with a reason and a blank column for notes. |
xray.json |
Everything, for re-rendering or other tools. Schema: schema/xray.schema.json. |
- SSRS mode starts from the ReportServer catalog and follows each report into its queries and stored procedures.
- Database mode starts from a SQL Server database and documents the procedures, views and functions that reports, Agent jobs and applications depend on.
- Read-only logins:
db_datareaderon ReportServer,CONNECTandVIEW DEFINITIONon source databases. The tool checks its own permissions and refuses to run with write rights. - Never selects encrypted credentials or business rows; reads metadata, definitions and logs only. Plain-text passwords found in definitions are masked before they are stored.
- Works offline: clients who won't grant access run a read-only export script and hand over the bundle.
- AI is opt-in per engagement. When used, server names, database names, literals and email addresses are redacted before anything leaves the machine, and every sentence is checked against the code it cites. Unverifiable sentences never reach the client report.
uv sync
uv run sql-xray fixture --out demo/fx
cp demo/fx/xray.toml demo/
uv run sql-xray run --root demo --from-bundle demo/fx/bundle --code-dir demo/fx/app --no-aiThat builds a fictional distributor's estate (62 reports, 40 procedures, planted duplicates, contradictions and risks; demo/fx/answer_key.json lists them all), analyzes it, and writes the report in a couple of seconds. Open demo/xray-out/<run-id>/report.html.
To add AI explanations, set enabled = true under [ai] in demo/xray.toml, set AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_API_KEY, AZURE_OPENAI_DEPLOYMENT and AZURE_OPENAI_MODEL in your environment, and run again without --no-ai (add --budget-usd 2 to cap spend).
uv run sql-xray init # xray.toml + workspace
uv run sql-xray extract --server SSRS01 --source-db sales=SQL01/Distributor # live, Windows auth
uv run sql-xray extract --procs-only --source-db sales=SQL01/Distributor # or database mode
uv run sql-xray bundle-script --out xray-export # or: a package the client runs
uv run sql-xray extract --from-bundle xray-bundle-20261011.zip # and what they send back
uv run sql-xray extract --code-dir ../client-app # application callers
uv run sql-xray analyze # all deterministic analysis
uv run sql-xray explain --budget-usd 5 # AI explanations (opt in)
uv run sql-xray verify # re-check every claim
uv run sql-xray report # html, json, csv
uv run sql-xray purge # delete the workspace at the endAfter the first extract, map each data source to a source database alias under [datasources] in xray.toml; extract lists the ones still unmapped.
Apache 2.0. See LICENSE.