test/docs(ownership): §7 apply_ownership journey + design/CLAUDE updates
End-to-end coverage of the M1 ownership claim through the real CLI + server: claim-on-first-apply + owner column, idempotent re-apply by the owner, a second project refused (409, naming the owner), --takeover by an admin, app-inheritance from the nearest claimed ancestor (owning project ok; foreign or absent project refused), and the capability gate — a member with only an editor GROUP role can reconcile but is refused --takeover (needs group-admin), with ownership unchanged after the failed takeover. - tests/apply_ownership.rs (registered in cli.rs); a grant_group_membership helper in tests/common/member.rs (group-level, mirroring the app one). - design doc §7 gains an M1-shipped status note; CLAUDE.md records §7 M1 and re-points 'Next' at M2 (attach ceiling) + M3 (blast-radius / pic projects ls). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -764,6 +764,22 @@ non-orphaning:
|
||||
**Corollary:** don't co-own a node — split config downward. Shared config lives *higher* (owned by a
|
||||
platform/shared repo attaching at root); team-specific bits go into subgroups each team owns.
|
||||
|
||||
**Status — M1 shipped (the ownership claim).** The `owner_project` seam (0047) is now live, backed by a
|
||||
first-class `projects` table (`0066`, UUID pk + unique slug; `owner_project` FKs it `ON DELETE SET NULL`).
|
||||
A `[project]` block (slug + optional name) in the repo's root manifest declares identity; the first apply
|
||||
with a new slug registers the project and **claims** each group node it touches. The claim is a gate run
|
||||
inside the apply transaction, under the per-node advisory lock, *before* the diff — so a conflict
|
||||
short-circuits with a 409 before any write. Pure policy (`decide_group_claim` / `decide_app_owner` in
|
||||
`apply_service`): unclaimed→claim, owner→no-op, foreign→conflict unless `--takeover` (which additionally
|
||||
requires `GroupAdmin` — ownership ⟂ RBAC), no-project-into-a-claimed-subtree→conflict. Apps carry no
|
||||
`owner_project`; an app inherits ownership from its **nearest claimed ancestor group** (the ancestor walk
|
||||
is the boundary), and an unclaimed subtree stays open (backward-compatible — nothing changes until a repo
|
||||
first declares `[project]`). Visibility: `pic groups ls` shows an `owner` column; `--takeover` on `pic
|
||||
apply`. Pinned by `apply_service` unit tests + the `apply_ownership` journey. **Deferred:** point 2's
|
||||
attach-point *ceiling* (M2 — `[project] parent_group`), and the plan-time cross-repo blast-radius preview +
|
||||
`pic projects ls` (M3). The **structural-divergence** detection of §6 and declarative group create/reparent
|
||||
(lifting "groups pre-exist") remain later work.
|
||||
|
||||
---
|
||||
|
||||
## 8. Diagrams
|
||||
|
||||
Reference in New Issue
Block a user