From 49c4fb41ce96c422a757156cc51840bc98c130b3 Mon Sep 17 00:00:00 2001 From: MechaCat02 Date: Wed, 24 Jun 2026 20:16:29 +0200 Subject: [PATCH] docs(design): mark Phase 2 (groups) shipped + record decisions/deferrals Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/design/groups-and-project-tool.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/design/groups-and-project-tool.md b/docs/design/groups-and-project-tool.md index 8017cc0..0f3ca47 100644 --- a/docs/design/groups-and-project-tool.md +++ b/docs/design/groups-and-project-tool.md @@ -853,6 +853,28 @@ Resolved items now live inline next to their topic. What genuinely remains: RESTRICT**, reparent/rename with the **ancestor-walk cycle guard** + **slug-freeze** + **tree-structure version**, §5.6), inherited membership, hierarchy-aware `can`, UI grouping, the §9 backfill. No shared resources yet — cheap, no data-plane schema change. + + > **Status (Phase 2): ✅ shipped.** Migration `0047_groups.sql` adds `groups` (self-FK + > `parent_id` ON DELETE RESTRICT, instance-global frozen `slug`, `structure_version`, inert + > `owner_project` §7 seam) + `group_members` (same `app_admin|editor|viewer` literals as + > `app_members`) + `apps.group_id` (NOT NULL, RESTRICT) with the §9 single-root backfill. The + > tree lives in `group_repo` (reparent: ancestor-walk cycle guard under a coarse instance-wide + > structural advisory lock, slug-freeze, `structure_version` bump; delete=RESTRICT) and + > `group_members_repo`. **Hierarchy-aware RBAC** (§5.3): `AuthzRepo::effective_app_role` / + > `effective_group_role` resolve the highest role across the app's own membership + every ancestor + > group via one depth-bounded recursive CTE; `authz::can`'s Member path folds inherited group + > roles, so a `group_admin` on any ancestor is implicitly app_admin beneath it — resolved **live** + > per request (revocation is immediate). New caps `InstanceCreateGroup` / `Group{Read,Write,Admin}` + > (no `app_id` ⇒ bound API keys can't manage groups). Surfaced via `groups_api`, `pic groups …`, + > and a dashboard group tree + detail/members. `structure_version` is bumped but not yet a consumer + > beyond the reparent path (CLI structural-drift detection is Phase 5). + > + > Deferred to Phase 3+ (unchanged): group-*owned* scripts/vars/secret-refs, the materialized + > effective-view resolver, masked group secrets + the group-secret AAD scheme, module/import + > resolution under inheritance, `config --effective --explain`, and personal-namespace root groups + > (the backfill seeds a single instance root). The §10 **inherited-membership revocation-lag** risk + > does not bite in Phase 2 because resolution is live (no inherited-role cache); it returns only + > when Phase 3's materialized views land. 3. **Group-inherited config** (vars, secret-refs, env-scoped). The net-new `vars`/`secret-refs` tables + polymorphic owner; the group-secret AAD scheme (§5.3 caveat); masked group secrets; the effective-view resolver + materialization + invalidation; **`config --effective --explain`** (hard