feat(system-tags): process vs chrome groups + WIP provisional auto-apply (#1464)
Backend for the system-tag behavior refactor (milestone #157). editor screenshot moves from chrome (hidden) to the PROCESS group (shown, like wip); wip+editor gain provisional auto-apply so they stop needing endless manual identification — without a runaway loop. - tag.py: split PRESENTATION_SYSTEM_TAGS → CHROME_SYSTEM_TAGS (banner) + PROCESS_SYSTEM_TAGS (wip, editor screenshot). - heads.py: generalize presentation_auto_apply_sweep → system_tag_auto_apply_sweep (mode chrome|process). Same Guard 1 (skip human/confirmed) + Guard 2 (ring-loud conflict → PresentationReview). process mode uses source 'process_auto' and does NOT hide (hide is a gallery-query effect of group membership). - training_data._AUTO_SOURCES += 'process_auto' → the head never trains on its own auto-applied output; only wip_title/manual train it (the runaway break). - ml_settings: process_auto_apply_enabled (OFF, opt-in) + threshold + conflict threshold. presentation_review.mode ('chrome'|'process'). Migration 0086. - gallery_service: default-hide reads CHROME only (editor now shows); Explore neighbors exclude the whole PROCESS group. - tasks/ml + celery beat: scheduled_process_auto_apply (daily, opt-in); prune covers both modes. - api: ml_admin process_* CRUD+validation; hidden-review returns mode. - tests: rename chrome sweep calls; new test_process_auto_apply (apply, guards, mode flag, no-self-train); gallery test asserts editor now visible. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -15,7 +15,7 @@ from backend.app.models import (
|
||||
from backend.app.models.tag import image_tag
|
||||
from backend.app.services.ml.heads import (
|
||||
auto_apply_sweep,
|
||||
presentation_auto_apply_sweep,
|
||||
system_tag_auto_apply_sweep,
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.integration
|
||||
@@ -70,7 +70,7 @@ def test_presentation_sweep_hides_chrome(db_sync):
|
||||
_head(db_sync, banner.id, 0, weight=3.0)
|
||||
img = _img(db_sync, "a" * 64, _emb(0))
|
||||
db_sync.commit()
|
||||
res = presentation_auto_apply_sweep(db_sync)
|
||||
res = system_tag_auto_apply_sweep(db_sync, mode="chrome")
|
||||
assert res["n_applied"] == 1
|
||||
assert _source(db_sync, img.id, banner.id) == "presentation_auto"
|
||||
|
||||
@@ -86,7 +86,7 @@ def test_presentation_sweep_hard_skips_valued_image(db_sync):
|
||||
db_sync.execute(image_tag.insert().values(
|
||||
image_record_id=img.id, tag_id=content.id, source="manual"))
|
||||
db_sync.commit()
|
||||
res = presentation_auto_apply_sweep(db_sync)
|
||||
res = system_tag_auto_apply_sweep(db_sync, mode="chrome")
|
||||
assert res["n_applied"] == 0
|
||||
assert _source(db_sync, img.id, banner.id) is None
|
||||
|
||||
@@ -102,7 +102,7 @@ def test_presentation_sweep_flags_conflict(db_sync):
|
||||
_head(db_sync, content.id, 0, weight=1.0) # content head also fires
|
||||
img = _img(db_sync, "c" * 64, _emb(0))
|
||||
db_sync.commit()
|
||||
res = presentation_auto_apply_sweep(db_sync)
|
||||
res = system_tag_auto_apply_sweep(db_sync, mode="chrome")
|
||||
assert res["n_applied"] == 1
|
||||
assert res["n_flagged"] == 1
|
||||
assert _source(db_sync, img.id, banner.id) == "presentation_auto"
|
||||
@@ -123,7 +123,7 @@ def test_presentation_sweep_disabled_is_noop(db_sync):
|
||||
_head(db_sync, banner.id, 0, weight=3.0)
|
||||
img = _img(db_sync, "d" * 64, _emb(0))
|
||||
db_sync.commit()
|
||||
res = presentation_auto_apply_sweep(db_sync)
|
||||
res = system_tag_auto_apply_sweep(db_sync, mode="chrome")
|
||||
assert res["n_applied"] == 0
|
||||
assert _source(db_sync, img.id, banner.id) is None
|
||||
|
||||
@@ -134,7 +134,7 @@ def test_presentation_sweep_ignores_wip(db_sync):
|
||||
_head(db_sync, wip.id, 0, weight=3.0)
|
||||
img = _img(db_sync, "e" * 64, _emb(0))
|
||||
db_sync.commit()
|
||||
res = presentation_auto_apply_sweep(db_sync)
|
||||
res = system_tag_auto_apply_sweep(db_sync, mode="chrome")
|
||||
assert res["n_applied"] == 0
|
||||
assert _source(db_sync, img.id, wip.id) is None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user