Knowledge

Docs spaces and pages

Docs is Vigilo's wiki: hierarchical, block-based, versioned, commentable, and searchable. It lives at /ws/{slug}/kb and is organised into DocSpaces…

Last updated

Overview

Docs is Vigilo's wiki: hierarchical, block-based, versioned, commentable, and searchable. It lives at /ws/{slug}/kb and is organised into DocSpaces (top-level containers per team, project, or topic) that hold a tree of DocPages, each rendered from a BlockContent document.

Where the Catalog is your toolbox of short, structured artifacts, Docs is your long-form home for design proposals, onboarding guides, post-mortems, vendor evaluations, and the slow-moving prose that benefits from version history and inline review.

Why it exists

Engineering organisations need a single, workspace-isolated wiki that integrates with the same RBAC, RLS, and audit story as the rest of Vigilo. Bringing in an external wiki (Confluence, Notion) reintroduces the multi-tool fragmentation Vigilo exists to fix: docs lose their link to the changes and incidents they describe, comments duplicate the comment system in the rest of the product, and the AI assistant cannot index across silos. The Docs module keeps prose in the same RLS perimeter as the rest of the workspace.

Key concepts

DocSpace

A DocSpace (DocSpace: name, slug, description, icon, color, is_public, archived_at) is the top-level container. Spaces appear in the left sidebar of /ws/{slug}/kb and have their own icon and accent colour for quick scanning. The is_public flag is workspace-internal-public: it does not expose the space to the open internet, only relaxes per-page visibility within the workspace (the workspace-level RLS gate always applies). Spaces can be archived; archived spaces stay accessible by direct URL but are hidden from the picker.

DocPage

A DocPage (DocPage: space, parent, title, slug, block_content, is_public, is_archived, last_edited_by) is a single page in the wiki tree. The parent self-FK makes pages nestable to arbitrary depth — Vigilo enforces a soft limit of 8 levels to keep the URL and breadcrumb sane. The page renders breadcrumbs derived by walking the parent chain back to the space root.

BlockContent (TipTap)

Page body is stored as a BlockContent document — a JSON tree of TipTap blocks: headings, paragraphs, lists, code blocks (with language), callouts, tables, images, embeds, and Vigilo-specific blocks for change_ref, incident_ref, and metric_chart. The same BlockContent editor renders Catalog KB articles and meeting notes, so the editing experience is identical across the product.

Versioning, diffs, revert

Every save creates a DocPageVersion row (WD.3: page, version_number, block_content, author, change_summary, created_at). The page detail page has a History tab that lists versions newest-first; clicking two versions opens a side-by-side block-aware diff (added blocks green, removed red, modified blue with inline text diff). The Revert to this version button creates a new version whose body matches the chosen one — history is append-only, you never lose forward versions.

Comments and @mentions

Comments are threaded via PageComment (page, author, body, parent self-FK). Reply by clicking under any comment; the system nests replies under the parent you replied to. Inside a comment body, type @ to open the mention picker; an @username insert creates a Notification for that user (kind mention) and a Slack DM if they have the Slack integration linked. Mentions in the page body itself also generate notifications, on first save only — re-saving with the same mention does not re-notify.

Search

Page search is hybrid semantic + lexical (WD.2). The query is sent to two indexers in parallel: a Postgres FTS (to_tsvector('english', title || ' ' || plain_text)) for keyword precision, and a pgvector cosine search over the EmbeddedContent index for semantic recall. Results are merged via reciprocal-rank fusion and rendered with snippet highlights. The semantic side requires OPENAI_API_KEY; without it the search degrades gracefully to lexical-only.

Visibility

Each page has is_public (relaxes visibility within the workspace) and is_archived (hides from listings, kept by URL). Both flags operate inside the workspace RLS perimeter — no page is ever exposed to the public internet through this flag. To expose a page externally, use the Public forms module or generate a signed share link from the page action menu (signed links honour an expiry date and an audit log).

Common workflows

Create a page

  1. Open /ws/{slug}/kb, click the target DocSpace, then New page (or Add sub-page while viewing a parent).
  2. Type the title and start writing in the block editor. Press / to open the block picker.
  3. Add a change_ref block to embed a live status badge for a CHG; the badge auto-updates when the change moves through the FSM.
  4. Save triggers a DocPageVersion row and a webhook event doc_page.updated that integrations can subscribe to.

Review and revert

  1. Open the History tab on the page; click two version timestamps to enter compare mode.
  2. Scroll through the diff. Use Revert to this version if the newer change is unwanted; a fresh version is appended with change_summary='Reverted to v{n}'.
  3. The original author of the reverted-from version is notified.

Comment and mention

  1. Highlight any text in the page body and press the comment icon, or scroll to Comments at the bottom.
  2. Write the comment; type @ and pick a member.
  3. The mentioned member gets a notification card in their bell menu and (if linked) a Slack DM with a deep link to the comment thread.

Search

  1. Press / from anywhere in /ws/{slug}/kb to focus the search bar, or open the global command palette and prefix with docs:.
  2. The results panel shows the page title, the matching snippet, and the parent breadcrumb.
  3. Toggle Semantic only / Lexical only in the filter bar to debug ranking.

Permissions

  • Viewers can read pages and post comments.
  • Engineers (docs.write) can create and edit pages, but cannot delete spaces.
  • Approvers / admins (docs.manage) can archive pages, manage space membership, and rotate signed share links.
  • Owners can hard-delete pages (delete triggers a soft-delete with 30-day retention; owners only can force-delete from admin).

All operations are workspace-RLS-gated even when is_public=True.

Troubleshooting

Search returns nothing for a page I just wrote — The embedding index is updated asynchronously. Wait 30-60 seconds, or trigger an immediate reindex from the page action menu (Reindex now, admin only).

@mention did not notify the user — They may have the mention notification kind muted in Settings → Notifications, or they were already in the page's thread (Vigilo deduplicates mentions inside the same thread within 1 hour). Check the user's notification preferences.

Revert produced an empty page — The version you reverted to is from before BlockContent migration. Check version.block_content in admin; if it's null, the version is unreverable. Use the block_content_legacy field to manually copy the raw HTML.

Page breadcrumbs broken — A parent page was hard-deleted leaving the child orphaned. Owners can fix via the page admin: set a new parent or null it to make the page top-level in the space.

Related