Docs subsystem (this!)
The page you're reading right now is served by the docs subsystem — a separate first-class module that lives alongside regular content but with its own model designed specifically for documentation.
What makes it different#
| Regular content | Docs subsystem | |
|---|---|---|
| Storage | contents + field rows |
doc_pages rows, body is raw markdown |
| Site-scoped? | Yes | No — namespaces are global |
| Versions | One | Many (full-copy per version) |
| Hierarchy | Yes (parent_id) | Yes (parent_id) |
| Address | Site + path | Namespace + version + path |
| Markdown native | No | Yes — GFM rendered server-side |
| Sub-products | Via taxonomy | Via parent_namespace_id |
| Visibility | Per-site content perms | public / authenticated / restricted per namespace |
| Public site mounts | Direct URL | site_doc_mounts (longest-prefix wins) |
| AI surface | MCP manage_content |
MCP manage_documentation + REST + Python SDK |
Mental model#
- Namespace = one product (
scaigrid,scaibot,scaicms). Global. Optional parent for sub-products (soscaibotcan declare its parent asscaigridwithout changing URLs). - Version =
v1,v2, … inside a namespace. Pages are deep-copied on fork; versions are independent thereafter. Exactly one default. - Page = a markdown document at a slash-joined
pathinside a version (models/training).
Every page is uniquely identified by (namespace, version, path). URLs
follow the same shape. Mounts choose a URL prefix per site.
Mounting on a site#
1 2 3 4 5 | |
Longest-prefix wins, so internal docs nest cleanly under the public ones without conflicts.
Restricted docs flow#
When an anonymous user hits a restricted URL on the delivery service:
- The middleware checks for a session cookie.
- No cookie → 303 redirect to
/docs/login?next=<original>. - User signs in (same credentials as the admin UI — backend mints a JWT into an HttpOnly cookie).
- The role check runs: user must hold one of the namespace's
read_role_slugs. Authorised → page renders. Not authorised → 403.
The cache key includes the auth scope so signed-in users don't see the anonymous cache, and vice versa.
Searching, deep-linking#
Markdown is chunked by heading on index. Each chunk gets an embedding and
indexes into Weaviate's DocPage collection. A search hit carries both the
page path and the chunk anchor:
1 | |
so a search agent can produce links that jump straight to the relevant section.
Further reading#
- Agent guide — feed it to an LLM for read/write capability.
- Reference → docs API — full REST surface for the docs system.