provenance-dag · git:20260706.11e587f · 2026-07-06 · sha256 d23468c2357158c6
provenance-dag git:20260706.11e587fA
Immutable. This exact content is served forever at /api/v1/blob/d23468c2357158c6.
---
name: provenance-dag
description: >
Content-addressed provenance DAG for research lineage tracking.
Use for: recording which pipeline stage produced which artifact,
tracing artifact ancestry, recording reviewer findings.
CLI: python -m infrastructure.provenance {record,link,query,list,review}.
Config: set in projects/{name}/manuscript/config.yaml `provenance:` block.
Orchestrator: scripts/09_provenance_record.py --project {name} --stage NAME
---
# Provenance DAG
Content-addressed provenance DAG for tracking research artifact lineage.
Every artifact node is identified by a SHA-256 content hash; edges record
which pipeline stage produced each artifact from which inputs.
## Quick Start
```python
from infrastructure.provenance import ProvenanceStore
store = ProvenanceStore("output/.provenance")
# Record that stage "analysis" produced "results.json"
node_id = store.record(
artifact_path="output/results.json",
stage="analysis",
metadata={"script": "02_run_analysis.py"},
)
# Link a downstream artifact to its source
store.link(source_id=node_id, target_path="output/manuscript.pdf", stage="render")
```
## CLI
```bash
# Record an artifact
uv run python -m infrastructure.provenance record output/results.json --stage analysis
# Link two artifacts
uv run python -m infrastructure.provenance link <source-id> output/manuscript.pdf --stage render
# Query ancestry of an artifact
uv run python -m infrastructure.provenance query output/manuscript.pdf
# List all recorded artifacts
uv run python -m infrastructure.provenance list
# Record a reviewer finding against an artifact
uv run python -m infrastructure.provenance review <artifact-id> --note "Needs citation"
```
## Pipeline Orchestrator
```bash
# Record provenance for a named project and pipeline stage
uv run python scripts/09_provenance_record.py --project my_project --stage analysis
# Record with custom artifact paths
uv run python scripts/09_provenance_record.py \
--project my_project \
--stage render \
--artifacts output/manuscript.pdf
```
## Config Integration
Set provenance options in `projects/{name}/manuscript/config.yaml`:
```yaml
provenance:
store_dir: output/.provenance
record_stages:
- analysis
- render
- validate
auto_link: true
```
## Key Types
```python
from infrastructure.provenance import (
ProvenanceStore, # Main interface — record / link / query / list / review
ProvenanceNode, # Immutable artifact record with SHA-256 content address
ProvenanceEdge, # Directed stage edge between two nodes
ReviewRecord, # Reviewer finding attached to an artifact node
)
```
## Content Addressing
Every artifact is stored by SHA-256 hash of its content:
```python
node = store.record("output/results.json", stage="analysis")
print(node.content_hash) # "sha256:abc123..."
print(node.artifact_path) # resolved absolute path at record time
```
Re-recording the same unchanged file is idempotent — the same node is
returned. A changed file produces a new node, preserving the full history.
## Ancestry Tracing
```python
ancestors = store.query("output/manuscript.pdf")
for node in ancestors:
print(f" {node.stage} → {node.artifact_path} ({node.content_hash[:12]})")
```
## Reviewer Findings
```python
store.review(node_id, note="Missing error bars in Fig 3", reviewer="LLM-review")
findings = store.list_reviews(node_id)
```
## Testing
```bash
uv run pytest tests/infra_tests/provenance/ -v
```
## See Also
- [`AGENTS.md`](AGENTS.md) — operating contract and architecture
- [`../search/SKILL.md`](../search/SKILL.md) — search module skill
- [`../core/pipeline/AGENTS.md`](../core/pipeline/AGENTS.md) — pipeline integration