Split @dossier/okf-view into a client-safe entry (view-model + types) vs a server-only entry (the fs readers) + guard against node:fs leaking into the client

task-harden-okf-view-client-safe-entry

task confidence inferred status backlog 2026-06-22 owner sveltekit-engineer
source log-auditor — surfaced during DEC-0072 Track-1 browser verification; the OkfMeta node:fs-in-client hydration leak (now fixed in place) is a symptom of a structural barrel issue. Board globbed/grepped before filing — no open task covered the okf-view entry split or a client/server import guard (task-render-dogfood-kb-native-in-app fixed the one symptom call-site, not the leaky barrel).

Split @dossier/okf-view into client-safe vs server-only entries + guard the boundary

@dossier/okf-view ships a single barrel that re-exports the fs-based route/kb readers (knowledgeDir / getRouteMap / readKbAtoms / generateSidebar) alongside the pure client-safe view-model helpers + types. Any client value-import of that barrel drags node:fs into the browser bundle.

Why a task (not a fix-in-place)

The one symptom call-site is already fixed — OkfMeta.svelte was value-importing conceptBadgeClass from the barrel, pulling node:fs into the client and throwing on hydration (the SSR HTML looked fine; only a real browser exposed it — found during Track-1 verification, fixed by making OkfMeta import types only + pre-resolving the badge class / owner routes server-side). But that only treats the symptom. The structural fix — a client-safe entry split + an import guard so the bug class can't recur — needs the Principal SvelteKit Engineer's judgment on the package's public surface and the guard wiring. In Vite dev there is no tree-shaking, so the leak is always present; prod tree-shaking removes it but is fragile (one stray value-import re-introduces it). confidence: inferred (agent-derived from the verification finding).

Scope

  • Client-safe entry/subpath — view-model helpers + types only (conceptBadgeClass, the view-model types, etc.); pulls in zero node:fs.
  • Server-only entry — the fs readers (knowledgeDir, getRouteMap, readKbAtoms, generateSidebar); unreachable through the safe entry.
  • Import guard — an ESLint/CI rule that fails on value-importing the fs readers (or node:fs, transitively) into client code, so the bug class can't silently recur.

Shared-leaf constraint

@dossier/okf-view is a shared leaf consumed by both @dossier/app and @dossier/docs. The split must keep both consumers green — Astro docs and the SvelteKit app both reach the same reader (no forked KB, DEC-0044).

Board globbed/grepped before filing — no open task covered the okf-view entry split or a client/server import guard.