Repository object · test
Test Dossiers
Accepted test in the public catalog.
- Source path
tests/test_dossiers.py- Media type
text/x-python- Object ID
em:test:sha256:e898e1403974a237db794e9bb8fa1ef79edc915faef3214236cd0840db67c376- Content digest
93544a5250ce8b7f84ee40dae960b9d6396823424e3ce28a79ea559cff9f9a2e
Source content
from __future__ import annotations
import hashlib
import json
from urllib.parse import quote
import pytest
from epistemedia.core import canonical_json
from epistemedia.dossier import (
DOSSIER_FORMAT,
DossierProjection,
DossierValidationError,
dossier_id,
independence_summary,
public_dossier,
record_id,
stamp_dossier,
validate_dossier,
)
def exact_bytes(value: object) -> bytes:
if isinstance(value, str):
return value.encode("utf-8")
return canonical_json(value).encode("utf-8")
def sha256(value: object) -> str:
return "sha256:" + hashlib.sha256(exact_bytes(value)).hexdigest()
def edition(
key: str,
work_key: str,
label: str,
content: str | dict | list,
*,
visibility: str = "public",
) -> dict:
raw = exact_bytes(content)
return {
"key": key,
"work_key": work_key,
"edition_label": label,
"media_type": "text/plain" if isinstance(content, str) else "application/json",
"retrieved_at": "2026-08-22T00:00:00Z",
"content": content,
"content_digest": sha256(content),
"content_length": len(raw),
"visibility": visibility,
}
def text_span(
key: str,
edition_key: str,
text: str,
*,
visibility: str = "public",
) -> dict:
return {
"key": key,
"edition_key": edition_key,
"locator": {
"type": "text-offset",
"start": 0,
"end": len(text),
"label": f"characters 0-{len(text)}",
},
"extent": {"type": "quote", "text": text},
"digest": sha256(text),
"visibility": visibility,
}
def fixture_material() -> dict:
origin_text = "Synthetic instrument output: value=10."
copy_text = "Synthetic copy repeats value=10 and names the origin."
unknown_text = "Synthetic unattributed summary repeats value=10."
private_text = "Private fixture note; excluded from the public projection."
relations = [
{
"key": "relation-support",
"relation_type": "support",
"from_ref": "span-origin",
"to_ref": "proposition-value",
"basis_span_keys": ["span-origin"],
"note": "Synthetic structural support example only.",
"visibility": "public",
},
{
"key": "relation-rebuttal",
"relation_type": "rebuttal",
"from_ref": "assertion-copy",
"to_ref": "assertion-origin",
"basis_span_keys": ["span-copy"],
"note": "Synthetic structural rebuttal example only.",
"visibility": "public",
},
{
"key": "relation-qualification",
"relation_type": "qualification",
"from_ref": "span-copy",
"to_ref": "proposition-value",
"basis_span_keys": ["span-copy"],
"note": "Synthetic structural qualification example only.",
"visibility": "public",
},
{
"key": "relation-undercutting",
"relation_type": "undercutting",
"from_ref": "span-unknown",
"to_ref": "assertion-unknown",
"basis_span_keys": ["span-unknown"],
"note": "Synthetic structural undercutting example only.",
"visibility": "public",
},
{
"key": "relation-replication",
"relation_type": "replication",
"from_ref": "assertion-copy",
"to_ref": "assertion-origin",
"basis_span_keys": ["span-copy"],
"note": "Synthetic structural replication example only.",
"visibility": "public",
},
{
"key": "relation-failed-replication",
"relation_type": "failed-replication",
"from_ref": "assertion-unknown",
"to_ref": "assertion-origin",
"basis_span_keys": ["span-unknown"],
"note": "Synthetic failed-replication shape; no empirical claim.",
"visibility": "public",
},
{
"key": "relation-dependence",
"relation_type": "dependence",
"from_ref": "lineage-copy",
"to_ref": "lineage-origin",
"basis_span_keys": ["span-copy"],
"note": "The synthetic copy declares dependence on the synthetic origin.",
"visibility": "public",
},
]
return {
"format": DOSSIER_FORMAT,
"title": "Synthetic lineage fixture",
"question": (
"Can copied and unknown support be represented without counting it as independent?"
),
"scope": "Synthetic application validation only; no real-world conclusion.",
"stage": "fixture",
"visibility": "public",
"source_works": [
{
"key": "work-origin",
"kind": "instrument",
"title": "Synthetic origin work",
"creators": ["Epistemedia test suite"],
"canonical_uri": "urn:epistemedia:fixture:origin",
"license": "CC0-1.0",
"visibility": "public",
},
{
"key": "work-copy",
"kind": "report",
"title": "Synthetic copied report",
"creators": ["Epistemedia test suite"],
"canonical_uri": "urn:epistemedia:fixture:copy",
"license": "CC0-1.0",
"visibility": "public",
},
{
"key": "work-unknown",
"kind": "report",
"title": "Synthetic unattributed report",
"creators": ["Epistemedia test suite"],
"canonical_uri": "urn:epistemedia:fixture:unknown",
"license": "CC0-1.0",
"visibility": "public",
},
{
"key": "work-private",
"kind": "other",
"title": "Private synthetic note",
"creators": ["Epistemedia test suite"],
"canonical_uri": "urn:epistemedia:fixture:private",
"license": "private-fixture",
"visibility": "private",
},
],
"editions": [
edition("edition-origin", "work-origin", "synthetic v1", origin_text),
edition("edition-copy", "work-copy", "synthetic v1", copy_text),
edition("edition-unknown", "work-unknown", "synthetic v1", unknown_text),
edition(
"edition-private",
"work-private",
"private synthetic v1",
private_text,
visibility="private",
),
],
"spans": [
text_span("span-origin", "edition-origin", origin_text),
text_span("span-copy", "edition-copy", copy_text),
text_span("span-unknown", "edition-unknown", unknown_text),
text_span(
"span-private",
"edition-private",
private_text,
visibility="private",
),
],
"propositions": [
{
"key": "proposition-value",
"text": "The synthetic fixture represents the value 10.",
"scope": "Synthetic fixture only.",
"visibility": "public",
}
],
"lineages": [
{
"key": "lineage-origin",
"status": "known",
"dimensions": ["source"],
"depends_on": [],
"basis_span_keys": ["span-origin"],
"assertion_keys": ["assertion-origin"],
"note": "Known synthetic root lineage.",
"visibility": "public",
},
{
"key": "lineage-copy",
"status": "known",
"dimensions": ["source", "social"],
"depends_on": ["lineage-origin"],
"basis_span_keys": ["span-copy"],
"assertion_keys": ["assertion-copy"],
"note": "Known synthetic dependent lineage.",
"visibility": "public",
},
{
"key": "lineage-unknown",
"status": "unknown",
"dimensions": [],
"depends_on": [],
"basis_span_keys": ["span-unknown"],
"assertion_keys": ["assertion-unknown"],
"note": "Unknown lineage is explicit in the fixture.",
"visibility": "public",
},
{
"key": "lineage-private",
"status": "known",
"dimensions": ["source"],
"depends_on": [],
"basis_span_keys": ["span-private"],
"assertion_keys": ["assertion-private"],
"note": "Private synthetic lineage.",
"visibility": "private",
},
],
"assertions": [
{
"key": "assertion-origin",
"proposition_key": "proposition-value",
"actor": {"id": "fixture-origin", "kind": "instrument"},
"stance": "asserts",
"span_keys": ["span-origin"],
"lineage_key": "lineage-origin",
"asserted_at": "2026-08-22T00:00:00Z",
"visibility": "public",
},
{
"key": "assertion-copy",
"proposition_key": "proposition-value",
"actor": {"id": "fixture-copy", "kind": "human"},
"stance": "asserts",
"span_keys": ["span-copy"],
"lineage_key": "lineage-copy",
"asserted_at": "2026-08-22T00:01:00Z",
"visibility": "public",
},
{
"key": "assertion-unknown",
"proposition_key": "proposition-value",
"actor": {"id": "fixture-unknown", "kind": "collective"},
"stance": "questions",
"span_keys": ["span-unknown"],
"lineage_key": "lineage-unknown",
"asserted_at": "2026-08-22T00:02:00Z",
"visibility": "public",
},
{
"key": "assertion-private",
"proposition_key": "proposition-value",
"actor": {"id": "fixture-private", "kind": "human"},
"stance": "hypothesizes",
"span_keys": ["span-private"],
"lineage_key": "lineage-private",
"asserted_at": "2026-08-22T00:03:00Z",
"visibility": "private",
},
],
"evidence_relations": relations,
"claim_families": [
{
"key": "family-value",
"title": "Synthetic value family",
"question": "How many independent lineages support the synthetic value?",
"proposition_keys": ["proposition-value"],
"assertion_keys": [
"assertion-origin",
"assertion-copy",
"assertion-unknown",
],
"relation_keys": [relation["key"] for relation in relations],
"visibility": "public",
}
],
"evaluations": [
{
"key": "evaluation-fixture",
"claim_family_key": "family-value",
"policy_id": "fixture-policy-v0",
"frontier": "fixture-frontier-v0",
"label": "Fixture only; no empirical assessment.",
"reason_codes": ["fixture-only"],
"visibility": "public",
}
],
}
def test_strict_dossier_is_content_addressed_and_separates_object_layers() -> None:
dossier = stamp_dossier(fixture_material())
validate_dossier(dossier)
assert dossier["dossier_id"] == dossier_id(dossier)
ids: set[str] = set()
for collection in (
"source_works",
"editions",
"spans",
"propositions",
"lineages",
"assertions",
"evidence_relations",
"claim_families",
"evaluations",
):
for record in dossier[collection]:
assert record["id"] == record_id(collection, record)
assert record["id"] not in ids
ids.add(record["id"])
assert dossier["source_works"][0]["id"] != dossier["editions"][0]["id"]
assert "policy_id" not in dossier["propositions"][0]
assert dossier["evaluations"][0]["claim_family_key"] == "family-value"
@pytest.mark.parametrize(
("mutation", "message"),
[
(
lambda material: material["spans"][0]["locator"].update({"end": 10_000}),
"out of bounds",
),
(
lambda material: material["spans"][0]["extent"].update({"text": "wrong"}),
"does not match edition text",
),
(
lambda material: material["spans"][0].update({"digest": "sha256:" + "0" * 64}),
"does not match exact extent",
),
(
lambda material: material["editions"][0].update(
{"content_digest": "sha256:" + "0" * 64}
),
"does not match edition content",
),
],
)
def test_invalid_edition_or_span_fails_closed(mutation, message: str) -> None:
material = fixture_material()
mutation(material)
with pytest.raises(DossierValidationError, match=message):
stamp_dossier(material)
def test_structured_span_verifies_json_pointer_value_and_digest() -> None:
material = fixture_material()
content = {"rows": [{"value": 10}]}
material["editions"][0] = edition(
"edition-origin", "work-origin", "synthetic structured v1", content
)
material["spans"][0] = {
"key": "span-origin",
"edition_key": "edition-origin",
"locator": {
"type": "json-pointer",
"pointer": "/rows/0/value",
"label": "row 0, value",
},
"extent": {"type": "json-value", "value": 10},
"digest": sha256(10),
"visibility": "public",
}
validate_dossier(stamp_dossier(material))
material["spans"][0]["locator"]["pointer"] = "/rows/00/value"
with pytest.raises(DossierValidationError, match="does not resolve"):
stamp_dossier(material)
def test_nonfinite_content_typed_relations_and_private_root_fail_closed() -> None:
nonfinite = fixture_material()
nonfinite["editions"][0] = edition(
"edition-origin",
"work-origin",
"invalid structured v1",
{"value": float("nan")},
)
with pytest.raises(DossierValidationError, match="NaN or infinity"):
stamp_dossier(nonfinite)
mistyped = fixture_material()
mistyped["evidence_relations"][0]["from_ref"] = "work-origin"
with pytest.raises(DossierValidationError, match="span/assertion source"):
stamp_dossier(mistyped)
private_root = fixture_material()
private_root["visibility"] = "private"
dossier = stamp_dossier(private_root)
with pytest.raises(DossierValidationError, match="private dossier root"):
public_dossier(dossier)
def test_dangling_relation_and_public_to_private_dependency_fail_closed() -> None:
dangling = fixture_material()
dangling["evidence_relations"][0]["from_ref"] = "missing-record"
with pytest.raises(DossierValidationError, match="unknown reference"):
stamp_dossier(dangling)
malformed_lineage = fixture_material()
malformed_lineage["lineages"][1]["depends_on"] = ["lineage-missing"]
with pytest.raises(DossierValidationError, match="unknown reference"):
stamp_dossier(malformed_lineage)
disclosure_leak = fixture_material()
disclosure_leak["assertions"][0]["span_keys"] = ["span-private"]
dossier = stamp_dossier(disclosure_leak)
with pytest.raises(DossierValidationError, match="not referentially closed"):
public_dossier(dossier)
def test_duplicate_ids_forbidden_fields_and_dependence_cycles_fail_closed() -> None:
dossier = stamp_dossier(fixture_material())
dossier["source_works"][1]["id"] = dossier["source_works"][0]["id"]
with pytest.raises(DossierValidationError, match="duplicate stable ID"):
validate_dossier(dossier)
forbidden = fixture_material()
forbidden["propositions"][0]["confidence"] = 0.9
with pytest.raises(DossierValidationError, match="intrinsic field 'confidence' is forbidden"):
stamp_dossier(forbidden)
cyclic = fixture_material()
cyclic["lineages"][0]["depends_on"] = ["lineage-copy"]
with pytest.raises(DossierValidationError, match="lineage dependence cycle"):
stamp_dossier(cyclic)
def test_relations_remain_representable_and_unknown_lineage_gets_no_credit() -> None:
dossier = stamp_dossier(fixture_material())
assert {record["relation_type"] for record in dossier["evidence_relations"]} == {
"support",
"rebuttal",
"qualification",
"undercutting",
"replication",
"failed-replication",
"dependence",
}
summary = independence_summary(
dossier,
["assertion-origin", "assertion-copy", "assertion-unknown"],
)
assert summary == {
"assertion_keys": ["assertion-origin", "assertion-copy", "assertion-unknown"],
"independent_lineage_count": 1,
"independent_lineage_roots": ["lineage-origin"],
"unknown_lineage_count": 1,
"unknown_lineages": ["lineage-unknown"],
}
tainted = fixture_material()
tainted["lineages"][1]["depends_on"] = ["lineage-unknown"]
tainted_summary = independence_summary(stamp_dossier(tainted), ["assertion-copy"])
assert tainted_summary["independent_lineage_count"] == 0
assert tainted_summary["unknown_lineages"] == ["lineage-unknown"]
def test_private_only_mutation_cannot_change_public_projection() -> None:
first = stamp_dossier(fixture_material())
changed = fixture_material()
replacement = "A different private fixture note that must not affect public output."
changed["editions"][3] = edition(
"edition-private",
"work-private",
"private synthetic v2",
replacement,
visibility="private",
)
changed["spans"][3] = text_span(
"span-private",
"edition-private",
replacement,
visibility="private",
)
second = stamp_dossier(changed)
assert first["dossier_id"] != second["dossier_id"]
assert public_dossier(first) == public_dossier(second)
def test_all_adapters_preserve_one_disclosure_safe_dossier_identity() -> None:
source = stamp_dossier(fixture_material())
with pytest.raises(DossierValidationError, match="disclosure-safe public dossier"):
DossierProjection(source)
projection = DossierProjection.from_dossier(source)
json_document = json.loads(projection.json_text())
cli_document = json.loads(projection.cli_text())
api = projection.api_envelope()
mcp = projection.mcp_resource()
mcp_document = json.loads(mcp["text"])
identity = projection.id
assert json_document["dossier_id"] == identity
assert cli_document["dossier_id"] == identity
assert api["dossier_id"] == identity == api["data"]["dossier_id"]
assert mcp["_meta"]["dossier_id"] == identity
assert mcp_document["dossier_id"] == identity
assert identity in projection.markdown()
assert f'data-dossier-id="{identity}"' in projection.html()
assert quote(identity, safe="") in mcp["uri"]
for rendered in (
projection.json_text(),
projection.cli_text(),
projection.markdown(),
projection.html(),
mcp["text"],
):
assert "Private fixture note" not in rendered
Build receipt
Reproduce this projection
- Catalog
em:catalog:sha256:9bfc972213cba2cde167386103dc2c011ee74639fb7f0794c54120fbbdef1a5d- Frontier
em:frontier:sha256:f33be3eae4c75232d56750ef9a1aa79d96274ece3417d65a75c1391bf61a81bf- Accepted commit
f92846570180dfa4511263f8ba98ecd18f7772c9- Epistemic policy
commons-balanced-v0.1- Disclosure policy
public-noninterference-v0.1- Compiler
epistemedia/0.2.0