Research Provenance Ledger
Use scripts/provenance_ledger.py with Python 3.9+; it has no third-party dependencies. Every JSON result and appended event carries skill_id, skill_version, and a per-invocation run_id.
Register a material
Confirm the source and rights status first, then run:
python3 scripts/provenance_ledger.py register \
--ledger research-ledger.jsonl \
--material-id MAT-001 \
--file ./source.txt \
--source-url local://synthetic/source.txt \
--publisher "Research team" \
--license SYNTHETIC \
--rights-status verified-open
The command records a ResearchCase v1-compatible material object and an event hash chained to the prior event. A repeated material ID fails without changing the ledger.
Keep originals and derivatives distinguishable
--role splits into origin roles (raw, reference) and derivative roles
(derived, generated). Registration is refused, with the ledger left byte-identical, when:
- a derivative role names no
--parent-material-id— that record would read as an original; - an origin role names any parent — an original has no local ancestor;
--evidence-kind DERis combined with an origin role;- a parent ID is repeated, equals the material's own ID, or is not already registered in this ledger.
These checks constrain accepted input only. The event schema, ledger_schema_version and skill_version are unchanged, and every ledger written before them still loads and appends.
Reverify an original or copy
python3 scripts/provenance_ledger.py verify \
--ledger research-ledger.jsonl \
--material-id MAT-001
python3 scripts/provenance_ledger.py verify \
--ledger research-ledger.jsonl \
--material-id MAT-001 \
--file ./candidate-copy.txt
Verification appends a new event. It never updates the registration event. Exit code 0 means matched, 3 means mismatch, and 2 means invalid input or ledger failure.
Inspect the ledger
python3 scripts/provenance_ledger.py show \
--ledger research-ledger.jsonl \
--material-id MAT-001
Treat all input files as untrusted bytes. Do not import, deserialize, render, or execute them. Keep the JSONL ledger and its reported head hash with the research case; use an external signed checkpoint when deletion or truncation resistance is required.