Found by manual testing of the shipped 0.0.1b1 wheel.
What happens
In the schema editor, a class with no declared colour shows the two colours it will actually be drawn in as two different colours in the same row:
- the dot beside the class name shows the real derived colour (
pedestrian → teal, weather → gold)
- the Colour swatch immediately to its right shows grey, with the caption "Derived from the name."
The grey is just an empty <input type="color"> falling back to its default. The class is not grey anywhere — the annotator draws pedestrian in the same teal the dot shows, which I confirmed by drawing one.
So the editor shows a swatch that contradicts both the dot two inches to its left and the annotator, in the one control whose entire job is to show what colour something is.
Root cause
The colour input is bound to the class's stored colour, which is null for a derived class, rather than to the colour that will be used. The single spelling of the real rule already exists and is the one to read from: classColor in frontend/ui-core/src/annotator/paint.ts — schema colour first, else FNV-1a over the name → hsl(hash % 360 72% 58%). DESIGN.md records this as the shipped rule, and #128 exported it for exactly this kind of reuse.
Suggested fix
Show the derived colour in the swatch, while keeping "declared" and "derived" visibly distinct — the caption already carries that meaning, and the existing "Derive" button implies the state is meaningful and must not be erased:
- set the input's value from
classColor(labelClass) so it always previews the truth
- keep the stored value
null until the user actually picks one, so "Derive" still means something and saving does not silently freeze a hash-derived colour into the schema as if it had been chosen
That second point is the one to be careful about: making the input display a colour must not make the class declare it. A schema version that pins today's hash output would change meaning if the palette rule ever changes, and it would make every derived class look authored.
Acceptance criteria
- A class with no declared colour previews its derived colour in the swatch, matching the dot beside its name and the colour the annotator draws it in.
- Saving an untouched schema does not add a
color to a class that had none — assert on the created version's payload, not on the UI.
- "Derive" still clears a declared colour back to the derived one.
- The derived value comes from
classColor, not from a second implementation of the hash.
Scope notes
Found by manual testing of the shipped
0.0.1b1wheel.What happens
In the schema editor, a class with no declared colour shows the two colours it will actually be drawn in as two different colours in the same row:
pedestrian→ teal,weather→ gold)The grey is just an empty
<input type="color">falling back to its default. The class is not grey anywhere — the annotator drawspedestrianin the same teal the dot shows, which I confirmed by drawing one.So the editor shows a swatch that contradicts both the dot two inches to its left and the annotator, in the one control whose entire job is to show what colour something is.
Root cause
The colour input is bound to the class's stored colour, which is
nullfor a derived class, rather than to the colour that will be used. The single spelling of the real rule already exists and is the one to read from:classColorinfrontend/ui-core/src/annotator/paint.ts— schema colour first, else FNV-1a over the name →hsl(hash % 360 72% 58%).DESIGN.mdrecords this as the shipped rule, and #128 exported it for exactly this kind of reuse.Suggested fix
Show the derived colour in the swatch, while keeping "declared" and "derived" visibly distinct — the caption already carries that meaning, and the existing "Derive" button implies the state is meaningful and must not be erased:
classColor(labelClass)so it always previews the truthnulluntil the user actually picks one, so "Derive" still means something and saving does not silently freeze a hash-derived colour into the schema as if it had been chosenThat second point is the one to be careful about: making the input display a colour must not make the class declare it. A schema version that pins today's hash output would change meaning if the palette rule ever changes, and it would make every derived class look authored.
Acceptance criteria
colorto a class that had none — assert on the created version's payload, not on the UI.classColor, not from a second implementation of the hash.Scope notes
openapi.jsonuntouched.DESIGN.mdis the authority on the palette rule; if this changes anything about it, update that file in the same PR.tokens.cssand the exported palette rule).