Skip to content

Documentation System

Overview

The Rose documentation is built using MkDocs with the Material theme. It is automatically deployed to Cloudflare Pages on every push to the develop or main branches.

Deployment Environments

Trigger Git Branch Environment Cloudflare Branch Domain
Push develop test test docstest.userose.ai
Push main production main docs.userose.ai
Manual dispatch "test" any test test docstest.userose.ai
Manual dispatch "production" any production main docs.userose.ai

Local Development

Prerequisites

  • Python 3.11+
  • Poetry (installed automatically by bootstrap)

Setup

cd docs

# Install dependencies (creates .venv and installs packages)
just install

# Or force reinstall
just install-force

Running Locally

# Start dev server with hot reload
just dev

The documentation will be available at http://localhost:8001.

Building

# Build static site to ./site directory
just build

Generated AI model inventory

The AI models page is generated for staff docs at https://docs.userose.ai/client/ai-models/ (Cloudflare Access). Logged-in backoffice users see the same inventory at Settings → Compliance → AI models (GET /admin/model-inventory), not in the embedded client documentation build. Keep the rest of the internal documentation protected.

Both MkDocs configurations load scripts/model_inventory.py. At build time the hook replaces the page's inventory marker with two lists read from code-owned deployment_route(...) references in ChatPolicy declarations, tagging/Admin generation defaults, and production embedding configuration. Deployment records come from backend/packages/ixllm/ixllm/deployments.toml, shared with runtime clients. The hook loads the catalogue through its standard-library-only loader and parses usage sources without importing backend services, reading credentials, or calling providers. Rows show Model, Provider, Agent, Region, and Training on your data (from provider catalogue metadata, default No), with one row per model/provider combination. Shared services are grouped under the agents they support, including GEO's reuse of the Website Agent pipeline. Direct MkDocs builds and just build both generate the table; mkdocs serve watches those source files.

Define each provider deployment in the ixllm catalogue. Package-owned routes reference its ID; keep per-use-case timeouts, retries and primary/fallback choices in those routing modules. Azure deployment aliases are separate from logical model identities, and ingestion embeddings have their own deployment record. When adding a new direct model path, extend the generator's coverage; unsupported route expressions fail the build instead of silently disappearing. Embedding fallback providers are read from the runtime function's provider-pair declarations. Include newly covered source paths in the docs deployment workflow so source-only changes rebuild the public list. The shared catalogue holds reviewed endpoint regions, separate processing/storage locations, endpoint environment references and credential names. It contains no credential values. There is no docs-only copy of this metadata. europe_endpoint indicates a configured European route, not per-client policy enforcement. Keep providers separate and combine agents only within each model/provider pair. Classify each pair independently, so a European provider remains in the European list even when another provider of the same model appears in the additional list. Exact model annotations override provider defaults; deployments outside the default context (the US Azure ingestion embedding) are left out of the list. Disabling the production OpenAI Europe flag moves those models out of the European list. Builds do not read credentials or contact providers. The accepted EU model-processing boundary is EEA + Switzerland. The generated page distinguishes current European routing from the planned per-client policy. Proposed hosting alternatives belong in the improvement ticket IX-5097 and the implementation plan, not the current model inventory. Recheck metadata when deployments change. The public-website embedding exception applies in either mode and is explained separately; it does not make a US deployment EU-resident.

Verify with ../backend/.venv/bin/python -m pytest scripts/test_model_inventory.py (from docs/) and build the full MkDocs site. Check client/ai-models/index.html on the staff docs host. The client-only MkDocs build excludes ai-models.md; backoffice users load the table from Settings → Compliance → AI models via GET /admin/model-inventory.

