Skip to main content

Setting up a new tenant's knowledge base

How to stand up an isolated agent-native knowledge base (the knowledge-base wiki space) for a new team — one that agents read index-first and that compounds from their work, fully isolated from other tenants by Row-Level Security.

For what the KB is and how it operates, read the agent-native knowledge base concept page first; for the read path agents use, see KB retrieval.

The model: a team that needs its own KB = its own tenant

  • Tenant = the RLS isolation boundary. A team that needs an isolated KB gets its own tenant.
  • Organisation = a sub-entity within a tenant (ADR-005). Orgs in one tenant share the tenant's RLS scope, so they share one KB.
  • Therefore: isolated KB ⇒ separate tenant, not just a separate org.

Prerequisite — verify RLS is actually enforced (do this first)

This is the gating step

The entire multi-tenant isolation rests on the app connecting to Postgres as a non-BYPASSRLS role. If the runtime connects as a superuser / BYPASSRLS role, all RLS is inert — one tenant could read another's data, and per-tenant KB isolation is illusory.

Before onboarding any team whose KB must be isolated, confirm the runtime connects as a non-bypass role. If it does not, fix that first. Everything below assumes RLS is genuinely enforced.

Setup steps

1. Provision the tenant + org (Directory)

Create the tenant (types: AGENCY / SUPPLIER / PROGRAMME_OFFICE / PLATFORM_OPERATOR), at least one organisation, and an admin user. This is the RLS boundary every later step inherits.

2. Create the knowledge-base space (in the new tenant)

Use exactly the slug knowledge-base. That well-known slug is what wires the coordinator read path and consult file-back to the space. Mark it agent-owned and give it a description (mirror the platform KB space). One KB space per tenant.

3. Mint tenant-scoped API keys (Settings → API Keys, in the tenant)

The Directory-issued API-key JWT carries tenant_id, so every MCP / pt CLI call RLS-scopes to this tenant — a key for Team A can never read Team B's KB. One key per agent/machine; shown once; ~90-day default. See the MCP server setup.

4. Wire the environment

VariableWhereWhy
WIKI_BASE_URLthe team's .mcp.jsonRegisters the wiki MCP tools (search_pages, get_page, ingest, lint, …) on the MCP server. Does not gate query_knowledge_base — that tool is always registered against the PT client.
WIKI_ZONE_URLthe PT / coordinator runtimeThe backend read path for query_knowledge_base and the coordinator KB reader; the wiki-spaces proxy fails closed if it is unset (returns WIKI_BACKEND_NOT_CONFIGURED, never a silent empty).
CRON_SECRET + DISPATCHER_DATABASE_URLthe wiki runtime (for file-back)The outbox dispatch-events cron must run for consult file-back to deliver. Use a dispatcher-role DSN.

5. Set the coordinator profile + initiative (PT)

The coordinator is initiative-scoped. Create the team's initiative and its coordinator_profile (the conventions the coordinator reasons with). The platform coordinator service is generic — per-team behaviour lives in this profile.

6. The per-repo convention layer (in the team's repo)

The platform is generic; convention lives in two places — the per-initiative coordinator_profile (step 5) and the team's repo:

  • .mcp.jsonPT_BASE_URL, WIKI_BASE_URL, PT_AUTH_TOKEN.
  • The consult-the-kb skill — so agents query the KB before implementing and cite what they used.
  • .claude/agents/pt-coordinator.md — copied in, with their initiative ID.

A fresh KB is empty. Seed the team's durable canonical knowledge (their constitution / ADRs / conventions) via ingest_source (human-approved, with approvedBy), in curated waves — not a raw dump. ADRs and locked decisions are the best seed material; volatile documents create curation churn. See the knowledge-base concept page for what makes a good ingestion candidate.

Verify it works

  • Read path: a live consult on the team's initiative returns citations referencing seeded KB pages.
  • File-back loop: a successful UNCLASSIFIED consult files back a synthesis-consult-* page (and events.deliveries grows — proving the dispatcher delivers).
  • Index health: the space index is a small hub-and-spoke, under the coordinator reader cap.
  • Isolation: a token for this tenant cannot see another tenant's KB (the RLS check from the prerequisite, now proven end to end).

Keep it healthy (curation cadence)

  • Daily mechanical lint — automated cron: orphan / broken-crossref / provenance-drift.
  • Per-release LLM judgement pass + nomination-queue processing: stale-claim / contradiction findings + ingesting newly-nominated pages.
  • See Wiki lint & curation and the wiki-curator subagent.

What is not shared across tenants (yet)

Each tenant's KB is fully isolated. Common knowledge — a shared constitution, platform ADRs, cross-team conventions — is duplicated per tenant today; there is no shared/federated KB. A cross-tenant / platform shared KB is a future enhancement, not a current capability.

Deployment models

ModelTrade-off
(a) Additional tenant, shared instanceFastest. The team is a tenant with its own KB. Works today — modulo the RLS prerequisite above.
(b) Separate Constellation deploymentHeavier, full infra isolation. SaaS / Dedicated-Cloud / On-Prem tiers; each deployment gets its own KB. See Deployment.