feat(suggestions): group wip/banner/editor under a separate 'system' category
System tags are kind=general, so their suggestions previously landed in the General group. Give them their own 'system' suggestion category so the operator reviews them apart from content tags: _current_heads maps is_system heads to category 'system' (still trained as general heads, still gated by the 0.65 floor). Frontend: CATEGORY_ORDER/LABELS gain 'system'; SuggestionsPanel renders a 'System' group first (small, collapsible, open — false positives easy to spot and reject); the typed-dropdown shows the shield icon for system entries. Safe: system-tag suggestions always carry a canonical_tag_id, so the create-by-kind path (which would send 'system' as a TagKind) is never hit. 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:
@@ -124,9 +124,11 @@ async def test_system_tag_surfaces_at_flat_floor_despite_high_threshold(db):
|
||||
await _head(db, tag.id, slot=0, suggest_threshold=0.9)
|
||||
await db.commit()
|
||||
sl = await SuggestionService(db).for_image(img.id)
|
||||
# System tags surface under their OWN "system" category, not "general".
|
||||
assert any(
|
||||
s.canonical_tag_id == tag.id for s in sl.by_category.get("general", [])
|
||||
s.canonical_tag_id == tag.id for s in sl.by_category.get("system", [])
|
||||
)
|
||||
assert not sl.by_category.get("general")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -139,7 +141,7 @@ async def test_system_tag_below_floor_stays_hidden(db):
|
||||
await _head(db, tag.id, slot=0, suggest_threshold=0.9)
|
||||
await db.commit()
|
||||
sl = await SuggestionService(db).for_image(img.id)
|
||||
assert not sl.by_category.get("general")
|
||||
assert not sl.by_category.get("system")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
||||
Reference in New Issue
Block a user