Appearance
Managing visual tags
In the admin: Media library — visual-tag review lives on the library cards (#1370; the old
/admin/media-tagsscreen now redirects here).What/why: Content & media — what this screen manages and why it exists.
Purpose: review the AI-proposed tags that describe what each image depicts — accept or reject them — so imagery is classified against the same controlled vocabulary the media library uses, without an analyzer ever silently changing the taxonomy.
Since #1370 the review is part of the media library (/admin/media):
- every card shows its AI visual tags as status-coded chips (proposed / rejected) next to a real thumbnail, and a proposed chip carries inline ✓/✕;
- select assets (the same multi-select used for bulk tagging) and use Accept AI tags / Reject AI tags in the bulk bar to decide every proposed tag on the selection — across all axes the AI proposes — in one action;
- each bulk decision is provenance-stamped (AI-proposed → human-decided, dated) and undoable per batch: the status line offers "Undo this batch", which reverts only what is still in the state the batch set (a tag someone re-decided afterwards is never clobbered) — an accept batch's undo removes the promoted classification tags and re-seeds the proposals;
- review pages with the library (server-side pagination, #375) — no full-table load at 18.8k scale;
- the coverage filter (#1371) drives the queues: AI-proposed, unreviewed pages straight to the review backlog; Untagged is the classification gap (project membership doesn't count as classification); Not in a shot group feeds the bulk-suggest workflow — each composes with project scope and sort;
- Run AI analysis (page header) runs the pass that proposes tags (#1188 vision adapter when egress is enabled, deterministic stub otherwise).
When to use
- After an analysis pass has run and proposals are waiting for review.
- Auditing which visual tags are live on imagery, or re-running the pass after new media has been synced.
Prerequisites
- Admin access with the
edit_datacapability (anydata_editororadminrole). - Referenced media to analyze — synced from nanawall.com (see Managing media).
Steps
- Open Admin → Visual tags (
/admin/media-tags). The header counts what's to review, live, and rejected. - To generate proposals, click Run analysis pass. The pass is cost-bounded — it analyzes a batch of images per run and defers the rest (the flash message reports how many were analyzed, unchanged, and deferred); re-run it to work through the catalog. Nothing is applied silently — every proposal lands as a proposed row.
- For each proposal:
- Accept — the tag is promoted to a real classification tag (#1805): it appears on the asset's Classification tab with an
aiprovenance badge, and the audit trail records who accepted it and when. - Reject — the proposal is remembered and never re-proposed for that image/tag.
- Accept — the tag is promoted to a real classification tag (#1805): it appears on the asset's Classification tab with an
- Every accept/reject and each pass run is recorded in the audit trail.
Behavior guarantees
- Proposals are never live until accepted; rejected proposals are never re-proposed.
- Accepted proposals live in
media_tags— the single live store (#1805) — withsource='ai'; the review table holds only the inbox and the rejection memory. - The pass is idempotent — an image already analyzed against its current state is skipped unless you force a re-analysis, so a re-run never churns reviewed tags.
- Provenance is explicit: a proposal is
ai; once accepted, the live classification tag keepssource='ai'so its origin never disappears, and the audit trail records who accepted it and when.
Running the pass from the CLI
For a large batch, run the pass against the local dev database directly:
npm run media:analyze # up to the default budget
npm run media:analyze -- --max 2000 # a bigger batch
npm run media:analyze -- --force # re-analyze every imageIt prints a cost/throughput report (assets scanned, analyzed, unchanged, deferred; tags proposed; embeddings written).
How similarity works
Each analyzed image also gets a stored similarity embedding, so "assets like this" is a bounded cosine query over the embedding store. Per the decision on this build, the shipped analyzer and embedder are deterministic stubs behind a pluggable adapter seam — a real vision model is a later one-adapter swap that leaves the review, provenance, and similarity paths unchanged. The review workflow mirrors the content-tags review pattern.