Slice 4 step 1 (faraday-Q7). RenderShape gets a fourth member
ShapeTimeline, AllShapes extends, Validate accepts it. The
companion TimelineConfig struct stores the saved palette / density /
range-preset for a CV-timeline view so re-opening the view restores
the same visual settings — same vocabulary as the standalone
/projects/{id}/chart URL state, just persisted in user_views.render_spec
instead of the URL.
Validator mirrors the frontend's enum guards:
- known palettes (default | kind-coded | track-coded | high-contrast | print)
- known densities (compact | standard | spacious)
- known range presets (1y | 2y | all | custom)
- ISO-date strings length-bounded to 32 chars so a hostile editor
can't bloat the jsonb column.
Tests pin every accept/reject path in TestRenderSpec_TimelineConfigValidates.
Design ref: docs/design-project-chart-2026-05-09.md §11.5 + §14 Q7.
Schema bump that lets the universal <FilterBar> tell shape-list which
row interaction to wire (navigate / complete_toggle / approve / none).
Defaults to navigate when empty so existing SystemView definitions and
saved user views continue to render rows that route to the per-kind
detail page.
Validator extended; pure-Go test cases over every enum value + reject.
TS mirror updated in client/views/types.ts. No DB migration — the
field is purely additive on the JSON shape.