What
src/main.js:96-101 (share-link bootstrap) writes queryView(spec) into app.state.resultView without validating it against the view enum. A crafted share link can therefore set resultView to an arbitrary string. src/state.ts now pins the signal to Signal<'table'|'json'|'panel'|'filter'> (ADR-0002 phase 2), which documents the intended value set at compile time — but main.js is still unchecked .js glue, so the ingress isn't actually guarded at runtime.
The Spec schema constrains view to "table" | "json" | "panel", but the share-link path doesn't run the schema validator on that field before assignment.
Why deferred
Found during the #262 TypeScript migration (strict typing of state.js); the migration is behavior-change-free by policy, and adding runtime narrowing here is a real behavior change (needs a decision: silently fall back to 'table' vs. surface a diagnostic).
Suggested fix
Normalize through the same guard the view switcher uses (or validate spec.view via the schema service) before assigning to resultView in the share-link path.
What
src/main.js:96-101(share-link bootstrap) writesqueryView(spec)intoapp.state.resultViewwithout validating it against the view enum. A crafted share link can therefore setresultViewto an arbitrary string.src/state.tsnow pins the signal toSignal<'table'|'json'|'panel'|'filter'>(ADR-0002 phase 2), which documents the intended value set at compile time — butmain.jsis still unchecked.jsglue, so the ingress isn't actually guarded at runtime.The Spec schema constrains
viewto"table" | "json" | "panel", but the share-link path doesn't run the schema validator on that field before assignment.Why deferred
Found during the #262 TypeScript migration (strict typing of
state.js); the migration is behavior-change-free by policy, and adding runtime narrowing here is a real behavior change (needs a decision: silently fall back to 'table' vs. surface a diagnostic).Suggested fix
Normalize through the same guard the view switcher uses (or validate
spec.viewvia the schema service) before assigning toresultViewin the share-link path.