attestable
Make it structurally impossible to ship an AI-produced value without a confidence score and a version-pinned, resolvable citation.
attestable is a tiny, zero-dependency Python library for auditable provenance on model output. It gives you four things that compose:
Derived[T]— a value that cannot be constructed without a confidence in[0, 1]and at least one valid source anchor. Provenance travels with the value, by construction, everywhere it goes.- An anchor grammar — a frozen citation URI that pins the source version, so re-chunking or re-embedding a newer revision never invalidates a citation stored against an older one. This is the one correctness property hand-rolled citation schemes get wrong.
- Resolvers + dangling detection — resolve anchors back to source text, and batch-check a corpus for citations that no longer point anywhere.
- Attestations — deterministic, tamper-evident (optionally HMAC-signed) digests that prove a value/confidence/citation triple has not been altered.
Why
Auditors, regulators, and reviewers reject "the model said so." When an LLM extracts a field, answers a question, or flags a finding, three things must be true for that output to survive scrutiny:
- It carries a confidence you can threshold on.
- It carries a pointer to the exact source it came from.
- That pointer still works after you re-index the corpus.
Most stacks bolt this on as an afterthought and get (3) wrong: citations are stored as raw offsets or chunk ids that break the moment a document is re-chunked. attestable makes (1) and (2) a type-level requirement and makes (3) correct by pinning the source version in the citation itself.
It is deliberately small, dependency-free, offline-capable, and framework-agnostic — it composes with your extraction/RAG stack rather than replacing it.
Install
pip install attestable.py
The PyPI distribution is named
attestable.py(the plainattestablename is an unrelated, unmaintained package). The import name is unaffected:import attestable.
Requires Python 3.10+. No third-party runtime dependencies.
Quick start
from attestable import Derived, span_anchor, attest, verify, InMemoryResolver, parse_anchor
# 1. Cite the exact characters — pinned to version 3 of the source.
anchor = span_anchor("document", "invoice-abc", version=3, chunk_id="p2", start=40, end=52)
# 2. Wrap the value. This raises unless confidence is in [0,1] and provenance is a valid anchor.
total = Derived(value="2026-01-15", confidence=0.94, provenance=[anchor])
# 3. Attest it (keyed = forge-resistant).
token = attest(total, key="rotate-me")
assert verify(total, token, key="rotate-me")
# 4. Tampering is detected.
assert not verify(total.with_value("2026-02-02"), token, key="rotate-me")
# 5. Resolve back to source, and detect citations that no longer point anywhere.
resolver = InMemoryResolver()
resolver.put("document", "invoice-abc", 3, "… issued on 2026-01-15 …")
assert resolver.resolve(parse_anchor(anchor)) is not None
Run the full tour: python examples/quickstart.py.
The anchor grammar
attest://<type>/<lineage_id>@<version>
attest://<type>/<lineage_id>@<version>#chunk:<chunk_id>
attest://<type>/<lineage_id>@<version>#span:<chunk_id>:<start>-<end>
attest://<type>/<lineage_id>@<version>#field:<json_pointer>
| Part | Meaning |
|---|---|
type |
lowercase entity type, e.g. document or document.sop |
lineage_id |
identity that is stable across versions of the source |
version |
the specific integer version cited |
chunk_id |
opaque, stable id of a chunk/paragraph |
start/end |
character range within a chunk (start <= end) |
json_pointer |
RFC-6901 pointer into a structured record |
parse_anchor() is total: it returns a fully-typed ParsedAnchor or raises AnchorSyntaxError — never a half-populated result. The scheme (attest) is fixed per deployment; use Grammar("your-scheme") to change it.
Integrating with your store
Implement the Resolver protocol over wherever your source text actually lives:
from attestable import Resolver, ResolvedSource, ParsedAnchor
class SqliteResolver:
def resolve(self, anchor: ParsedAnchor) -> ResolvedSource | None:
row = db.get(anchor.entity_type, anchor.lineage_id, anchor.version)
if row is None:
return None # -> reported by find_dangling()
text = row.text[anchor.start:anchor.end] if anchor.fragment == "span" else row.text
return ResolvedSource(anchor=anchor.to_anchor(), text=text)
Then find_dangling(anchors, resolver) and dangling_in(derived_values, resolver) give you a corpus-wide integrity check to run after every re-ingest.
Documentation
- Architecture & design decisions
- API reference
- FAQ & troubleshooting
- Changelog
- Contributing · Security policy · Code of conduct
License
Metadata
Release files for attestable.py 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| attestable_py-0.1.1.tar.gz | 19.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| attestable_py-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 37.6 kB
Release files / attestable_py-0.1.1.tar.gz
| Download URL | attestable_py-0.1.1.tar.gz |
|---|---|
| Size | 19.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5bc539dc648cd6add713ca4b16354265200b8ce1f85ed83b70152bbc181c23a0
|
|
BLAKE2b-256 checksum How to use checksums |
370d2cc2cde16dff52bf3bb4bc8cb949b5124114671a97cfe5d5e5e997812d59
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 7, 2026.
Transparency logRelease files / attestable_py-0.1.1-py3-none-any.whl
| Download URL | attestable_py-0.1.1-py3-none-any.whl |
|---|---|
| Size | 18.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0bf375dbe8ac9240c3e5c965243d5cfd554d34624d0096e0b6daa5419e10cf63
|
|
BLAKE2b-256 checksum How to use checksums |
27630f59eb20c3088820c87275af5078a2b3ef39a9deff793e6f9363fb6689e5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 7, 2026.
Transparency log