feat(ml): CCIP references exclude unconfirmed auto character tags + confirm trips detectors (m139)
Completes "no self-training": unconfirmed auto-applied character tags no longer seed CCIP references — character_references + the prototype builder (_current_fingerprints/_rebuild_one) gain a shared _positive_char_tag filter (human-applied OR operator-confirmed), mirroring the head-positive exclusion. Confirming a tag also has to move the change-detectors, or an incremental refresh/Retrain right after a confirm wouldn't fold the tag in (only the nightly full pass would): the CCIP global gate now counts character confirmations, and the head training fingerprint counts confirmations. Test for the CCIP path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CDgx8bQS5YrGRK76v8HUnM
This commit is contained in:
@@ -12,6 +12,7 @@ from backend.app.models import (
|
||||
MLSettings,
|
||||
Tag,
|
||||
TagKind,
|
||||
TagPositiveConfirmation,
|
||||
)
|
||||
from backend.app.models.tag import image_tag
|
||||
from backend.app.services.ml.character_prototypes import (
|
||||
@@ -141,6 +142,27 @@ def test_multi_character_image_not_referenced(db_sync):
|
||||
assert _proto_count(db_sync, daphne.id) == 0
|
||||
|
||||
|
||||
def test_unconfirmed_auto_char_tag_not_referenced(db_sync):
|
||||
# A single-character image whose ONLY character tag was AUTO-applied
|
||||
# (unconfirmed) must NOT seed a prototype — else CCIP self-trains on its own
|
||||
# guess (milestone 139). Confirming it (which trips the global gate) makes it
|
||||
# a reference.
|
||||
raven = _char(db_sync, "Raven")
|
||||
img = _img(db_sync, "z" * 64)
|
||||
_figure(db_sync, img.id)
|
||||
db_sync.execute(image_tag.insert().values(
|
||||
image_record_id=img.id, tag_id=raven.id, source="ccip_auto",
|
||||
))
|
||||
db_sync.commit()
|
||||
refresh_character_prototypes(db_sync)
|
||||
assert _proto_count(db_sync, raven.id) == 0
|
||||
|
||||
db_sync.add(TagPositiveConfirmation(image_record_id=img.id, tag_id=raven.id))
|
||||
db_sync.commit()
|
||||
refresh_character_prototypes(db_sync)
|
||||
assert _proto_count(db_sync, raven.id) == 1
|
||||
|
||||
|
||||
def test_lost_references_are_removed(db_sync):
|
||||
raven = _char(db_sync, "Raven")
|
||||
img = _img(db_sync, "e" * 64)
|
||||
|
||||
Reference in New Issue
Block a user