Skip to main content

ADR-195: Push-Button Documentation Publishing Platform

Status: Accepted Date: 2026-02-14 Deciders: Hal Casteel (CTO)


Context

CODITECT projects generate rich documentation corpora (markdown documents, JSX interactive dashboards, research artifacts). The BIO-QMS project alone has 83 artifacts (57 markdown + 26 JSX dashboards). Currently:

  1. JSX dashboards render in a Vite+React viewer but markdown documents have no rendering pipeline
  2. No search capability across content
  3. No presentation mode for screen-sharing demos (Zoom/Google Meet)
  4. No cloud publishing — content only viewable locally via npm run dev
  5. No reusable package — each project would need to rebuild viewer infrastructure

We need a push-button publishing platform that:

  • Renders markdown alongside existing JSX dashboards in a unified viewer
  • Provides full-text search across all content
  • Supports presentation mode for investor demos
  • Deploys to cloud with one command
  • Is reusable across all CODITECT platform projects and customer projects

Decision

D1: Unified Markdown Pipeline (unified/remark/rehype)

Use the unified ecosystem for server-side and client-side markdown processing:

  • remark-parse: Markdown → MDAST
  • remark-gfm: GitHub Flavored Markdown (tables, task lists, strikethrough)
  • remark-frontmatter: YAML frontmatter extraction
  • remark-math: LaTeX math expression support
  • rehype-stringify: MDAST → HTML
  • rehype-highlight: Syntax highlighting via highlight.js
  • rehype-slug: Heading ID generation
  • rehype-autolink-headings: Clickable heading anchors
  • rehype-katex: Math rendering via KaTeX

Rationale: unified is the industry standard for markdown processing in JavaScript. It's modular, extensible, and supports both build-time and runtime rendering. Better than marked (less extensible) or markdown-it (weaker ecosystem).

D2: publish.json Manifest

Each project declares its publishable content via a single publish.json manifest:

{
"project": "bio-qms",
"version": "1.0.0",
"title": "CODITECT Biosciences QMS Platform",
"base_url": "/bio-qms",
"auth_mode": "none",
"audiences": ["executive", "technical", "compliance"],
"documents": [
{
"id": "01-executive-summary",
"title": "Executive Summary",
"path": "docs/executive/01-executive-summary.md",
"type": "markdown",
"audience": "executive",
"category": "executive",
"keywords": ["overview", "investment", "market"],
"summary": "Platform overview and investment thesis"
}
]
}

Generation: scripts/generate-publish-manifest.js walks docs/, dashboards/, research/ directories, extracts frontmatter metadata, and emits public/publish.json.

Rationale: Decouples content organization from viewer implementation. Any project can adopt the viewer by generating a publish.json — no code changes needed.

D3: Unified Viewer (extending existing viewer.jsx)

Extend the existing Vite+React dashboard viewer to handle both document types:

  • Markdown documents: Route to MarkdownRenderer component
  • JSX dashboards: Route to existing dynamic import loader
  • Detection: type field in publish.json determines renderer
  • Layout: Shared sidebar navigation, breadcrumbs, metadata bar

Rationale: Building on the existing viewer preserves the investment in 26 working dashboards. The viewer becomes a universal content platform rather than a dashboard-only tool.

D4: Client-Side Search (MiniSearch local / MCP API cloud)

Dual-mode search architecture:

ModeEngineIndexUse Case
LocalMiniSearchsearch-index.json (build-time)Offline presentations, local dev
CloudMCP Semantic Search APIServer-side indexProduction deployment, semantic queries
  • MiniSearch: Lightweight (8KB), fast, supports fuzzy matching, field boosting, prefix search
  • Build-time indexing: Vite plugin extracts text during build, emits compressed index
  • Size target: < 500KB compressed for 100+ documents

Rationale: Local-first search enables offline presentations. Cloud search adds semantic understanding for production deployments. MiniSearch is the best client-side option (better than Lunr.js for size and features).

D5: Presentation Mode

Full-screen presentation mode designed for screen-sharing:

  • Entry: Toolbar button + keyboard shortcut (P)
  • Navigation: Arrow keys (prev/next document), Up/Down (categories)
  • Slide progression: H2 headings as slide boundaries within documents
  • Chrome: Minimal — content only, no sidebar/search/breadcrumbs
  • Timer: Elapsed time display (toggle with T)
  • Presenter notes: Hidden panel visible in separate window

Rationale: Investor and partner demos are the primary use case for Sprint 1. Screen-sharing via Zoom/Google Meet requires clean, distraction-free rendering with keyboard-only navigation.

D6: Cloud Deployment (Cloud Run + CDN)

One-command deployment to GCP Cloud Run:

npm run publish  # Build → validate → deploy → verify
  • Static hosting: Cloud Run serving Nginx with SPA fallback
  • CDN: Cloud CDN for static assets (30-day cache with content hash busting)
  • URL: docs.coditect.ai/{project} or {project}.docs.coditect.ai
  • SSL: Managed certificates via GCP
  • Rollback: Keep previous 3 versions, instant rollback

Rationale: Cloud Run provides auto-scaling, custom domains, and managed SSL with minimal configuration. Combined with Cloud CDN, it delivers sub-100ms global latency for static content.

D7: Multi-Project npm Package

Extract the viewer as a reusable package:

  • Package: @coditect/doc-viewer
  • Components: MarkdownRenderer, DashboardLoader, SearchPanel, PresentationMode, NavTree
  • Config: Accept publish.json URL as primary configuration
  • Theme: CSS variables + Tailwind config for brand customization
  • CLI: npx @coditect/create-doc-site my-project for scaffolding

Rationale: Making the viewer reusable serves both CODITECT internal projects and future customer deployments. The publish.json contract ensures any project can adopt the platform without viewer code changes.


Consequences

Positive

  • Unified content experience: All 83+ artifacts viewable in one interface
  • Instant demos: Presentation mode enables investor/partner demos from day 1
  • Cloud deployment: One-command publishing for any project
  • Reusable: npm package serves all CODITECT projects and customers
  • Offline-capable: Local search and presentation mode work without internet
  • Standards-based: unified/remark ecosystem is well-maintained and extensible

Negative

  • Build complexity: Vite plugin for search indexing adds build step
  • Package maintenance: npm package requires versioning discipline
  • Two search engines: MiniSearch (local) + MCP API (cloud) adds complexity

Risks

  • MiniSearch index size: May exceed 500KB for very large document sets (mitigate: pagination, lazy loading)
  • JSX security: Dynamic JSX import needs Content Security Policy consideration
  • Offline drift: Local and cloud content may diverge (mitigate: version checking)

Implementation Phases

PhaseSprintScope
1S1Markdown rendering + navigation + search + presentation mode (local)
2S2Cloud deployment + CDN + publish CLI
3S3NDA-gated access (ADR-196) + npm package extraction
4S4+Semantic search (cloud), customer self-service

  • ADR-196: NDA-Gated Conditional Access Control (authentication layer)
  • ADR-015: Authentication Architecture (auth.coditect.ai)
  • ADR-090: JWT Token Strategy (token format)
  • ADR-145: Cloud Authentication (GCP integration)

Author: Hal Casteel Project: BIO-QMS (CODITECT Biosciences QMS Platform)