Decouples "many users" + "many server replicas" from "many machines" so the platform is tenant-isolated and horizontally safe on the current single node. - Per-signup workspaces (cm-auth): a new hosted-identity sign-in provisions and owns its own workspace instead of joining the first. Config-gated by auth.per_signup_workspace (default off); concurrent first-logins serialized by a per-subject advisory lock so no duplicate workspaces. - Terminal tickets in Postgres (migration 0016, hashed, single-use): any replica can redeem a ticket minted by another. Drops the in-process ticket map. - Container registry in Postgres (migration 0017, agent_containers): Terminal and Sandbox managers resolve an agent's container through a shared registry, so a 2nd replica reuses it instead of spawning a duplicate. node_id recorded as 'local' (Phase 2 hook). Boot reconcile removes only true orphans, so terminals now survive a redeploy (tmux sessions resume). - Per-workspace quotas (cm-api/quota.rs): plan-tier caps on agents + live containers, enforced at agent create + terminal spin-up (reconnects allowed), returned as HTTP 402. New GET /api/quota surfaces usage vs limits. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
18 lines
1014 B
SQL
18 lines
1014 B
SQL
-- Durable registry of the live container backing each agent (terminal / agent /
|
|
-- browser), so ANY server replica can find + reuse it instead of the former
|
|
-- in-process map (which made a 2nd replica spawn duplicate containers). node_id
|
|
-- records placement for the multi-node node-pool (Phase 2); it is 'local' today.
|
|
CREATE TABLE agent_containers (
|
|
agent_id UUID NOT NULL REFERENCES agents (id) ON DELETE CASCADE,
|
|
kind TEXT NOT NULL, -- 'terminal' | 'agent' | 'browser'
|
|
node_id TEXT NOT NULL DEFAULT 'local',
|
|
container_id TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
workspace_id UUID NOT NULL REFERENCES workspaces (id) ON DELETE CASCADE,
|
|
session_count INTEGER NOT NULL DEFAULT 0, -- live attached sessions (terminals)
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
last_seen TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
PRIMARY KEY (agent_id, kind)
|
|
);
|
|
CREATE INDEX agent_containers_idle_idx ON agent_containers (kind, last_seen);
|