Make_Skills
Make_Skills

Architecture

What's shared, what's per-user, what's per-tenant, and how that maps to Docker containers in self-host vs hosted modes.

The layered model and container topology. Contributions from 2026-04-28 onward respect these layers.

Two deployment modes

Self-hostHosted-multitenant
Who runs itThe user, on their own machine or VPSLiz, on humancensys.com
AuthNone (single user)OAuth (provider TBD)
Data isolationTrivial (one user)tenant_id everywhere
Cost modelUser pays compute + their own API keysBring-your-own API keys; Liz pays infra
Same codebaseYes — PLATFORM_MODE env var selects modeSame

The five layers

LAYER 1: Platform code (always shared, open-source)
  ├─ platform/api/       FastAPI, deepagents runtime, tools
  ├─ web/                Next.js UI shell
  ├─ skills/             curated skill library (read-only common)
  └─ subagents/          template subagents

LAYER 2: Tenant identity & isolation (mode-dependent)
  ├─ Self-host:          tenant_id = "default"; no auth code path runs
  └─ Hosted:             tenant_id from verified OAuth token

LAYER 3: Tenant configuration (per-tenant, user-editable)
  ├─ AGENTS.md           orchestrator persona
  ├─ deepagents.toml     model + skill paths
  ├─ Their subagents     personalized clan
  └─ Their skill choices what's loaded into their agent

LAYER 4: Tenant data (per-tenant, isolated, never shared without explicit publish)
  ├─ Conversations       (LangGraph checkpoints in postgres, scoped by thread)
  ├─ Semantic memory     (LanceDB records, tenant-scoped)
  ├─ Roadmap             (their ROADMAP.md)
  ├─ Knowledge graph     (their canonical nodes — when 3c lands)
  └─ Promotion log       (their skill→tool history)

LAYER 5: Publishable content (opt-in shared)
  ├─ Skills they author and publish
  ├─ Agents they share
  └─ Knowledge graph contributions to a public commons (when 3c lands)

Container topology

Three options:

Option X — One Docker stack, multi-tenant via tenant_id

┌─ ONE Docker stack on Liz's hosted infra ──────────────┐
│                                                        │
│   FastAPI (single)        ← all tenants hit this       │
│   Postgres (single)       ← rows scoped by tenant_id   │
│   LanceDB (single dir)    ← table per tenant           │
│   Grafana (single)        ← dashboards per tenant      │
│                                                        │
└────────────────────────────────────────────────────────┘

Pros: cheap, simple, one thing to operate. Cons: noisy-neighbor risk, a single bug can leak data, less user control.

Option Y — Per-user Docker stack (each user = their own deployment)

User A:  ┌─ Docker stack ──┐    User B:  ┌─ Docker stack ──┐
         │ FastAPI         │             │ FastAPI         │
         │ Postgres        │             │ Postgres        │
         │ LanceDB         │             │ LanceDB         │
         │ Grafana         │             │ Grafana         │
         └─────────────────┘             └─────────────────┘
         their machine OR                 their machine OR
         their Render service             their Render service

Pros: complete data isolation, user owns the infra, simpler legal/regulatory posture. Cons: more cost if Liz hosts (one Render service per user), harder to operate at scale, no cross-tenant features.

Option Z — Hybrid: shared platform, per-user data containers

┌─ Shared Docker (Liz operates) ─────────────────────────┐
│   FastAPI gateway · auth · public docs · public skills │
└──────────────┬─────────────────────────────────────────┘
               │ routes per-tenant requests to:

   ┌───────────▼──────────┐    ┌──────────────────────┐
   │ User A's data pod    │    │ User B's data pod    │
   │ Postgres + LanceDB   │    │ Postgres + LanceDB   │
   └──────────────────────┘    └──────────────────────┘

Pros: shared platform code with isolated user data. Cons: highest operational complexity; requires per-user containers and a routing layer.

Today vs planned

ModeTopology todayPlanned
Self-hostOption X with tenant_id="default" — one Docker stack on the user's machine, single user.Same.
Hosted (humancensys.com)Single-stack with UI on Vercel; agent backend on Render. No multi-tenancy yet.Choice: X (shared with tenant_id), Y (per-user instances), or Z (hybrid).

Engine, commons, personal toolkit

A three-tier model:

┌─ ENGINE — the larger organizational thing (shared by everyone) ──────────┐
│                                                                           │
│   Platform code · auth · public docs · runtime infrastructure            │
│   The FastAPI app, the deepagents runtime, LanceDB engine, Postgres      │
│                                                                           │
└──────────────────────────┬────────────────────────────────────────────────┘

        ┌──────────────────┼──────────────────────────────┐
        │                  │                               │
┌───────▼────────┐  ┌──────▼──────────┐  ┌────────────────▼───────────┐
│ COMMONS        │  │ PERSONAL        │  │ PERSONAL                    │
│ (shared by     │  │ TOOLKIT (User A)│  │ TOOLKIT (User B)            │
│  everyone)     │  │                 │  │                             │
│                │  │ Their clan      │  │ Their clan                  │
│ Public skills  │  │ Their convos    │  │ Their convos                │
│ Public agents  │  │ Their memory    │  │ Their memory                │
│ Public knowledge graph (opt-in publish)│  Their roadmap              │
│ Public templates│  │ Their KG canon  │  │ Their KG canon              │
└────────────────┘  └─────────────────┘  └─────────────────────────────┘

Engine: the shared runtime. FastAPI, deepagents, LanceDB, Grafana — same code for every user.

Commons: the shared content layer. Public skills, public agent templates, opt-in public knowledge contributions.

Personal toolkit: per-user data. Conversations, memory, clan, roadmap, private knowledge. Never shared with another user without explicit publish.

Recommendation: Option X with explicit commons

A single shared Docker stack (the engine) with tenant_id partitioning all user-private data. The commons is data marked public = true (or in a separate namespace) that any tenant can read.

LayerContainer topologyData isolation
EngineOne shared Docker stack (FastAPI + Postgres + LanceDB + Grafana)n/a — code
CommonsShared servicesPublic namespace; readable by everyone; publish requires user consent
Personal toolkitShared servicestenant_id-scoped on every query

Tradeoffs against the alternatives:

  • Option Y (per-user Docker stacks) loses the commons. With every user in an isolated container, there is no shared knowledge graph or cross-user collaboration.
  • Option Z (hybrid) adds operational complexity. Justified when per-tenant data volumes outgrow shared infra, which is not the case here.
  • Option X matches the pattern used by most multi-tenant platforms (GitHub, HuggingFace, Notion, Linear).

Open work (Pillar 0)

For Option X in hosted mode, the foundational work in ROADMAP.md Pillar 0:

  • Tenant abstractiontenant_id column on every personal-toolkit table, scoped queries everywhere, isolation tests
  • Auth interfaceNoAuthBackend (self-host) and OAuthBackend (hosted)
  • Config loader abstraction — filesystem (self-host) ↔ multi-tenant config store (hosted)
  • PLATFORM_MODE env var — single switch determines auth backend
  • Commons table partitioning — public namespace for skills, agents, KG nodes that opted in to publish

Self-host runs as Option X with tenant_id="default" — no multi-tenancy code path executes.

Codebase status

Done:

  • Single Docker stack (platform/deploy/docker-compose.yml) for both self-host and "hosted = your own instance"
  • render.yaml deploys one instance per user
  • Web UI on Vercel, calling each user's agent backend via NEXT_PUBLIC_AGENT_URL

Open (Option X path):

  • Tenant abstraction (tenant_id column, scoped queries)
  • Auth interface
  • Config loader abstraction
  • PLATFORM_MODE=multitenant env var

Open (Option Y path):

  • A "deploy to Render" flow on humancensys.com
  • Optional: a routing layer mapping <username>.humancensys.com to the user's Render URL

Two-mode discipline

Every change considers:

  1. Self-host user impact
  2. Hosted-multitenant user impact (when that mode exists)
  3. Tests for both modes
  4. Docs for both modes

Anti-patterns

  • Hardcoded paths or queries without tenant scoping (in the Option X path)
  • "Multi-tenancy can come later" — retrofitting after data is being written is a migration cost
  • Mixing platform code and tenant data in the same repo

Concretely

Self-host: docker compose up runs the engine locally. tenant_id="default" is hardcoded in the no-auth path.

Hosted (humancensys.com): Liz operates one Docker stack as the engine. Users get tenant identities and share infrastructure; personal toolkit data is never shared. Public skill library and knowledge commons live in shared services with a public = true marker.

Every PR, query, and write goes through the tenant abstraction. Tests verify isolation. Anti-patterns at /docs/contributing.