The only cookie list is §2.6 of the public Privacy Policy (website/src/legal/privacy-policy.mdx, served at https://userose.ai/privacy-policy/#26-cookies). Settings → Compliance → Cookie details in the backoffice links to it rather than keeping a copy. The policy is legal-owned: send every table change to legal so the source document stays in step.

Update it when a change adds, renames or removes a widget cookie, localStorage or sessionStorage key, changes a cookie lifetime, or loads a new provider script in the visitor's browser. Night Shift's compliance-drift job also re-checks it every two weeks, because third-party SDKs (Snitcher, Vector) change their cookies without a Rose code change. It reads the SDK code only, so run step 2 by hand when its report asks for it.

  1. List the first-party keys the widget writes: git grep -nE "(localStorage|sessionStorage)\.setItem|setCookie\(|STORAGE_KEY =|COOKIE_NAMES" -- frontend/shared/src frontend/widget/src ':!*.test.*'. Cookie lifetimes are in frontend/shared/src/analytics/providers/cookie-provider.ts. Preprod-only rose_preprod_* overrides are not listed.
  2. For third-party providers, open a demo page with the provider enabled, send a message, and read the cookies and storage in the browser's developer tools.
  3. Edit the tables in privacy-policy.mdx and bump lastUpdated in website/src/pages/privacy-policy.astro.
  4. Verify: just check from website/, then confirm the built page still has the 26-cookies heading id the backoffice link targets.

Manual Deployment

You can manually deploy to either environment:

cd docs

# Deploy to test environment (docstest.userose.ai)
just deploy test

# Deploy to production (docs.userose.ai)
just deploy production

Automatic Deployment (CI/CD)

The GitHub workflow (.github/workflows/deploy-docs.yml) automatically deploys:

  • On push to develop: Deploys to test environment
  • On push to main: Deploys to production environment
  • Manual trigger: Choose environment from GitHub Actions UI

Workflow Triggers

The workflow runs when:

  1. Files in docs/** are modified
  2. The workflow file itself is modified
  3. Manually triggered via workflow_dispatch
  4. Model routing, tagging defaults, Admin generation, embedding implementation, or production model configuration sources used by the generated model list change

Project Structure

docs/
├── src/                    # Documentation source files
│   ├── index.md           # Home page
│   ├── architecture.md    # Architecture overview
│   ├── documentation.md   # This file
│   ├── features/          # Feature documentation
│   ├── backend/           # Backend documentation
│   └── frontend/          # Frontend documentation
├── public/                # Static assets
│   ├── _headers          # Cloudflare headers config
│   └── _redirects        # Cloudflare redirects config
├── mkdocs.yml            # MkDocs configuration
├── pyproject.toml        # Python dependencies
├── poetry.lock           # Locked dependencies
├── justfile              # Development commands
└── bootstrap.py          # Setup script

Writing Documentation

File Format

All documentation is written in Markdown with MkDocs extensions:

  • Admonitions for callouts (note, warning, tip, etc.)
  • Code blocks with syntax highlighting
  • Mermaid diagrams for flowcharts and sequences
  • Tables for structured data

Adding a New Page

  1. Create a new .md file in the appropriate directory under src/
  2. Add the page to the navigation in mkdocs.yml
  3. Link to related pages where appropriate

Example: Adding a Feature Doc

# 1. Create the file
touch docs/src/features/my-new-feature.md

# 2. Edit mkdocs.yml to add to navigation
# In mkdocs.yml
nav:
  - Features:
      - Overview: features/index.md
      - My New Feature: features/my-new-feature.md  # Add this line

Maintaining the glossary

src/glossary.md is the shared vocabulary: a term means the same thing across code, schema, backoffice, and docs. Treat it as living reference, not a one-off.

  • Add a term when a concept gets reused. The moment the same word starts appearing in an ADR, a schema column, and a backoffice label — or you catch yourself re-explaining it in a second place — define it once here and link to it instead of redefining. Do not pre-populate speculative terms.
  • Keep each entry short and scope-stable: what it is, what owns it, and any invariant that is always true. Leave history, rollout, and per-feature detail in the ADR or topic page; link there.
  • Update, don't fork. When a concept's meaning shifts, edit the existing entry so the two can never drift. Remove a term when it stops being used.
  • Group by domain under an ## heading (e.g. Sites, knowledge, and routing), so sections can be extended independently as areas mature.

Add a class diagram when the relationships between terms matter more than the terms alone — ownership, cardinality, or which attribute lives on which entity. Model it as a UML class diagram, not a flowchart:

  • Concepts that own each other are classes joined by composition (*--); annotate every edge with a multiplicity ("1", "0..*").
  • Parameters are fields inside a class, never boxes of their own — an enabled flag or a status enum belongs in its entity, not beside it.
  • Put constraints and derived relationships (e.g. "exactly one canonical root", "crawl seeds derive from roots") in a note, not in the boxes.
  • Keep enum value lists (draft|live|disabled) in the prose definitions; Mermaid class bodies break on |, «», and similar characters.

Mermaid renders inline, so a glossary diagram needs no build step — but there is no local Mermaid linter, so hand-check syntax, or preview with just dev.

Markdown Extensions

Admonitions

!!! note "Title"
    This is a note callout.

!!! warning
    This is a warning without a custom title.

!!! tip "Pro Tip"
    This is a tip callout.

Title

This is a note callout.

Warning

This is a warning without a custom title.

Pro Tip

This is a tip callout.

Mermaid Diagrams

```mermaid
flowchart LR
    A[Start] --> B[Process]
    B --> C[End]
```
flowchart LR A[Start] --> B[Process] B --> C[End]

Code Blocks

```python
def hello():
    print("Hello, World!")
```
def hello():
    print("Hello, World!")

Tables

| Column 1 | Column 2 |
|----------|----------|
| Value 1  | Value 2  |
Column 1 Column 2
Value 1 Value 2

Cloudflare Configuration

Custom Domains

DNS configuration for custom domains:

Type Name Target
CNAME docs rose-docs.pages.dev
CNAME docstest test.rose-docs.pages.dev

Headers and Redirects

Custom headers and redirects are configured in public/_headers and public/_redirects, which are copied to the build output.

Troubleshooting

Build Fails

# Clean and rebuild
just clean
just install
just build

Missing Dependencies

# Force reinstall
just install-force

Port Already in Use

# Use a different port
.venv/bin/mkdocs serve -a localhost:8002
# Show all available commands
just --list

# Show DNS configuration
just show-dns

# Clean build artifacts
just clean