Status/Wiki Common-Surface Extraction

Scouting slice: CareerVector and JobCache are equal product faces over the same substrate. Shared code should remove real duplication only when both surfaces consume it immediately.

Status

Common and extracted now:

  • Public status shell: HeaderBar, public footer, Status perspective label, product link set as input.
  • Health-state UI vocabulary: operational/degraded/down/not_configured to tone, label, dot class, badge class.
  • Relative age labels, count formatting, status API base override trimming, and public JSON fetch handling.

Still product-specific:

  • CareerVector headline and metrics are workspace/user trust oriented.
  • JobCache headline and metrics are shared-index/freshness oriented.
  • JobCache exposes public-only source aggregate and broker-path pointer; CV does not.
  • API response envelopes and env var names differ.
  • Incident feed shapes differ enough that a shared component would need a normalisation contract first.

Next small status step, if useful: extract an InfrastructureChecks.svelte component from both pages after deciding whether CV should show check summaries like JobCache. Do not force that before the public copy contract is settled.

Wiki

Common, but not extracted in this slice:

  • Build-time markdown index from import.meta.glob.
  • README.md to directory-index URL mapping.
  • Section grouping and sibling-section navigation.
  • marked rendering, article body, and source-file footer.
  • Header/footer chrome via shared admin links.

Must remain product-specific:

  • CareerVector wiki is an admin knowledge hub with Atlas, Canon, Codebook, Journal, Librarian tabs, KnowledgeHubControl, graph/codebook APIs, wiki-link rewriting, heading IDs, backlinks, and page-link panels.
  • JobCache wiki is intentionally a smaller LeafWiki-style content site with architecture/API/runbook sections and no graph control plane.
  • Content roots stay separate: wiki/content/** and jobcache/wiki/content/**.
  • CareerVector root redirects to /atlas; JobCache root renders the content section landing page.

Exact Wiki Extraction Plan

Create lib/wiki-platform/** only when the first commit consumes it from both wiki and jobcache/wiki.

  1. Extract pure index helpers:

    • Keep import.meta.glob('../../content/**/*.md', ...) inside each wiki app.
    • Add buildWikiIndex(raw, { rootTitle, sourcePathPrefix }).
    • Shared output types: WikiEntry, SectionSummary, WikiIndex.
    • Both apps replace local firstHeading, filePathToUrl, sectionSlugFor, SECTIONS, ALL_PATHS, and findByUrl.
  2. Extract the basic markdown renderer:

    • Add renderMarkdownBasic(source) wrapping marked.parse.
    • JobCache consumes it directly.
    • CareerVector keeps its product-specific link rewrite, route healing, heading IDs, backlinks, and knowledge-page projection around that helper.
  3. Extract reader layout only after server data shapes match:

    • Candidate component: WikiReaderLayout.svelte.
    • Inputs: html, filePath, urlPath, optional siblingSection, optional backlinks, optional pageLinks.
    • It may cover article body, sibling nav, source footer, and optional side rails. It must not know about Atlas/Canon/Codebook/Journal/Librarian.
  4. Keep chrome local unless a second wiki gains tabs/control slots:

    • CareerVector layout needs tabs and KnowledgeHubControl.
    • JobCache layout intentionally has no tabs.
    • Existing HeaderBar and PrivateFooter already carry the common chrome.

Focused checks for the eventual wiki extraction:

  • bun run --filter @cv/wiki test
  • bun run --filter @cv/wiki check
  • bun run --filter @cv/jobcache-wiki test
  • bun run --filter @cv/jobcache-wiki check

Non-goals:

  • Do not merge the content trees.
  • Do not make JobCache inherit CareerVector graph/codebook behavior.
  • Do not introduce a ceremonial wiki framework before both apps consume the extracted code.
Source: wiki/content/working-memory/status-wiki-common-surface-extraction.md