layered-soul/docs/HIVE-ONBOARDING.md
Sam & Claude 7c3016cf06 docs(hive): record first-proof policy — scratch jail + test collection until hardening
First proven end-to-end uses a scratch jail + throwaway test collection only; no
real tenant data until path hardening (#92) lands. First-proof blockers are #88
(resolve collection by name) and #89 (per-call unlock); #92 is hardening.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 06:39:31 +02:00

6.5 KiB

Hive Onboarding — colibri-vault and the "join the hive" primitive

LIVE VS PLANNED. This is a design/vision doc. The building blocks are real and proven (Bastille jails on osa, capability routing, register-agent, and the clawdie-vault-fetch flow validated end-to-end on domedog 2026-06-19). The platform described here — colibri-vault as a crate, multi-tenant buckets, the mother skill — is [PLANNED]. The thesis: it is mostly composition of pieces we already have, not new invention. Sections are tagged [LIVE] / [PLANNED].


1. The core idea

The Vaultwarden→.env fetch we proved is not a utility — it is the onboarding primitive. Promote it from the clawdie-vault-fetch shell helper to a first-class crate, colibri-vault, sitting beside colibri-spawner / colibri-store:

  • in: a tenant id (→ a bucket) + a target jail/home
  • out: a 0600 .env materialized inside the jail, owned by the jail user
  • wraps the bw CLI for now (do not reimplement the Bitwarden protocol), fail-closed, idempotent, no-op when there is no bucket

It stops being "a thing you run" and becomes "a thing the hive does to you when you join."

2. [PLANNED] "Join the hive" = one composed step

spawn jail   →   colibri-vault provision   →   register-agent
(spawner,LIVE)   (new crate, PLANNED)          (LIVE)

The first and third primitives already exist. Vault-provision is the missing limb between an empty Bastille jail and a participating hive member. Once secrets land and the agent registers its capabilities, everything else — capability routing, poll/worker loop, the cross-host bridge — is already live (see CAPABILITY-ROUTING.md).

3. The mapping (decided)

tenant_id == Bastille jail name == Vaultwarden bucket, 1:1:1. One row in colibri-store: (tenant_id, jail, collection_id, status, created_at). No more indirection than that.

On "folder vs bucket":

  • Folders are personal-vault organization → fine for Clawdie's own internal agents.
  • Organization + Collections give access-scoped isolation → the multi-tenant primitive. One customer = one Collection; a scoped credential reads only that collection.
  • Do not run a separate Vaultwarden instance per customer — Collections are exactly this feature.

4. The "one key" ideal — actually two ones

  • Customer's one key: a single provider key in their bucket. OpenRouter is the exemplar (one key → every model), but a single direct-provider key works too — DeepSeek alone is the currently validated single-key case. The point is one secret per tenant.
  • Operator's one key: the Vaultwarden org service-account credential, held only on the orchestrator, that can read any tenant collection to provision jails.

Everything non-secret — harness, base config, model-routing prefs — ships in the clawdie-iso image. The image is the body; the bucket is the one private nerve.

5. [PLANNED] The mother skill

The genesis routine every image carries — the one skill that turns a jail into an agent:

mother := resolve-identity (layered-soul)
        ∘ acquire-secrets   (colibri-vault)
        ∘ register          (colibri capabilities)
        ∘ heartbeat / poll
  • Narrow: onboarding — births one working agent from a bare jail.
  • Wide: self-replication. An agent that holds the mother skill can spawn and provision more jails (a queen births workers, each inheriting the mother skill), gated by capability/policy so it cannot run away. That is "agent swarms with a mother skill," and colibri-vault is how each birth gets its one nerve.

osa/FreeBSD/Bastille is the natural womb — cheap, dense, isolated jails.

6. The product, and the moat

A customer pastes one key → gets a private agent in an isolated jail → that lean agent transparently borrows the whole multi-OS swarm's capabilities via the routing already shipped.

A one-key agent on osa needs image-render? It routes to a Linux lane (domedog). Needs a build? Routes to a capable host. The customer pays for one agent but stands on a survivable, multi-OS hive. Anyone can run an LLM in a container; few hand you a swarm behind one key — capability routing is the differentiator.

  • osa = the tenant-jail host (the hive body, dense Bastille jails)
  • debby / domedog = capability lanes (specialized organs)
  • Vaultwarden = per-tenant nerve store
  • clawdie-iso = the shared body every jail boots from

7. The security invariant (non-negotiable)

Bootstraps live on the host; jails hold only their resolved secrets.

  • The orchestrator holds the org service-account credential. It fetches a tenant's collection, writes the resolved .env into the jail, and the bootstrap never enters the jail. A compromised jail cannot re-fetch and cannot reach another tenant.
  • Per-tenant blast radius = one collection. Scoped credential, never a master.
  • This is the same shape the domedog smoke test validated (bootstrap on host, .env is the output) — just made multi-tenant.

8. [PLANNED] Lean MVP — and what NOT to build yet

Smallest path that is real:

  1. colibri-vault crate — lift clawdie-vault-fetch into Rust (lib + CLI), fetch a named collection → jail .env. Retire the shell helper.
  2. tenants row in colibri-store — the 1:1:1 map.
  3. Spawner hook — call vault-provision right after jail create.
  4. mother skill in layered-soul — the genesis sequence above.

First-proof policy. The first proven end-to-end runs against a scratch jail + a throwaway test collection only — no real tenant data until the path hardening lands (canonicalize + allowed-root containment, colibri issue #92). The two first-proof blockers are colibri #88 (resolve the collection by name) and #89 (per-call unlock); #92 is hardening that follows. Tracker state lives on those issues.

Overengineering traps to avoid for now: a custom Bitwarden web UI (Vaultwarden's own UI

  • a Collection is enough to start), billing/metering, a native Bitwarden protocol in Rust, multi-region control plane, and recursive auto-spawn (gate it off until policy exists). Those are product layers; the four steps above are the engine.

See CAPABILITY-ROUTING.md for the routing layer the moat rests on, MCP-INTEGRATION.md for the board interface, and ../AGENTS.md for the agent matrix.