ad2a5fc5fe
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>
49 lines
2.2 KiB
Python
49 lines
2.2 KiB
Python
"""PresentationReview — a system-tag the auto-apply sweep applied that ALSO looked
|
|
like real content, flagged for operator review (milestone 141 + #1464).
|
|
|
|
When a sweep applies a system tag but the image ALSO scores highly on a content
|
|
head, it still applies the tag but records this row so a review strip can surface
|
|
it ("⚠ also looks like <conflict tag>"). Two modes (#1464): 'chrome' (banner —
|
|
image is HIDDEN, review is keep-hidden / un-hide) and 'process' (wip / editor
|
|
screenshot — image stays VISIBLE, review is confirm / remove-tag). Resolved rows
|
|
are pruned by retention.
|
|
"""
|
|
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import DateTime, Float, ForeignKey, String, func
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from .base import Base
|
|
|
|
|
|
class PresentationReview(Base):
|
|
__tablename__ = "presentation_review"
|
|
|
|
image_record_id: Mapped[int] = mapped_column(
|
|
ForeignKey("image_record.id", ondelete="CASCADE"), primary_key=True
|
|
)
|
|
# The presentation tag that was auto-applied (banner / editor screenshot).
|
|
tag_id: Mapped[int] = mapped_column(
|
|
ForeignKey("tag.id", ondelete="CASCADE"), primary_key=True
|
|
)
|
|
# The content tag the image ALSO scored high on — the "concerning" signal.
|
|
# SET NULL (not CASCADE): losing the conflict tag shouldn't erase the flag.
|
|
conflict_tag_id: Mapped[int | None] = mapped_column(
|
|
ForeignKey("tag.id", ondelete="SET NULL"), nullable=True
|
|
)
|
|
conflict_score: Mapped[float] = mapped_column(Float, nullable=False)
|
|
# Which sweep flagged this (#1464): 'chrome' (banner, hidden) or 'process'
|
|
# (wip / editor screenshot, shown). Drives which review strip surfaces it and
|
|
# what "resolve" means (un-hide vs remove-tag). Existing rows backfill 'chrome'.
|
|
mode: Mapped[str] = mapped_column(
|
|
String(16), nullable=False, default="chrome", server_default="chrome"
|
|
)
|
|
created_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), nullable=False, server_default=func.now()
|
|
)
|
|
# Set when the operator keeps-hidden or un-hides; retention prunes resolved.
|
|
resolved_at: Mapped[datetime | None] = mapped_column(
|
|
DateTime(timezone=True), nullable=True
|
|
)
|