Skip to content

The config store

The config store is what turns Hivemind from a single-operator tool into a product: per-user configuration, stored in the Hub, isolated per tenant, consumed per need. It holds the saved records that the runtimes read — how to deploy a Commander, how to run a workflow, and how each target should be gated — each owner-scoped and validated against its schema.

The store invents no new runtime. It is CRUD plus schema validation plus provenance over a small set of record types; each record is consumed by the runtime that already knows how to act on it.

The record types

Record What it configures Consumed by
commander_deployments a saved "deploy a Commander like this" — box + project + model + budget + cred refs the remote-Commander control surface
workflows a saved LLM-workflow — model, prompt, allowed actions, trigger, output, gates, budget, cred refs the workflow runtime
gate_rules per-(target, action) operator rules — auto / ask-me / never the unified gate evaluator

A Commander-deployment record references, rather than copies, the composed pieces: the target box, the project the Commander coordinates, the model, and a budget ceiling. Its per-target gate rules are not embedded — they live in gate_rules keyed by that box. The deployment points at the box; the gate model composes the rules for it. This compose-not-duplicate discipline runs through the whole design: one fact lives in one place and is referenced, never mirrored.

With a saved deployment, the control surface's deploy path can consume a stored record by id — "config stored in the Hub, used per need" — instead of a raw request body.

Isolation is the point

Every record carries two keys:

  • owner_id — the per-user key within a tenant.
  • tenant — the outer boundary.

Every read and every write filters by both, resolved from the request's verified principal. A second user cannot read, list, or consume another user's saved deployment — the (tenant, owner_id) filter denies. A tenant mismatch denies exactly as a capability check denies. That cross-user isolation is the thesis proof of the config store: the smallest meaningful test is "user B cannot see user A's config."

The schema is designed to be defense-in-depth ready. In the shared-instance model, a per-connection tenant setting plus row-level security in the database is the backstop so a missing WHERE clause cannot leak across tenants; in the container-per-tenant model the container itself is the boundary and row-level security is optional. Building the schema isolation-ready from the start costs little and keeps the shared-SaaS move a later flip rather than a rewrite.

Tenancy models

Two deployment shapes reach the same product surface:

  • Container-per-tenant — each customer gets their own Hub container, database, and encryption key. Isolation is the container/DB boundary: the strongest isolation, and the shape the platform runs today. Productization here is per-user config and isolation within a tenant's instance.
  • Shared multi-tenant — one Hub serves many tenants; the tenant is resolved per-request from auth, with row-level isolation and per-tenant credential-key derivation. Maximum density, at the cost of moving the isolation boundary from the container to every query — the classic multi-tenant-SaaS hard problem.

The config store and credential scoping work identically in both models, so they are built first and the model choice is deferred. The near-term default is container-per-tenant with the shared-tenant seam kept live, so the shared move is a configuration flip, not a re-architecture.

Dark by default

The productization records land behind a flag that defaults OFF, following the same dark-launch pattern as the rest of the Hub. The record and its isolation are proven before any live deployment consumes them.