"""The Run Certificate — identity, tamper evidence, and honest incompleteness. The compiler's design record was already deterministic and already stated what it did not establish. What it could not do was prove it described the run it claimed to. A certificate is content-addressed: the id IS the hash, so nobody can rename a result into agreeing with them, and anyone holding the document can check it without a key, a service, or trusting us. Determinism is not a nicety here — it is the entire mechanism. If the same inputs could produce two ids, every property below collapses at once. """ import pytest from dee.core import certificate as C def _cert(**kw): base = dict(kind="compile", inputs={"variant": "NM_000518.5:c.20A>T", "offset": 60}, outputs={"route": "prime_editing", "n_pegrnas": 6}, not_established=["Assess specificity"]) base.update(kw) return C.build(**base) # --------------------------------------------------------------------------- # # Determinism — the mechanism everything else rests on # --------------------------------------------------------------------------- # def test_the_same_inputs_always_produce_the_same_id(): assert _cert()["id"] == _cert()["id"] def test_key_order_does_not_change_the_id(): """Two callers building the same facts in a different order must not mint two different certificates for one run.""" a = C.build(kind="k", inputs={"a": 1, "b": 2}, outputs={"x": 1}, not_established=[]) b = C.build(kind="k", inputs={"b": 2, "a": 1}, outputs={"x": 1}, not_established=[]) assert a["id"] == b["id"] def test_the_order_gaps_were_found_in_does_not_change_the_id(): a = _cert(not_established=["specificity", "consequence"]) b = _cert(not_established=["consequence", "specificity"]) assert a["id"] == b["id"] def test_float_noise_does_not_fork_a_certificate(): """0.1 + 0.2 must not mint a different document from 0.3.""" a = C.build(kind="k", inputs={"v": 0.1 + 0.2}, outputs={}, not_established=[]) b = C.build(kind="k", inputs={"v": 0.3}, outputs={}, not_established=[]) assert a["id"] == b["id"] def test_an_integral_float_and_an_int_agree(): a = C.build(kind="k", inputs={"n": 1.0}, outputs={}, not_established=[]) b = C.build(kind="k", inputs={"n": 1}, outputs={}, not_established=[]) assert a["id"] == b["id"] def test_nothing_in_the_payload_reads_a_clock_or_a_random_source(): """A timestamp would give one run two ids, which is exactly the failure the whole design exists to prevent. Time is the caller's metadata, kept outside the hashed payload. Checked against the parsed AST rather than the file text: the first version of this test grepped the source and failed on its own docstring, which says the words "random" and "clock" while importing neither. """ import ast tree = ast.parse(open("dee/core/certificate.py", encoding="utf-8").read()) imported = set() for node in ast.walk(tree): if isinstance(node, ast.Import): imported.update(a.name.split(".")[0] for a in node.names) elif isinstance(node, ast.ImportFrom) and node.module: imported.add(node.module.split(".")[0]) assert imported == {"hashlib", "json", "typing", "__future__"}, ( f"certificate.py imports {imported} — anything beyond hashing, " "serialisation and typing can make the id non-reproducible") # --------------------------------------------------------------------------- # # Refusal — a hash over a repr is worse than an error # --------------------------------------------------------------------------- # def test_an_uncanonicalisable_value_is_refused_not_stringified(): """Coercing with str() would produce a hash that looks authoritative and covers nothing — it fails silently, and only when somebody relies on it.""" class Thing: pass with pytest.raises(C.CanonicalError): C.build(kind="k", inputs={"o": Thing()}, outputs={}, not_established=[]) @pytest.mark.parametrize("bad", [float("nan"), float("inf"), float("-inf")]) def test_nan_and_infinity_are_refused(bad): """A certificate containing one could never be reproduced.""" with pytest.raises(C.CanonicalError): C.build(kind="k", inputs={"v": bad}, outputs={}, not_established=[]) def test_non_string_keys_are_refused(): with pytest.raises(C.CanonicalError): C.build(kind="k", inputs={1: "one"}, outputs={}, not_established=[]) # --------------------------------------------------------------------------- # # Tamper evidence # --------------------------------------------------------------------------- # def test_a_fresh_certificate_verifies(): ok, why = C.verify(_cert()) assert ok is True and "matches its id" in why @pytest.mark.parametrize("field,mutate", [ ("outputs", lambda c: c["outputs"].__setitem__("n_pegrnas", 99)), ("inputs", lambda c: c["inputs"].__setitem__("offset", 61)), ("kind", lambda c: c.__setitem__("kind", "something_else")), ]) def test_altering_any_field_breaks_the_id(field, mutate): cert = _cert() mutate(cert) ok, why = C.verify(cert) assert ok is False assert "altered since it was issued" in why def test_dropping_the_caveats_breaks_the_id(): """The most important tamper case: `not_established` is hashed with everything else, so you cannot quietly delete the gaps and keep the id.""" cert = _cert(not_established=["Assess specificity", "Assess consequence"]) assert C.verify(cert)[0] is True cert["not_established"] = [] ok, why = C.verify(cert) assert ok is False and "altered" in why def test_a_certificate_with_no_id_does_not_silently_pass(): ok, why = C.verify({"kind": "k", "inputs": {}, "outputs": {}}) assert ok is False and "nothing to check" in why def test_an_older_version_is_reported_as_such_not_as_tampering(): """An old certificate is valid under the rules it was minted with. Calling it 'altered' would be a false accusation.""" cert = _cert() cert["cert_version"] = "0" ok, why = C.verify(cert) assert ok is False assert "altered" not in why and "cert_version" in why def test_verify_survives_junk_without_raising(): for junk in (None, [], "cert", 7): ok, _ = C.verify(junk) assert ok is False # --------------------------------------------------------------------------- # # The rendered document # --------------------------------------------------------------------------- # def test_the_text_carries_its_own_self_check(): txt = C.render_text(_cert()) assert "SELF-CHECK PASS" in txt assert "No key required." in txt def test_a_tampered_certificate_renders_as_failing(): """It must not be possible to print a clean-looking document from altered content — the render calls verify rather than trusting the id.""" cert = _cert() cert["outputs"]["n_pegrnas"] = 0 assert "SELF-CHECK FAIL" in C.render_text(cert) def test_an_empty_gap_list_is_labelled_a_claim_not_an_absence(): """'Nothing unestablished' is an assertion someone should have to make on purpose, and a reader should see it as one.""" txt = C.render_text(_cert(not_established=[])) assert "That is a CLAIM, not an" in txt def test_the_document_disclaims_what_it_does_not_attest(): txt = C.render_text(_cert()) assert "not a claim that the design is" in txt assert "does not replace the review" in txt def test_gaps_are_listed_when_present(): txt = C.render_text(_cert(not_established=["Assess specificity"])) assert "- Assess specificity" in txt # --------------------------------------------------------------------------- # # End to end: a compile mints one, and anyone can check it # --------------------------------------------------------------------------- # from dee import server def _client(): app = server.create_app() app.config.update(TESTING=True) return app.test_client() class _Anon: user_id = None anonymous = True class _User: """The compiler is sign-in gated (_dna_signin_gate), so a compile needs a real user. Verification deliberately is NOT — see the test below.""" user_id = "u1" anonymous = False HBB = ("CCTGAGGAGAAGTCTGCCGTCACTGCCCTGTGGGGCAAGGTGAACGTGGATGAAGT" "TGGTGGTGAGGCCCTGGGCAGGCTGCTGGTGGTCTACCCTTGGACCCAGAGGTTCTTTGAGTCCTTTG") def _compile(monkeypatch, **body): monkeypatch.setattr(server._auth, "get_auth", lambda: _User()) payload = {"wt_allele": "G", "patient_allele": "C", "window": HBB, "offset": 66} payload.update(body) return _client().post("/api/compiler/compile", json=payload).get_json() def test_a_compile_mints_a_verifiable_certificate(monkeypatch): out = _compile(monkeypatch) cert = out["certificate"] assert cert and cert["id"] ok, _ = C.verify(cert) assert ok is True def test_the_same_compile_mints_the_same_id(monkeypatch): """Content-addressed means reproducible. If two identical compiles minted two ids the identifier would be noise.""" a = _compile(monkeypatch)["certificate"] b = _compile(monkeypatch)["certificate"] assert a["id"] == b["id"] def test_a_different_compile_mints_a_different_id(monkeypatch): a = _compile(monkeypatch)["certificate"] b = _compile(monkeypatch, offset=67)["certificate"] assert a["id"] != b["id"] def test_the_certificate_carries_the_gaps_the_report_declared(monkeypatch): """The compiler already reports what did not run. Hashing it means a downstream reader cannot receive a certificate whose caveats were removed in transit and still have the id check out.""" out = _compile(monkeypatch) assert out["certificate"]["not_established"] == sorted(out["incomplete_because"]) assert "Assess specificity" in out["certificate"]["not_established"] def test_the_window_is_hashed_not_embedded(monkeypatch): """A certificate is quoted in methods sections and pasted into email. It should identify the sequence it ran on without republishing it.""" out = _compile(monkeypatch) inputs = out["certificate"]["inputs"] assert HBB not in json_dumps(inputs) assert len(inputs["window_sha256"]) == 16 assert inputs["window_length"] == len(HBB) def json_dumps(o): import json return json.dumps(o) def test_verification_is_public_and_needs_no_account(monkeypatch): """A document only its issuer can verify is not evidence.""" cert = _compile(monkeypatch)["certificate"] # Signed OUT from here: the whole point is that a stranger can check it. monkeypatch.setattr(server._auth, "get_auth", lambda: _Anon()) res = _client().post("/api/certificate/verify", json={"certificate": cert}) assert res.status_code == 200 body = res.get_json() assert body["valid"] is True and body["id"] == cert["id"] def test_the_endpoint_detects_a_tampered_certificate(monkeypatch): cert = _compile(monkeypatch)["certificate"] cert["outputs"]["n_pegrnas"] = 999 body = _client().post("/api/certificate/verify", json={"certificate": cert}).get_json() assert body["valid"] is False assert "altered since it was issued" in body["explanation"] def test_the_endpoint_rejects_junk(): res = _client().post("/api/certificate/verify", json={"certificate": "nope"}) assert res.status_code == 400