Two cadences for keeping heads in sync with your tagging:
- PASSIVE: a nightly `scheduled_train_heads` beat (skips if a run is already
in flight; creates+commits the run row before dispatching train_heads so the
ml worker always finds it). Folds the day's accepts/rejects + newly-eligible
concepts into the heads without anyone clicking.
- ACTIVE: a "Retrain heads" button in the Explore trail bar — bank the +/-
feedback you just gave while walking content, without a trip to Settings.
Shared logic in a new useHeadTraining composable (trigger + poll + start/finish
toasts), used by the Explore button; reflects an already-running run (incl. the
nightly one) on mount.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ttrj5P7upUTueSfoJcxEqa
Arrow keys walk the Explore breadcrumb trail: ← steps back, → goes forward to
an already-visited item or — with no forward history — jumps to a RANDOM
neighbour to keep the rabbit-hole going (operator-asked).
The trail gains a cursor (browser back/forward semantics): stepping back no
longer trims the forward branch, so → can return to it; a genuinely new walk
off a back-step truncates the stale branch then appends. The crumb-bar "current"
highlight follows the cursor, not the tip.
Arrows are ignored while typing a tag, but still navigate when the tag input is
focused-but-empty (it auto-focuses after every walk, so otherwise arrow-nav
would dead-end after one step). Modifier-key combos pass through untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ttrj5P7upUTueSfoJcxEqa
The panes grid had no explicit row, so the implicit `auto` row sized to its
tallest pane's content. With Provenance + Tags + a long Suggestions list, the
rail outgrew the fixed-height workspace, spilled over and made the WHOLE page
scrollable — showing as a weird empty gap at the top (operator-flagged
2026-06-26). grid-template-rows: minmax(0, 1fr) bounds the row to the container
so each pane's own overflow-y:auto scrolls internally instead. Reset to `none`
in the stacked (<=1100px) layout where the page is meant to scroll.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The post title/description frequently names the character, so surface it while
tagging in Explore (operator-asked 2026-06-26). ProvenancePanel gains optional
imageId/image props (default = modal store, so the modal is unchanged) since
provenance is its own system loaded by id; ExploreView renders it above TagPanel
in the right rail, hosted on the anchor. Self-collapses when the image has no
provenance.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Explore is a rapid walk-and-tag surface, so focus must keep returning to the tag
input with no extra click (operator-asked 2026-06-26). Two gaps closed:
- Navigation hardening: refocus on every focused-image change (neighbour click,
breadcrumb, Random image, seed) now runs nextTick → requestAnimationFrame, so
it lands AFTER the post-navigation re-render/paint instead of being stolen
back by the neighbour-grid re-render.
- All tag actions refocus, in both Explore and the modal: tag add (existing/new)
and remove now hand focus back like accept-suggestion already did; and the
rename + fandom-assignment dialogs refocus on @after-leave (fires after
Vuetify's own focus-return to the activator, so ours wins).
TagAutocomplete's mobile guard is preserved throughout (no soft-keyboard pop on
touch). Modal behaviour gains the same stickier focus — consistent, low-risk.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The workspace is built for rapid walk-and-tag, but the tag field was only
focused once (TagAutocomplete's on-mount autofocus) — walking to a neighbour
left focus behind, so the operator had to click the field each time
(operator-asked 2026-06-26).
TagPanel now exposes focusTagInput; ExploreView watches the focused image id and
re-focuses the field on seed + every walk via nextTick. Reuses the existing
focus path, so TagAutocomplete's mobile guard (no soft-keyboard pop on touch) is
preserved.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reworks Explore from "anchor + neighbour grid + cluster tag-gap rail" into a
persistent 3-pane workspace that unfolds the image modal so you can tag while
rabbit-holing (operator concept 2026-06-26):
- LEFT neighbour grid (larger thumbs), click = walk; breadcrumb retained.
- CENTER light viewer — reuses ImageCanvas + ImageMetaBar(:image) for the
focused image; "Open full viewer" still launches the overlay modal.
- RIGHT the modal's TagPanel, hosted on the anchor for modal-parity tagging
(chips, autocomplete, suggestions + Accept, fandom-on-chip, T/"/" focus).
Reuse without destabilising the audited modal store: TagPanel and
SuggestionsPanel gain an optional `host` prop (default = modal store, so the
image modal is unchanged); the explore store implements the same small
tag-CRUD surface (current/currentImageId + reloadTags/addExistingTag/
removeTag/createAndAdd) over the anchor. ImageMetaBar gains an optional
`image` prop for the same reason.
Drops the mass/cluster tagger (TagGapPanel deleted; clusterIds/thumbById
removed) — per-image tagging feeds the per-tag reference-embedding centroid
better than bulk ops.
Nav: keep the Explore tab but bare /explore now SEEDS a random image
(GET /api/showcase?limit=1 → /explore/:id) so the tab kick-starts a rabbit
hole; explicit meta.navOrder pins nav order (Explore after Gallery) since
router.getRoutes() doesn't preserve declaration order.
Note: the backend cluster tag-gaps route/service (#94a) is now frontend-orphaned
— left in place; flag for a separate cleanup.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cluster C frontend, milestone #94.
#94b Explore walk: new /explore/:imageId route + ExploreView + explore store.
Anchor (reuse /api/gallery/image), neighbour grid (reuse /api/gallery/similar,
24), click a neighbour to re-anchor; in-memory breadcrumb that trims on
backtrack (route is the source of truth). Empty/loading/error + no-embedding
states.
#94c tag-gap closing: components/explore/TagGapPanel — fetches
/api/images/cluster/tag-gaps for the anchor+neighbours, a consensus-threshold
slider (default 60%), per gap shows present/total + the missing thumbnails +
'Apply to N missing' → /api/tags/images/bulk/tags (source manual) → re-fetch.
#94d entry points: 'Explore' button in the modal RelatedStrip; the TopNav entry
comes free from the route's meta.title.
#4a metadata HUD + #4b split Download: new modal ImageMetaBar (always-on, above
ProvenancePanel) shows dimensions/size/type and a split Download button
(default Download, chevron → Copy link via utils/clipboard — no clipboard-image,
rule 95).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XCUHUGQLrBrkgyk1t49kpX