feat: check-assets ↔ KI gekoppelt — byte-getauschte Bilder neu bewerten
Da bekannte Bilder aus Effizienzgründen nicht jeden Scan neu geladen werden (url_hashes), prüfte die KI einen späteren Byte-Tausch eines bekannten Bildes nicht von selbst erneut. Lücke geschlossen: Erkennt die Datei-Prüfung (check-assets) eine geänderte Bilddatei, wird deren URL über BaselineManager.invalidate_ai_url_hashes aus der Hash-Erinnerung entfernt → nächster Scan lädt das Bild neu, neue Bytes = neuer Hash = Cache-Miss = die KI bewertet den Inhalt neu. Einhängung in cmd_scan (vor run_ai_analysis → Neubewertung noch im selben Scan) und cmd_check_assets. Integritäts- und Inhaltsprüfung greifen so ineinander. Tests: 260 grün (+2: invalidate entfernt nur die genannten URLs; geändertes Bild wird nach Invalidierung neu geladen und beanstandet). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
4db5817013
commit
78dc79ceab
4 changed files with 80 additions and 2 deletions
|
|
@ -287,6 +287,49 @@ class TestImages:
|
|||
m2.assert_not_called()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# check-assets ↔ KI-Kopplung: geänderte Bilder werden neu bewertet
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestAssetAiCoupling:
|
||||
def _cfg_img(self):
|
||||
cfg = _cfg()
|
||||
cfg["ai_analysis"]["text"]["enabled"] = False
|
||||
cfg["ai_analysis"]["image"]["enabled"] = True
|
||||
return cfg
|
||||
|
||||
def test_invalidate_removes_only_given_urls(self, tmp_path):
|
||||
bm = BaselineManager(tmp_path)
|
||||
bm.save_ai_ledger({"entries": {}, "url_hashes": {"a": "h1", "b": "h2", "c": "h3"}})
|
||||
assert bm.invalidate_ai_url_hashes(["b", "x"]) == 1 # x ist nicht vorhanden
|
||||
assert set(bm.load_ai_ledger()["url_hashes"]) == {"a", "c"}
|
||||
|
||||
def test_changed_image_reanalyzed_after_invalidation(self, tmp_path, monkeypatch):
|
||||
"""Byte-Tausch eines bekannten Bildes → invalidieren → KI lädt+bewertet neu."""
|
||||
monkeypatch.setenv("OPENROUTER_API_KEY", "test")
|
||||
bm = BaselineManager(tmp_path)
|
||||
cfg = self._cfg_img()
|
||||
snap = _snap("kurz", img=[{"url": "https://x.de/logo.png", "class": "internal"}])
|
||||
|
||||
with patch("scanner.ai_analyzer.fetch_asset_hashes",
|
||||
return_value={"https://x.de/logo.png": {"sha256": "OLD", "size": 1, "error": None}}), \
|
||||
patch("scanner.ai_analyzer._openrouter_chat", return_value=_verdict()):
|
||||
run_ai_analysis(cfg, bm, snap, {})
|
||||
|
||||
# check-assets erkennt Byte-Änderung → Kopplung invalidiert die URL
|
||||
assert bm.invalidate_ai_url_hashes(["https://x.de/logo.png"]) == 1
|
||||
|
||||
new = _verdict("pornography", "high", 0.95)
|
||||
with patch("scanner.ai_analyzer.fetch_asset_hashes",
|
||||
return_value={"https://x.de/logo.png": {"sha256": "NEW", "size": 1, "error": None}}) as f2, \
|
||||
patch("scanner.ai_analyzer._openrouter_chat", return_value=new) as c2:
|
||||
res = run_ai_analysis(cfg, bm, snap, {})
|
||||
f2.assert_called() # neu geladen (URL war invalidiert)
|
||||
c2.assert_called() # neue Bytes (NEW) → Cache-Miss → neu analysiert
|
||||
assert res["api_calls"] == 1
|
||||
assert len(res["findings"]) == 1 # jetzt beanstandet
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Scoring: cap at yellow
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue