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:
@@ -31,7 +31,7 @@ from ..models import (
|
||||
Tag,
|
||||
TagPositiveConfirmation,
|
||||
)
|
||||
from ..models.tag import PRESENTATION_SYSTEM_TAGS, WIP_SYSTEM_TAG, image_tag
|
||||
from ..models.tag import CHROME_SYSTEM_TAGS, PROCESS_SYSTEM_TAGS, image_tag
|
||||
from .pagination import decode_cursor, encode_cursor
|
||||
from .tag_query import (
|
||||
fandom_join_alias,
|
||||
@@ -419,16 +419,17 @@ class GalleryService:
|
||||
async def _hidden_tag_ids(
|
||||
self, include_hidden, tag_ids, tag_or_groups,
|
||||
) -> list[int] | None:
|
||||
"""Presentation-chrome tag ids to implicitly exclude from a gallery query,
|
||||
or None. None when the caller asked to include hidden, when the operator
|
||||
is explicitly filtering FOR a presentation tag (they clearly want to see
|
||||
it), or when no presentation tags exist. (milestone 141)"""
|
||||
"""Chrome (banner) tag ids to implicitly exclude from a gallery query, or
|
||||
None. None when the caller asked to include hidden, when the operator is
|
||||
explicitly filtering FOR a chrome tag (they clearly want to see it), or when
|
||||
no chrome tags exist. (milestone 141; #1464: editor screenshot is now PROCESS
|
||||
— shown — so only `banner` hides here.)"""
|
||||
if include_hidden:
|
||||
return None
|
||||
rows = await self.session.execute(
|
||||
select(Tag.id).where(
|
||||
Tag.is_system.is_(True),
|
||||
Tag.name.in_(PRESENTATION_SYSTEM_TAGS),
|
||||
Tag.name.in_(CHROME_SYSTEM_TAGS),
|
||||
)
|
||||
)
|
||||
pres = [r[0] for r in rows]
|
||||
@@ -749,15 +750,16 @@ class GalleryService:
|
||||
eff = _effective_date_col()
|
||||
stmt = select(ImageRecord, Post.post_date, eff.label("eff"))
|
||||
stmt = _outer_join_primary_post(stmt)
|
||||
# Presentation images (banner / editor-screenshot system tags, #128)
|
||||
# cluster on UI chrome rather than content, so near any one of them
|
||||
# they'd fill the grid. Excluded from CANDIDATES only — the anchor
|
||||
# itself may be a banner. `wip` stays surfaced here by default (real art;
|
||||
# only the training pipelines exclude it), but the Explore rabbit-hole
|
||||
# passes exclude_wip to also drop work-in-progress (operator, 2026-07-08).
|
||||
excluded_system_tags = PRESENTATION_SYSTEM_TAGS
|
||||
# Chrome (banner, #128) clusters on UI rather than content, so near any one
|
||||
# of them they'd fill the grid → excluded from CANDIDATES always (the anchor
|
||||
# itself may be a banner). PROCESS art (wip / editor screenshot) stays
|
||||
# surfaced here by default (real content; only the training pipelines exclude
|
||||
# it), but the Explore rabbit-hole passes exclude_wip to also drop the whole
|
||||
# process group so a browse doesn't keep surfacing work-in-progress
|
||||
# (operator, 2026-07-08; #1464 — editor now rides with wip here).
|
||||
excluded_system_tags = CHROME_SYSTEM_TAGS
|
||||
if exclude_wip:
|
||||
excluded_system_tags = (*PRESENTATION_SYSTEM_TAGS, WIP_SYSTEM_TAG)
|
||||
excluded_system_tags = (*CHROME_SYSTEM_TAGS, *PROCESS_SYSTEM_TAGS)
|
||||
presentation = (
|
||||
select(image_tag.c.image_record_id)
|
||||
.join(Tag, Tag.id == image_tag.c.tag_id)
|
||||
|
||||
Reference in New Issue
Block a user