"""Entity-preserving MT — #000056 §9 (the validated lever). Deterministic detection + mask/restore round-trip + the MaskedTranslator protocol wrapper. No model, no network. """ from __future__ import annotations from arborist.qa.mt import StubTranslator from arborist.qa.mt.entity_mask import MaskedTranslator, mask, protect_spans, restore def _spans(text): return [text[s:e] for s, e in protect_spans(text)] def test_detects_capitalised_runs_and_quotes_not_function_words(): assert _spans("who is Paul of Tarsus?") == ["Paul of Tarsus"] assert _spans("when was the Eiffel Tower built?") == ["Eiffel Tower"] assert _spans("a bridge between New London & Groton?") == ["New London & Groton"] # quoted span keeps the quote chars (restored verbatim — harmless) assert _spans('what does "winter is coming" mean?') == ['"winter is coming"'] # wh / function lead word is NOT an entity; lowercase noun isn't either. assert _spans("what is anarchocapitalism?") == [] assert _spans("how does intel compare to amd?") == [] def test_mask_restore_round_trips_exactly(): q = "who wrote the play Hamlet?" m, mp = mask(q) assert "Hamlet" not in m and "ZQX0XQZ" in m assert restore(m, mp) == q # Restore tolerates MT mangling the sentinel's case/spacing. assert restore("Quien escribio la obra zqx 0 xqz?", mp) == \ "Quien escribio la obra Hamlet?" def test_masked_translator_preserves_entity_through_a_mangling_engine(): # Engine that lowercases everything it actually sees — would destroy # "Hamlet" if it reached MT. Masking keeps it verbatim. mangle = StubTranslator(fn=lambda t, s, g: t.lower()) mt = MaskedTranslator(mangle) out = mt.translate("who wrote the play Hamlet?", "en", "es") assert "Hamlet" in out # entity survived the mangler assert out.startswith("who") # non-entity text still translated def test_graceful_degrade_propagates(): dead = StubTranslator(fn=lambda *a: "x", available=False) mt = MaskedTranslator(dead) assert mt.available is False # Inner unavailable → original text back (sandwich → Phase-0). assert mt.translate("who is Paul of Tarsus?", "es", "en") == \ "who is Paul of Tarsus?" def test_engine_identity_carries_mask_policy(): mt = MaskedTranslator(StubTranslator(engine_id="opus-mt-v1")) assert "entmask-v1" in mt.engine_id assert mt.manifest_hash.endswith(":entmask-v1")