-- Loop staffing: attach agents / teams / orgs to a loop so the run driver -- knows who fills the role slots baked into loops.graph. Three parallel -- join tables, one per selection tier — the wizard lets the user mix modes -- (e.g. one team + two individual specialists). -- -- All FKs cascade off loop_id so an existing hard-delete of a loop stays a -- single-statement operation with no orphans. Agent/team/org deletions -- also cascade so we never point at a phantom entity. CREATE TABLE loop_agents ( loop_id UUID NOT NULL REFERENCES loops (id) ON DELETE CASCADE, agent_id UUID NOT NULL REFERENCES agents (id) ON DELETE CASCADE, role_slot TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), PRIMARY KEY (loop_id, agent_id) ); CREATE INDEX loop_agents_agent_idx ON loop_agents (agent_id); CREATE TABLE loop_teams ( loop_id UUID NOT NULL REFERENCES loops (id) ON DELETE CASCADE, team_id UUID NOT NULL REFERENCES teams (id) ON DELETE CASCADE, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), PRIMARY KEY (loop_id, team_id) ); CREATE INDEX loop_teams_team_idx ON loop_teams (team_id); CREATE TABLE loop_orgs ( loop_id UUID NOT NULL REFERENCES loops (id) ON DELETE CASCADE, org_id UUID NOT NULL REFERENCES orgs (id) ON DELETE CASCADE, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), PRIMARY KEY (loop_id, org_id) ); CREATE INDEX loop_orgs_org_idx ON loop_orgs (org_id);