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,Statusperspective label, product link set as input. - Health-state UI vocabulary:
operational/degraded/down/not_configuredto 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.mdto directory-index URL mapping.- Section grouping and sibling-section navigation.
markedrendering, 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/**andjobcache/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.
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, andfindByUrl.
- Keep
Extract the basic markdown renderer:
- Add
renderMarkdownBasic(source)wrappingmarked.parse. - JobCache consumes it directly.
- CareerVector keeps its product-specific link rewrite, route healing, heading IDs, backlinks, and knowledge-page projection around that helper.
- Add
Extract reader layout only after server data shapes match:
- Candidate component:
WikiReaderLayout.svelte. - Inputs:
html,filePath,urlPath, optionalsiblingSection, optionalbacklinks, optionalpageLinks. - It may cover article body, sibling nav, source footer, and optional side rails. It must not know about Atlas/Canon/Codebook/Journal/Librarian.
- Candidate component:
Keep chrome local unless a second wiki gains tabs/control slots:
- CareerVector layout needs tabs and
KnowledgeHubControl. - JobCache layout intentionally has no tabs.
- Existing
HeaderBarandPrivateFooteralready carry the common chrome.
- CareerVector layout needs tabs and
Focused checks for the eventual wiki extraction:
bun run --filter @cv/wiki testbun run --filter @cv/wiki checkbun run --filter @cv/jobcache-wiki testbun 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.