-- §7 multi-repo ownership: the `projects` registry + wiring the inert -- `owner_project` seam. -- -- A "project" is a repo-root that declaratively MANAGES a slice of the shared -- group tree (contains its manifest as something it applies, not merely -- references). §7's model is SINGLE-OWNER-PER-NODE: each group node is owned by -- exactly one project; the first `pic apply` that declares a `[project]` claims -- the node, and a second repo applying to an owned node is refused unless it -- passes a group-admin-gated `--takeover`. Ownership ⟂ RBAC — it records which -- manifest is authoritative, not whether a principal may act. -- -- Identity is a committed `[project] slug` (stable across clones); the server -- assigns the UUID (server-internal). The `owner_project UUID` column already -- exists on `groups` (0047, inert) — this migration creates the table it was -- always meant to reference and wires the FK. Apps carry NO owner column: an -- app inherits ownership from its NEAREST claimed ancestor group (the ancestor -- walk is the isolation boundary), faithful to §7's "don't co-own a node — -- split config downward" corollary. CREATE TABLE projects ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Instance-global identity, declared in the repo's committed root manifest -- and frozen. First apply with a new slug registers the project. slug TEXT NOT NULL UNIQUE, name TEXT NOT NULL, -- The admin who first registered it. SET NULL (not CASCADE) — losing the -- creator's account must not orphan-delete the project or un-claim its tree. created_by UUID REFERENCES admin_users(id) ON DELETE SET NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- Wire the inert 0047 seam. ON DELETE SET NULL un-claims the owned nodes (they -- fall back to UI/API-owned) rather than cascading a destructive tree delete — -- deleting a project must never destroy the groups/apps it happened to manage. ALTER TABLE groups ADD CONSTRAINT groups_owner_project_fk FOREIGN KEY (owner_project) REFERENCES projects(id) ON DELETE SET NULL; -- Ownership lookups: "what does project X own?" (pic projects ls) and the -- LEFT JOIN behind pic groups ls' owner column. CREATE INDEX groups_owner_project_idx ON groups (owner_project);