adduce
A local research-artifact auditor.
adduce checks whether a paper's claims, code, configs, data, dependencies, remote models, precision settings, and generated results still agree with each other before submission. It also drafts repository-observable NeurIPS/ACL checklist items, an ACM Artifact Appendix, archival metadata (RO-Crate, Croissant, CodeMeta, Zenodo), and a claim-by-claim evidence trail for author review.
The north-star question: for every number in the paper, can I point to the artifact that produced it, and will that artifact still produce it elsewhere?
Install
pipx install adduce # or: pip install adduce / uvx adduce
adduce check .
PyPI 0.2.0 is the current release.
Upgrade commands per installer, and the caveat that existing installations do not update themselves, are in docs/cli-reference.md.
Adduce is beta software. Findings are static-analysis signals for review, and scores, tiers, and reviewer-time estimates are provisional pending calibration against manually reviewed real repositories. Generated submission material is always a draft.
Built-in checks are offline by default. Public-metadata requests require the explicit
--onlineorpin-remotesmodes and use a bounded public-HTTPS resolver; pre-existing cache entries never count as network evidence. Read the security model before using network, provider, plugin, or dynamic-execution features on untrusted input.
What it reports
Verbatim excerpt from adduce check on nanoGPT
at commit 3adf61e. Omitted whole: eight of the fifteen category rows, the
no-paper-sources notice, the inferred claim-trail block, the last two fixes, and
the closing Next: line. Nothing is reworded, and every … is the tool's own
truncation marker.
╭─ adduce · nanogpt · commit 3adf61e ────────────────────────────────────────────────────────╮
│ Reproducibility 54/100 Bronze · profile: default │
╰────────────────────────────────────────────────────────────────────────────────────────────────╯
Reviewer time to first result: 23–83 min (Risky)
- no one-command reproduction path
- environment must be assembled by hand (no container or conda env)
- dependency resolution may not converge to the original environment
- no smoke/quick-run target for a minutes-scale sanity check
Category Score Notes
Code & Execution 8/12 Commands are documented, but there is no run script or
Makefile target to execute them; The README shows run
command(s) (e.g. `python
data/shakespeare_char/prepare.py`), but …
Environment & Tooling 1/10 No dependency manifest found (requirements.txt,
pyproject.toml, environment.yml); No lockfile found
(poetry.lock, uv.lock, Pipfile.lock, conda-lock); No
Dockerfile, …
Data 8/10 No checksums or content-addressed data tracking detected; A
data directory exists but does not separate raw from
processed content
Determinism & Model 3/12 Some RNG sources are seeded, but not all: missing python
(random.seed), numpy (np.random.seed or default_rng);
Neither torch.backends.cudnn.deterministic=True nor …
Numerical Precision & Hardware 2/4 TF32 / float32-matmul precision control in use
(torch.backends.cuda.matmul.allow_tf32 = True;
torch.backends.cudnn.allow_tf32 = True) but no precision
policy is documented …
Result Reconciliation — 1 check(s) applied; none could be assessed
Portability 3/3 all detected checks satisfied
Top fixes (largest score gains first)
1. Extend the seeding helper to cover: python (random.seed), numpy (np.random.seed or
default_rng).
adduce fix --scaffold seeds
2. Set torch.backends.cudnn.deterministic = True and torch.backends.cudnn.benchmark = False in
the seeding helper.
adduce fix --scaffold seeds
3. Declare dependencies, then pin them (pip freeze, pip-compile, uv lock, poetry lock).
Statuses are detected signals from static analysis, not a certification of reproducibility.
Location-bearing findings are anchored to source lines—the TF32 finding above
points at train.py:107, and the unpinned hub call at model.py:238. Seven of
the fifteen categories that applied to nanoGPT are shown above; the same run
also covers Documentation, Run Traceability, Checkpoint & Experiment State,
Notebooks, Remote Artifacts & Rot, Versioning, Access & Legal, and Archival
Readiness.
When a manifest declares claims, the report adds a per-claim trail. Trimmed
output from adduce manifest followed by adduce check on the synthetic
positive-control repository
corpus/synthetic/synthetic_rounding_match
in this repository, where the paper states an accuracy of 81.4 and the logged
run recorded 81.37:
Claim trails (manifest; draft claims remain inferred until author-confirmed)
paper/main.tex:3 · "accuracy of 81.4" [inferred draft]
metric results/eval.csv:accuracy (found: 81.37) ~ rounding vs paper
(81.4) ✓
log results/eval.csv ✓
status PARTIAL
Every finding carries a status (pass / partial / fail / not-applicable
/ unknown), a confidence, available file:line locations, and a concrete
remediation. partial is used when the repository supports only part of a
check.
Honest limits
adduce reports detected signals, never a certification of reproducibility. It
never says a repository "is reproducible", and it never assesses
execution-based badges (Results Reproduced/Replicated) — only badge
eligibility signals. Static analysis never implies execution: the opt-in
--online/pin-remotes (network) and reproduce (execution) layers are the
only parts of adduce that leave the offline, static default, and both are
explicitly fenced.
Scores and named tiers are experimental prioritisation aids, not calibrated quality grades. The validation corpus protocol defines a pending release-quality gate, and no effectiveness or calibration claim is made until its human-review requirements are complete.
The full list of limits — automatic claim inference as scaffolding only, the static-resolution ceiling, remote pinning as a forward guarantee rather than historical recovery, dynamic reproduction's non-sandboxed execution, and more — is in docs/honest-limits.md.
Documentation
Adduce ships 78 rules across 17 categories, each gated on whether it
applies, so an inapplicable category drops out of scoring rather than counting
against a repository. A category that did apply but reached no assessment —
Result Reconciliation above — keeps its row and shows — rather than a
zero, because "nothing to check here" and "checked and found nothing" are
different answers and only one of them is a finding.
Full documentation — every rule, the CLI reference, the manifest and claim-trail model, CI recipes, generation safety, the optional LLM layer, and the security model — starts at docs/index.md. The rule reference and honest limits are the two pages most worth reading before relying on a score.
Contributing
Contributions are welcome, especially incorrect or low-value finding reports. See CONTRIBUTING.md for the development setup, design constraints, and how to add a rule. Report vulnerabilities privately under the security policy.
License
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 adduce-0.2.0.tar.gz.
File metadata
- Download URL: adduce-0.2.0.tar.gz
- Upload date:
- Size: 802.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f984a3f3afefe75fbcfdf5b3dda921f40f378814c29389bff1c5d67a3479ee8f
|
|
| MD5 |
39a2d9d7b2f454e230ded106336f8670
|
|
| BLAKE2b-256 |
5aa33229f4fc0f7ea91b0a74a062a4753515570cd6e2113c76ab4fcc5d4e3ee0
|
Provenance
The following attestation bundles were made for adduce-0.2.0.tar.gz:
Publisher:
release.yml on QHarshil/adduce
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adduce-0.2.0.tar.gz -
Subject digest:
f984a3f3afefe75fbcfdf5b3dda921f40f378814c29389bff1c5d67a3479ee8f - Sigstore transparency entry: 2667493108
- Sigstore integration time:
-
Permalink:
QHarshil/adduce@bea16d655db499ce35807b18bcea7135736f705c -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/QHarshil
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@bea16d655db499ce35807b18bcea7135736f705c -
Trigger Event:
push
-
Statement type:
File details
Details for the file adduce-0.2.0-py3-none-any.whl.
File metadata
- Download URL: adduce-0.2.0-py3-none-any.whl
- Upload date:
- Size: 256.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6bb3d5588486bd65052513e342c48821f43e1011778be0f17abc16c8b63ea8f2
|
|
| MD5 |
d278190f0a9daca491c5dd91985cb1e7
|
|
| BLAKE2b-256 |
7bfa92563b39f363327d91c365c20dd0aafc5127540d435f3a75e417879105c1
|
Provenance
The following attestation bundles were made for adduce-0.2.0-py3-none-any.whl:
Publisher:
release.yml on QHarshil/adduce
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adduce-0.2.0-py3-none-any.whl -
Subject digest:
6bb3d5588486bd65052513e342c48821f43e1011778be0f17abc16c8b63ea8f2 - Sigstore transparency entry: 2667493199
- Sigstore integration time:
-
Permalink:
QHarshil/adduce@bea16d655db499ce35807b18bcea7135736f705c -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/QHarshil
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@bea16d655db499ce35807b18bcea7135736f705c -
Trigger Event:
push
-
Statement type: