--- id: LSN-0042 ticket: palette-management-in-studio title: Schema-Driven Palette Authoring and Local Metadata Events created: 2026-04-23 tags: - studio - glyph-bank - palette-management - color-schema - local-events --- ## Context The glyph-bank palette workflow originally treated palette candidates as extracted tile artifacts. That made grouping, recoloring, and final bank palette selection compete in the same surface. The completed palette-management work split the workflow into two authored layers: 1. `Color Schema Groups`, where selected tiles are grouped into a shared index structure. 2. `Palette Overhauling`, where palettes are authored and selected against already-ready schemas. The durable implementation lesson is that schema edits, palette edits, and build selection are all local glyph-material metadata operations first. They should update local metadata projections directly instead of forcing a full asset-details reload. ## Key Decisions ### Schema Owns Index Semantics **What:** A schema is the authored index structure for a group of selected glyph-bank tiles. It owns `material_indices`, artifact bindings, fingerprint snapshots, version, and status. **Why:** The source PNG stays unchanged, while Studio records how tile colors map into stable bank-local indices. This keeps tile grouping separate from recoloring. **Trade-offs:** Schema invalidation must be explicit. When selected tile fingerprints drift, the schema can become inconsistent and dependent palettes become invalid or stale. ### Palettes Are Schema-Scoped **What:** A palette always belongs to exactly one schema. It stores concrete `#RRGGBB` colors for that schema's visible indices and carries the schema version it was authored against. **Why:** Multiple recolors can safely exist for one index structure without duplicating tile grouping metadata. **Trade-offs:** Duplicate detection must use the tuple `schemaId + colors + order`, not display name or source tile identity. ### Original Palettes Are Synthetic and Read-Only **What:** The original palette is the synthetic `schema--original` projection derived from the current schema colors. It is not a persisted user palette. **Why:** Updating the schema should update the original palette automatically. The original represents the schema's source color meaning, not a user-authored recolor. **Trade-offs:** Users cannot edit or delete the original palette directly. If they want a changed palette, they create or edit a separate persisted palette for the same schema. ### Local Metadata Events Beat Global Reloads **What:** Schema and palette metadata mutations should publish `StudioGlyphMaterialMetadataChangedEvent` and let interested sections rebind local state. **Why:** Global asset refresh and selection events can close edit mode, reset form state, and make small metadata edits feel destructive. **Trade-offs:** Controls must keep their local coordinators robust: stale button handlers should read the current view model at click time, and metadata replacement must preserve edit-mode drafts where possible. ## Patterns and Algorithms ### `glyph-material.json` `glyph-material.json` is the Studio-owned support file for glyph-bank material authoring. It persists schemas and user-authored palettes, while derived original palettes remain a view projection. Schema records store: - stable `schema_id` - `status` - `version` - dense visible `material_indices` - artifact bindings with fingerprint snapshots Palette records store: - stable `palette_id` - persisted `name` - parent `schema_id` - schema `version` - concrete `colors` ### Palette Names Palette names are persisted even when the user leaves the name field blank. The blank-name path resolves to a deterministic, simple generated name such as `snow white`, `fog twist`, or `ember bloom`. The generated name is a convenience label only. Palette identity remains `palette_id`, and duplicate detection remains schema plus ordered colors. ### Original Palette Projection Every ready schema projects a synthetic original palette from the schema's current `material_indices`. This projection must always exist in the palette view, even if a user-authored palette has the same colors. A saved palette with the same schema and colors is still user-authored and can be deleted. ## Pitfalls - Do not treat same colors as proof that a palette is original. Original means "synthetic schema projection", not "matches current schema colors". - Do not publish global asset refresh events for local schema or palette metadata changes. Use local metadata events unless pack/runtime state truly changed. - Do not let button handlers capture stale preview objects. Fetch the current coordinator view model at click time for destructive actions. - Do not let blank palette names remain blank on disk. Resolve the generated name before persisting. - Do not open the palette wizard for synthetic original palettes. They are read-only projections. ## Takeaways - Schema formation and palette authoring are separate lifecycle stages. - Original palettes are derived views, not persisted editable records. - User-created palettes remain editable and removable even when they share a schema or colors with an original. - Local metadata events preserve form continuity better than full asset refreshes.