ArticleMap
An open standard for evidence-bound, tamper-evident article records. Make reported numbers and claims in supported study records clickable, replayable, and tamper-evident.
For HTA agencies · systematic-review groups · guideline developers · journals · pharma medical affairs.
An ArticleMap record is JSON for a single study — RCT, observational, or meta-analysis — with deterministic hashing, schema-validated structure, and evidence anchors that bind every effect estimate and claim to a verbatim quote and an executable selector into the source. One reviewer click jumps from an extracted hazard ratio to the exact lines of Table 2 in the source PDF. Sign it, anchor it, and an auditor five years later replays the entire chain offline with one command.
EXTRACTED EFFECT HR 0.69 95% CI 0.57–0.83
↓
EVIDENCE ANCHOR EV-002 · quote ≤ 25 words · selector
↓
SOURCE LOCATOR page 4 · lines 14–16 · Table 2
What's in this repository
This is the reference implementation of the ArticleMap trust layer — the deterministic, offline-verifiable core that makes the standard real. Open the format; sell the quality and the verification. The schema is open (CC0); this tooling is Apache-2.0. Adopt without us.
| Module | What it is |
|---|---|
articlemap/canonical.py |
RFC 8785 JSON Canonicalization (JCS) + SHA-256 — the hashing foundation. |
articlemap/signing.py |
Ed25519, did:key identities, offline key resolution. |
articlemap/record.py |
The ArticleMap record: content-hashing, content-addressed identity, signing. |
articlemap/conformance.py |
The L0–L3 conformance ladder. |
articlemap/eventlog.py |
The reviewer-event log: append-only, hash-chained, per-event signed. |
articlemap/capsule.py |
The Atlas Capsule: a self-contained, offline-verifiable bundle. |
articlemap/verifier.py |
The offline verifier — record + log + cross-binding. |
articlemap/extract/ |
Stages 1–3: PDF → source → layout → index (PyMuPDF). |
articlemap/slots.py · retrieval.py · extractor.py · anchor.py |
Stages 4–7: slot plan → retrieval → extraction → anchors. |
articlemap/build.py |
The orchestrator: index → signed, L3, verifiable record. |
articlemap/claimguard.py |
Fail-closed ClaimGuard v2 import boundary: reconciles raw artifacts, replays page-pinned evidence and typed effects, and emits an unsigned ArticleMap draft + receipt. |
Everything in the trust layer is deterministic and offline — no network,
no clock dependence, no API keys. That is the whole point: the verifier is
what an auditor or a journal's editorial-integrity team runs. For pinned
inputs, reproducibility is enforced in CI across supported Python versions.
The extraction stages run offline too with a deterministic backend, and
swap in a Claude backend
(articlemap[llm]) for higher recall — the anti-hallucination invariant holds
either way (docs/EXTRACTOR.md).
Quickstart
pip install "articlemap[schema]==1.1.1" # released verifier + schemas
# From a repository checkout, for development and the complete examples:
pip install -e ".[dev]" # cryptography + schemas + tests
# (PDF extraction also needs: pip install -e ".[extract]")
# Verify the worked orthopaedics-RCT example: record + reviewer-event log + source
python -m articlemap.cli verify examples/ortho_rct/record.json \
--log examples/ortho_rct/events.jsonl \
--source examples/ortho_rct/source.txt
# Verify the self-contained Atlas Capsule offline (no other files needed)
python -m articlemap.cli capsule-verify examples/ortho_rct/capsule.json
# Or run the whole product: index → signed, L3, verifiable record + capsule
python -m articlemap.cli build index.json --layout layout.json \
--source source.json --out record.json --sign
Release 1.1.1 adds the hardened ClaimGuard admission boundary, synchronized
schemas, reproducible pilot evidence, and installed-distribution verification.
VERIFIER: PASS conformance: L3
[pass] record.schema
[pass] record.content_hash
[pass] record.article_id
[pass] record.signatures
[pass] record.conformance
[pass] log.envelope_shape … log.sequencing … log.chaining
[pass] log.hash_recompute … log.signatures … log.lifecycle
[pass] log.record_continuity … log.anchored_root … log.record_binding
[pass] capsule.pinned_content_hash … pinned_event_log_root … merkle_root
Tamper with one digit of one effect estimate and the verifier names the failing check, the event index, and the field — there is nothing to argue about.
In code
from articlemap import ArticleMapRecord, evaluate, verify
rec = ArticleMapRecord.load("examples/ortho_rct/record.json")
print(rec.article_id) # amap:sha256:68aeb382...
print(evaluate(rec).achieved) # L3
report = verify(rec, events=None)
print(report.ok, report.conformance.achieved)
ClaimGuard → ArticleMap
ClaimGuard artifacts enter the trust layer through an explicit fail-closed boundary. A successful import is an unsigned L3 draft ready for review, not a reviewer decision or signature.
pip install -e ".[schema]"
python examples/claimguard_corr_demo/run_demo.py
The synthetic fixture first requires the standalone ClaimGuard verifier to
flag HR 0.42 against a source reporting HR 0.69. It then forges a dishonest
supported report and requires the ArticleMap adapter to reject it again. The
corrected HR 0.69 passes both gates; identical reruns reproduce promised bytes,
and changing one admitted digit makes verification fail. The generated report
is evidence for covered admission controls—not semantic truth or real-corpus
accuracy. See
docs/CLAIMGUARD_INTEGRATION.md and the
controlled pilot proposal.
The conformance ladder
Adopt at your own pace. Each rung is independently, mechanically checkable.
| L0 Minimal | Identity, provenance, ≥ 1 claim. | Replaces a spreadsheet row. |
| L1 Evidence-bound | Every claim and every effect references ≥ 1 evidence anchor with a verbatim quote (≤ 25 words) and a selector. | Where ArticleMap separates from every other extraction tool. |
| L2 Replayable | Integrity block populated; inference-ruleset version recorded; invalidation rules declared. | |
| L3 Source-bound | source_hash matches the exact source bytes; record round-trips deterministically. |
Instant, byte-level audit. |
Below L1 it's a spreadsheet with extra steps. See
docs/CONFORMANCE.md.
How it works
PDF in. ──► Extract ──► Review ──► Sign & Anchor ──► Replayable record out.
- Extract. Layout-aware parsing → IMRaD index → typed slot retrieval →
extractor in JSON mode → anchor proposer. Anti-hallucination invariant:
no field becomes an anchor unless its quote appears verbatim in the
source (
Index.find_quote). All of Stages 1–7 are implemented — a deterministic regex backend by default, an optional Claude backend for recall. Seedocs/EXTRACTOR.md. - Review. Source on the left, structured extraction on the right. Every
accept/edit/reject is recorded in the reviewer-event log with a
timestamp, a DID, a diff, and a signature.
(
docs/reviewer_event_log_spec.md) - Sign & Anchor. JCS canonical hash · Ed25519 signature · evidence
Merkle root · Atlas Capsule export. An auditor with the verifier and
the pinned roots replays the whole chain.
(
docs/VERIFIER.md)
CLI
articlemap verify record.json [--log events.jsonl] [--source src] [--json]
articlemap conformance record.json [--source src] [--json]
articlemap log-verify events.jsonl [--record record.json]
articlemap capsule-build record.json events.jsonl --out capsule.json
articlemap capsule-verify capsule.json
articlemap translog-build record.json... --out log.json # RFC 6962 log
articlemap translog-verify log.json record.json # prove inclusion
articlemap export record.json... --format csv|jsonl|fhir # rows or FHIR Evidence
articlemap diff old.json new.json # double-extraction / corrections
articlemap hash record.json
articlemap extract paper.pdf --out artifacts/ # needs pymupdf
articlemap build index.json --layout layout.json --source source.json --out record.json [--sign]
Exit status is 0 on pass, 1 on failure — drops straight into CI.
Tests
pytest # 300+ deterministic, offline tests (with optional skips)
Coverage includes the RFC 8785 number vectors, did:key round-trips, every
conformance rung and its failure modes, all eight reviewer-event-log checks,
capsule tamper detection, the extraction pipeline (including the
anti-hallucination guard dropping fabricated quotes), the ClaimGuard admission
boundary and numeric-mismatch regressions, an end-to-end test that index →
signed L3 capsule verifies green, and a golden test on the committed
example.
Regenerate the worked example after any change to the trust layer:
python scripts/build_example.py
Documents
docs/architecture.md— the full pipeline and stage status.docs/EXTRACTOR.md— the extraction pipeline (Stages 4–7) and backends.docs/CLAIMGUARD_INTEGRATION.md— the fail-closed ClaimGuard import boundary.docs/CLAIMGUARD_THREAT_MODEL.md— trust boundaries, covered attacks, and residual risks.docs/pitch/CLAIMGUARD_PILOT_PROPOSAL.md— the bounded 30-day decision request.docs/pitch/CLAIMGUARD_EVALUATION_PROTOCOL.md— preregistered corpus, adversarial, metric, and stop rules.docs/pitch/CLAIMGUARD_ARTICLEMAP_TECHNICAL_BRIEF.md— evaluator brief, evidence, boundaries, and pilot plan.docs/releases/1.1.1.md— ClaimGuard hardening release notes and verification boundary.docs/releases/1.1.0.md— toolkit 1.1.0 release notes.docs/CONFORMANCE.md— the L0–L3 ladder.docs/VERIFIER.md— what the offline verifier checks, and the two-hash design.docs/SCHEMA.md— the record format.docs/reviewer_event_log_spec.md— the event-log specification.docs/ROADMAP.md— the long road from here to a field standard.dist/articlemap_verify.py— a self-contained single-file auditor verifier (one file +cryptography).docs/pitch/— the pitch deck and a worked CORR pilot proposal.
License
Schema: CC0. Tooling: Apache-2.0 (see LICENSE).
Metadata
Release files for articlemap 1.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 | |
|---|---|---|---|
| articlemap-1.1.1.tar.gz | 145.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| articlemap-1.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 264.1 kB
Release files / articlemap-1.1.1.tar.gz
| Download URL | articlemap-1.1.1.tar.gz |
|---|---|
| Size | 145.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cb313e6838dd02e2b6c6e0bb3bb0f471326db662035b132f27f258cc39288e56
|
|
BLAKE2b-256 checksum How to use checksums |
968cbfb311dbfacc2c2a6b82f7e402564caae141413e9a41e5a741f42995f078
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 18, 2026.
Transparency logRelease files / articlemap-1.1.1-py3-none-any.whl
| Download URL | articlemap-1.1.1-py3-none-any.whl |
|---|---|
| Size | 119.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
daabfa96cf4fd730ed3e30ca4c8d02998fc7ec7417f687fb5177208023d6d2b4
|
|
BLAKE2b-256 checksum How to use checksums |
4edade8f688dc0d81fde51505e2ac5359836c9c6e77bbd7a1c0dd224e7d7b494
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 18, 2026.
Transparency log