Spaces:
Running
Running
| """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=[]) | |
| 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 | |
| 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 | |