"""Rekordy-pułapki (canary) — DAN-26. Testujemy sam MECHANIZM na syntetycznych pułapkach: prawdziwe markery i injekcja do baz przychodzą od właściciela produktu. Regresja byłaby CICHA i podwójnie zła: albo pułapka wycieka do interpretacji/LLM (zdradza się i psuje wynik), albo przestaje odsiewać i nie wiadomo o tym. """ import pathlib from app import canary MAIN = (pathlib.Path(__file__).resolve().parents[1] / "app" / "main.py").read_text(encoding="utf-8") MARK = "ASTROLOLO-CANARY-7f3a9" # unikalny — nie wystąpi w realnych danych ROWS = [ {"significator": "Ma Ari", "effect": "odważny, impulsywny"}, {"significator": "Ve Tau " + MARK, "effect": "pułapka — nie dotknie interpretacji"}, {"significator": "Su Leo", "effect": "dumny, twórczy"}, ] def test_no_markers_is_transparent(): """Bez skonfigurowanych markerów — zero ingerencji, zero kosztu.""" out, rep = canary.screen(ROWS, "cokolwiek", markers=[]) assert out == ROWS and rep["active"] is False def test_canary_row_is_fenced_from_results(): """Pułapka znika z wyników — nie opuści warstwy danych (a więc i promptu LLM).""" out, rep = canary.screen(ROWS, "Ve Tau", markers=[MARK]) assert rep["active"] and rep["removed"] == 1 assert all(MARK not in str(r) for r in out) # nigdzie nie ma markera assert len(out) == 2 and {"significator": "Su Leo", "effect": "dumny, twórczy"} in out def test_real_results_pass_through_untouched(): out, _ = canary.screen(ROWS, "Ari", markers=[MARK]) assert {"significator": "Ma Ari", "effect": "odważny, impulsywny"} in out def test_tripwire_when_query_targets_a_marker(): """Zapytanie CELUJĄCE w marker = ktoś enumeruje bazę, nie liczy horoskopu.""" _, rep = canary.screen(ROWS, "Ve Tau " + MARK, markers=[MARK]) assert rep["tripwire"] is True def test_normal_query_does_not_trip(): _, rep = canary.screen(ROWS, "Ma Ari", markers=[MARK]) assert rep["tripwire"] is False def test_marker_matched_in_any_string_field(): rows = [{"significator": "X", "effect": "opis " + MARK, "extra": 5}] out, rep = canary.screen(rows, "X", markers=[MARK]) assert out == [] and rep["removed"] == 1 # marker w polu 'effect' też łapiemy def test_endpoint_fences_before_returning(): """/search odsiewa pułapki na wyjściu z warstwy danych (niezależnie od dostawcy).""" assert "canary.screen(result.rows, query.value)" in MAIN assert "result.rows = visible" in MAIN