2 min read
kevin-wiki / ui
Purpose
The web viewer. A Next.js (App Router) app that renders the wiki/ markdown
knowledge base as a browsable site, plus Kevin's /me portfolio and the private
local /brief decision surface. Wiki content remains read-only; /brief writes
only to the local Daily Brief event store through its gated API. Tailwind owns
styling; the public wiki is deployed on Vercel.
Mental model & key files
src/app/(wiki)/— the wiki reader (page rendering,[...slug], assets).src/app/(wiki)/system/— public brain/system projection.src/app/(wiki)/brief/— global-password-gated local Daily Brief client.src/app/me/— the portfolio (about, work, projects, research, lab, photography).src/app/api/—og(per-article OpenGraph images),search,assets,unlock, publicsystem, public OKF v0.2, privatebrief, and bearer-authenticated proposal-memory routes.src/app/graph/,src/app/audit/— graph view + audit surfaces.src/components/,src/lib/,src/contexts/— shared UI, helpers, providers.src/lib/privacy-policy.json+src/lib/gating.ts— shared fail-closed public/private policy for runtime and bundling.scripts/— build-time content bundling + citation checks (seeui/scripts/SKILL.md).
Patterns to follow / invariants
- Tailwind +
cn()first; raw CSS only inglobals.css. No co-located CSS modules for ordinary UI (seewiki/style/css-ui-enforcement.md). - Follow
wiki/style/react.md+wiki/style/typescript.md; checkvercel-react-best-practicesfor data fetching / perf. - Package manager is pnpm here (the repo root is npm/tsx). Run from
ui/. - Keep the full-text search index out of server-rendered page props. Public
search loads the privacy-filtered
/search-index.jsonstatic asset; unlocked search uses the bounded/api/search?view=pageresponse.
Common tasks → first action
- Dev server →
pnpm dev(from repo root:npm run dev). - Build →
npm run build(installs ui deps frozen, then builds). - Add a page → App Router segment under
src/app/, reusesrc/components/.
Gotchas
- The app reads bundled wiki content — re-run the bundler (
ui/scripts) after wiki changes that the viewer must reflect. scripts/export-okf.mjsowns the privacy-filtered.content/okfprojection;/api/okfonly serves that generated tree and never reads canonical private pages directly.- Never add a parallel privacy list. Runtime and
bundle-wiki.mjsmust read the shared privacy manifest, and protected slugs cannot be force-public through frontmatter. - Never expose
/api/briefwithout checking the global gate session. The local PGlite ledger is authoritative for the first Daily Brief slice and must not be serialized into public pages or generated assets. /api/memoryis a separate machine credential boundary: derive authority on the server, require idempotency and provenance, enforceKEVIN_WIKI_MEMORY_SOURCE_SCOPES, deny public writes unless explicitly enabled, and require a durable ledger path in production. It stores proposals, not canonical wiki truth.- This is a separate pnpm workspace from the tsx scripts at the repo root.