You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The annotation workspace is being redesigned around one idea: the editor is where annotation work happens, start to finish. Class selection moves out of a side-panel tab and into a top-bar combobox with typeahead and a create-new escape hatch; the side panel becomes a single Annotations view (tag chips + object list + per-row reassignment); the top bar reorganizes into three zones with exactly one workflow primary rendered from allowed_actions; undo/redo become visible controls; and a new ratified design principle says no flow may force the annotator out of the editor and no exit may lose work. Behind it, schema versions gain a nullable provenance so versions published mid-annotation can be collapsed in the history instead of burying the curated ones. Every product decision below is settled; the four work streams that follow are execution.
Decision record
Decision (Armando, 2026-08-05) — supersedes any prior direction:
Class selection moves to a top-bar combobox (swatch + name + hotkey readout;
typeahead; hotkeys 1–9 stay global). The Labels tab is removed.
The side panel becomes a single "Annotations" view: a classification-tag chip strip
(when the pinned schema declares tag classes) above the objects list. No tabs. The
Tabs segmented variant is retired.
Top bar reorganizes into three zones (location / class / workflow); the Save button
is removed (⌘S + save-state text remain); exactly one workflow primary rendered
from allowed_actions; Skip stays visible as a secondary; zoom + fullscreen move
to a floating widget on the stage.
Undo/redo become visible tool-strip buttons (shortcuts unchanged).
Design principle 10 (ratified, immovable): the annotation workspace is
self-sufficient — no flow may force navigation out of the editor, and no exit may
lose work. Back/grid navigation must save-or-ask first.
Schema versions gain a nullable provenance (curated | annotation); the
version history collapses consecutive annotation runs into one expandable row;
milestones always render individually; diffs stay fetched on demand (option D3).
No schema-scoped capability is introduced (option E1): publishing is refused by
facts on disk; the dialog keeps gating on BatchAction.REPIN + the 409.
Out of scope, tracked separately: server-side schema draft entity;
canvas-anchored reassignment picker; assisted pre-annotation; any
publish-and-repin-project kernel operation; F14.
Work streams
Sequential — they share AnnotationPage.tsx above all. One worktree, one PR, merged green before the next starts. Every WS PR body carries cf. #<this issue>; the WS4 PR closes it.
WS1 — Backend: schema provenance.SchemaProvenance StrEnum, nullable field on AnnotationSchema, keyword-only provenance on SchemaService.create_version, migration 5 (schema_provenance, FORMAT_VERSION → 5), wire field on SchemaVersionCreate/SchemaVersionOut, and each writing surface declaring its own value (browser Schema tab and CLI schema apply → curated; AddClassDialog → annotation; MCP gains an optional parameter defaulting to curated). Existing versions are never backfilled.
WS2 — Combobox primitive, top bar, tool strip, navigation guard. An in-house Combobox (no new dependency), the top-bar class field with a C host action and a Create class "<text>" no-match row, the three-zone top bar with a single workflow primary derived from allowed_actions, the floating zoom/fullscreen widget, undo/redo in the tool strip, and the principle-10 save-first guard on back and grid.
WS3 — The Annotations panel. Tabs removed; filter input; classification-tag chip strip preserving the Labels tab's only non-selection capability; per-row class reassignment with geometry-incompatible classes disabled and the reason inline; activeClass/onActivateClass dropped from the panel entirely; the segmented Tabs variant retired.
WS4 — Dialog sessions, badge popover, version history.Create and add another accumulating into one published version, the v{n} badge as a pin-vs-active popover with an on-demand diff, and consecutive annotation-provenance versions collapsed into one expandable row in VersionNavigator.
Invariants that hold across all four
Kernel purity and the headless-annotator boundary (AGENTS.md) are never relaxed.
The frontend never computes legality: it renders allowed_actions and refusal prose from the wire. No new client-side gating rules.
classColor stays the single colour derivation; ClassFields stays the single class form.
Annotations are validated against the batch pin only; nothing reads the project's active version on a write path.
Schema versions stay immutable, 1..N, additive-by-publish. No update, no delete.
Hiding is a view concern: nothing about visibility enters the document/store commands.
Copy per DESIGN.md: sentence case, no "successfully", errors = what happened + what to do.
Visual context — the surfaces as they ship today
Four screenshots of the current state accompany this issue (attached separately; see the comment below). What they establish:
Project → Schema tab.Version 1 active · saving creates v2, a Why this version? (optional) note field, Add class, Save version; the class list filter; the ClassFields form (name, geometry with Singular — picking a class picks a tool., colour with Derived from name / Derive, hotkey chip, attributes block); and Version history — a flat table (Version / Published / Why / Classes) with one row per version. That table is what WS4 §3 collapses for consecutive annotation runs.
Batch view (obj-track.mp4, completed, 12 of 12 annotated). Establishes the grid the principle-10 guard has to protect on the way out of the editor, and the View affordance that lands in the annotator.
Annotator, Objects tab. The top bar as it ships: back · v1 · asset navigator · grid · annotated · ✓ Saved · Save (disabled) · Skip · Submit for review · Accept (disabled) · 1 / 13 annotated · Finish job (disabled) · zoom − 100% + · fullscreen — one undifferentiated row, three disabled workflow buttons rendered at once. WS2 replaces this with three zones, one primary, no disabled-without-reason, and zoom moved to the stage. The side panel shows the Objects/Labels tab pair and the object list (swatch, N. class, eye, trash) that WS3 keeps.
Annotator, Labels tab. The panel WS1–WS3 delete: a select row plus the pinned schema's classes with hotkey digit, swatch, name and geometry. Its class-activation job moves to the WS2 combobox; its only other capability — toggling classification tags — is preserved as WS3's chip strip.
Vocabulary warning for WS1: the provenance this epic adds is on schema versions (curated | annotation) and is unrelated to the annotation-level provenance (human | model | import) that already exists on Annotation. Docs must disambiguate.
The annotation workspace is being redesigned around one idea: the editor is where annotation work happens, start to finish. Class selection moves out of a side-panel tab and into a top-bar combobox with typeahead and a create-new escape hatch; the side panel becomes a single Annotations view (tag chips + object list + per-row reassignment); the top bar reorganizes into three zones with exactly one workflow primary rendered from
allowed_actions; undo/redo become visible controls; and a new ratified design principle says no flow may force the annotator out of the editor and no exit may lose work. Behind it, schema versions gain a nullableprovenanceso versions published mid-annotation can be collapsed in the history instead of burying the curated ones. Every product decision below is settled; the four work streams that follow are execution.Decision record
Work streams
Sequential — they share
AnnotationPage.tsxabove all. One worktree, one PR, merged green before the next starts. Every WS PR body carriescf. #<this issue>; the WS4 PR closes it.provenance.SchemaProvenanceStrEnum, nullable field onAnnotationSchema, keyword-onlyprovenanceonSchemaService.create_version, migration 5 (schema_provenance,FORMAT_VERSION→ 5), wire field onSchemaVersionCreate/SchemaVersionOut, and each writing surface declaring its own value (browser Schema tab and CLIschema apply→curated;AddClassDialog→annotation; MCP gains an optional parameter defaulting tocurated). Existing versions are never backfilled.Combobox(no new dependency), the top-bar class field with aChost action and aCreate class "<text>"no-match row, the three-zone top bar with a single workflow primary derived fromallowed_actions, the floating zoom/fullscreen widget, undo/redo in the tool strip, and the principle-10 save-first guard on back and grid.activeClass/onActivateClassdropped from the panel entirely; thesegmentedTabs variant retired.Create and add anotheraccumulating into one published version, thev{n}badge as a pin-vs-active popover with an on-demand diff, and consecutiveannotation-provenance versions collapsed into one expandable row inVersionNavigator.Invariants that hold across all four
AGENTS.md) are never relaxed.allowed_actionsand refusal prose from the wire. No new client-side gating rules.classColorstays the single colour derivation;ClassFieldsstays the single class form.DESIGN.md: sentence case, no "successfully", errors = what happened + what to do.Visual context — the surfaces as they ship today
Four screenshots of the current state accompany this issue (attached separately; see the comment below). What they establish:
Version 1 active · saving creates v2, aWhy this version? (optional)note field,Add class,Save version; the class list filter; theClassFieldsform (name, geometry withSingular — picking a class picks a tool., colour withDerived from name/Derive, hotkey chip, attributes block); and Version history — a flat table (Version / Published / Why / Classes) with one row per version. That table is what WS4 §3 collapses for consecutiveannotationruns.obj-track.mp4, completed, 12 of 12 annotated). Establishes the grid the principle-10 guard has to protect on the way out of the editor, and theViewaffordance that lands in the annotator.v1· asset navigator · grid ·annotated·✓ Saved· Save (disabled) ·Skip·Submit for review·Accept(disabled) ·1 / 13 annotated·Finish job(disabled) · zoom− 100% +· fullscreen — one undifferentiated row, three disabled workflow buttons rendered at once. WS2 replaces this with three zones, one primary, no disabled-without-reason, and zoom moved to the stage. The side panel shows the Objects/Labels tab pair and the object list (swatch,N. class, eye, trash) that WS3 keeps.selectrow plus the pinned schema's classes with hotkey digit, swatch, name and geometry. Its class-activation job moves to the WS2 combobox; its only other capability — toggling classification tags — is preserved as WS3's chip strip.Related
provenancethis epic adds is on schema versions (curated|annotation) and is unrelated to the annotation-levelprovenance(human|model|import) that already exists onAnnotation. Docs must disambiguate.