Check external evidence
An assertion in one archive cites an exact record in a different archive as evidence, and you want to check that citation offline, with the other archive opened only when you choose to open it.
Keep sample.core for evidence resolution; the claim whose evidence you are checking may have been recorded through sample.claim, and sample.claims reads its active head.
This guide assumes: you have finished the tutorial path, you can tell a checkpoint from a record after two kinds of identity, and you have met assertions in the scientific assertions workflow.
Suppose a colleague’s archive holds an ATR reference spectrum of a known polymer. Your
archive for sample polymer-film-01 carries the claim “this film is polypropylene”, and
that claim cites the colleague’s reference record as evidence. The citation is inert:
loading and verifying your archive never opens the other file. When you want to check the
citation, you decide which archives to hand over, and resolve_external_evidence does the
rest. The example builds both archives in memory so it runs standalone.
import numpy as np
from mtrl import InstrumentRun, MaterialData, Mtrlfrom mtrl.assertions import ( AssertionDraft, EvidenceRef, SubjectRef, resolve_external_evidence,)
reference = Mtrl(sample_id="reference-01")reference_run = InstrumentRun(run_name="atr-check")reference_checkpoint = MaterialData( content=np.array([1.0, 2.0]), type="raw", checkpoint_name="atr",)reference_run.add_checkpoint(reference_checkpoint)reference.add(reference_run)reference_record = reference.get_active_record(reference_checkpoint.checkpoint_id)
study = Mtrl(sample_id="polymer-film-01")study_uid = study.assign_sample_uid()evidence = EvidenceRef.for_external_record( reference.archive_id, reference_record.checkpoint_id, reference_record.record_id, role="reference-identification",)draft = AssertionDraft( subject=SubjectRef.sample(study_uid), property_id="polymer.identity", value="polypropylene", evidence=(evidence,),)assertion = study.assert_properties([draft])[0]print(f"evidence kind: {assertion.evidence[0].kind.value}")
reports = resolve_external_evidence(study, {reference.archive_id: reference})print(f"report status: {reports[0].status.value}")evidence kind: external-recordreport status: verifiedThe first line prints evidence kind: external-record: the evidence is a citation into
another archive, not a pointer to a local record. The second line prints report status: verified: you supplied the named archive, and the named record is in it.
What just happened?
Section titled “What just happened?”EvidenceRef.for_external_record(...) stored an ArchiveRecordRef (importable from
mtrl.domain) inside the assertion. It holds three identifiers — the identity of the other
archive, the logical checkpoint identity, and the exact record identity — plus an optional
expected payload digest. The reference is inert by design: loading and verifying your
archive never opens the other archive, so a missing or changed file cannot break yours. The
citation is a claim about another archive, not a live link into it.
resolve_external_evidence(study, {reference.archive_id: reference}) is where the check
happens, and it stays offline. You pass the container that holds the assertions and a
mapping of caller-supplied containers keyed by archive identity. MTRL opens no file and
commits no revision: it reads only what you hand it. You receive one report per external
evidence item, in assertion order and then evidence order. Each report carries the
assertion and claim identities, the property, the external record reference, and a status.
The status is one of four values. verified means the archive was supplied, the record is
present, and the expected digest — when one is recorded — matches the record’s content.
unresolved means you did not supply the named archive, so nothing could be checked.
missing-target means the archive is there but the record is not. digest-mismatch means
the record is present but its content digests differently from the expected payload digest
recorded in the evidence.
Pass expected_payload_digest= to EvidenceRef.for_external_record(...) when the claim
must name the record’s exact content, not only its identity. From then on, a citation whose
target holds different content reports digest-mismatch instead of passing silently. Pass
as_of_revision= to resolve_external_evidence to check the claims as they stood at an
earlier revision of your archive.
Tip —
unresolvedis an answer, not a failure. It means the check stayed honest: the archive was not in front of MTRL, so MTRL said so. Supply the archive and run the check again.
Caution — Resolution reports external-record evidence only. An assertion can also cite local records and local sources; those references are checked by the commit itself, so they never appear in these reports.
Where next
Section titled “Where next”- Record scientific assertions — the full assertion workflow: drafts, subjects, evidence, and the lifecycle calls.
- Reference — the exact signatures of
EvidenceRef,ArchiveRecordRef,EvidenceResolutionReport, andresolve_external_evidence.