feat(ml): clamp allowlist min_confidence to the tagger store floor
CI / integration (push) Successful in 3m12s
CI / lint (push) Successful in 2s
CI / frontend-build (push) Successful in 17s
CI / backend-lint-and-test (push) Successful in 27s

Consumer #4 of the store-floor change (#764). An allowlist tag can't
auto-apply more permissively than the ingest floor — predictions below
tagger_store_floor aren't stored, so a lower min_confidence behaves
identically to the floor. update_threshold now clamps to max(value, floor);
the AllowlistTable confidence input min-binds to the live floor and clamps
on edit. Keeps the stored threshold honest about actual apply behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-10 13:52:20 -04:00
parent 3f92669f12
commit c8b815afe6
3 changed files with 42 additions and 6 deletions
+14
View File
@@ -104,3 +104,17 @@ async def test_update_threshold_and_remove(db):
assert abs(row.min_confidence - 0.80) < 1e-6
await svc.remove(tag.id)
assert await db.get(TagAllowlist, tag.id) is None
@pytest.mark.asyncio
async def test_update_threshold_clamped_to_store_floor(db):
# A min_confidence below the store floor (default 0.70) is clamped up —
# predictions below the floor aren't stored, so a lower threshold can't
# apply more permissively than the floor (#764).
tag = await TagService(db).find_or_create("Lowthr", TagKind.general)
svc = AllowlistService(db)
img = await _make_image(db)
await svc.accept(img.id, tag.id)
await svc.update_threshold(tag.id, 0.30)
row = await db.get(TagAllowlist, tag.id)
assert abs(row.min_confidence - 0.70) < 1e-6