Evidence-gated scrape-to-artifact harness: artifacts you can defend
Project description
sprawll
Research artifacts you can defend.
Every AI research tool can write you a report.
sprawll is the one that refuses to publish a claim it can't pin to an archived source.
Highlights
- 🧾 Evidence-gated output — only claims that survive span-level verification against archived sources ship; everything else is withheld, never silently included
- 📦 Byte-for-byte archives — every source captured as WARC, with canonical snapshots every claim offset points into
- 🔢 Deterministic numeric guard — every figure in a claim must literally exist in a cited source
- 🔒 Local-first — prefers a local Ollama model; sources and drafts never leave your machine
- 💸 Hard budget cap — API fallback is checked against a dollar ceiling before every call
- 🔁 Replayable — re-verify any run from its archive with zero network access
Quick start
$ pip install sprawll
$ sprawll research-pack "solar e-bike charging on university campuses" \
-u https://example.edu/solar-project \
-u https://example.org/cycling-economy
What you get back:
| Artifact | What it is |
|---|---|
report.md |
Only claims that survived verification, each cited; single-source claims flagged |
diagnostics.md |
Every claim that failed, with the exact unsupported span named |
corpus.warc.gz |
The sources as they existed when fetched, byte-for-byte |
snapshots/ |
The canonical extracted text every claim offset points into |
[!NOTE] The promise is precise: defensible against this archived corpus, retrieved on these dates. Not "true". Nobody can honestly sell you "true"; we can sell you "checkable".
How it verifies
Source-first pipeline:
fetch → archive (WARC) → extract → harvest facts → draft (only from harvested facts) → ground → render
The grounding gate has two layers:
- Span model (LettuceDetect, MIT) — checks every claim against source text, chunked with tracked offsets
- Numeric guard (deterministic) — every figure in a claim must literally exist in a cited source. Catches the hedged wrong numbers models gloss over
Publication is binary: supported claims ship, everything else goes to diagnostics. Claims one source supports and another contradicts publish as supported but contested. If the span model is unavailable, the LLM-judge fallback brands the whole report DEGRADED.
Local-first
sprawll prefers a local LLM. If Ollama is running, your sources and drafts never leave your machine:
$ ollama pull qwen3:14b # ~9 GB, fits a 12 GB GPU
API keys (ANTHROPIC_API_KEY / OPENAI_API_KEY) are the fallback, capped by a hard dollar ceiling (SPRAWLL_BUDGET_USD, default $2 — checked before every call). Pin explicitly:
$ export SPRAWLL_LLM=ollama/qwen3:14b
$ export SPRAWLL_LLM=litellm/anthropic/claude-sonnet-5
No LLM at all? sprawll refuses to draft undefended text — sprawll audit still grounds claims you wrote yourself.
Replay and audit
$ sprawll research-pack --from-archive runs/<run-dir> # re-verify, no network
$ sprawll audit claims.json snapshots/ # just the grounding gate
Failed sources are taxonomized (fetch_failed, robots_blocked, paywalled, timeout, extract_empty) and shown in the report's source table — a source that couldn't be archived is a fact about the corpus, not a rounding error.
Install notes
[!TIP] Core is pure-Python pip. Fetching uses crawl4ai (real browser) when installed —
pip install sprawll[crawl]thenplaywright install chromium— and falls back to plain HTTP (marked DEGRADED in fetch notes) when not.
- First grounding run downloads the LettuceDetect weights (~1.5 GB).
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sprawll-0.0.2.tar.gz.
File metadata
- Download URL: sprawll-0.0.2.tar.gz
- Upload date:
- Size: 25.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
949dbca187bcd01d23c38c8b8d1cb1b0981a73046b81a45e87ebeea5b0583b67
|
|
| MD5 |
b9148def057f5332d327336e1afe2630
|
|
| BLAKE2b-256 |
ee6c99ac2d5de6ebbb679cdf32e19fe8fa6f471234ad896e9a5d1f015280a099
|
Provenance
The following attestation bundles were made for sprawll-0.0.2.tar.gz:
Publisher:
publish.yml on Wasif-ZA/sprawll
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sprawll-0.0.2.tar.gz -
Subject digest:
949dbca187bcd01d23c38c8b8d1cb1b0981a73046b81a45e87ebeea5b0583b67 - Sigstore transparency entry: 2160834721
- Sigstore integration time:
-
Permalink:
Wasif-ZA/sprawll@e68a894f5a84aaff103f60e5d4df3de7f71c099c -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/Wasif-ZA
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e68a894f5a84aaff103f60e5d4df3de7f71c099c -
Trigger Event:
push
-
Statement type:
File details
Details for the file sprawll-0.0.2-py3-none-any.whl.
File metadata
- Download URL: sprawll-0.0.2-py3-none-any.whl
- Upload date:
- Size: 20.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a3ce5c23ae1325818794e6581b2a0be4a43ee970f1ad83d664b92659954ac900
|
|
| MD5 |
b896e4ef8201fd4c3dc2349cdc4e693a
|
|
| BLAKE2b-256 |
5440d76c6ec5076fc0219d4d4fdd05566c0e5926744c17708af0ec908b8739c5
|
Provenance
The following attestation bundles were made for sprawll-0.0.2-py3-none-any.whl:
Publisher:
publish.yml on Wasif-ZA/sprawll
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sprawll-0.0.2-py3-none-any.whl -
Subject digest:
a3ce5c23ae1325818794e6581b2a0be4a43ee970f1ad83d664b92659954ac900 - Sigstore transparency entry: 2160835068
- Sigstore integration time:
-
Permalink:
Wasif-ZA/sprawll@e68a894f5a84aaff103f60e5d4df3de7f71c099c -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/Wasif-ZA
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e68a894f5a84aaff103f60e5d4df3de7f71c099c -
Trigger Event:
push
-
Statement type: