test(cli): project-tree journeys + Phase 5 docs
Phase 5 C5. Three `pic ... --dir` tree journeys:
* a group + a nested app apply atomically as one tree (the app's route binds
the group's same-apply `shared` script); the group node's script is
created; re-plan is all-noop (idempotent),
* one invalid node aborts the whole tree — the valid group node's script is
NOT created (true all-or-nothing),
* a `pic groups reparent` between `pic plan --dir` and `pic apply --dir` trips
the bound-plan (StateMoved) check via the tree's structure version.
Docs: `groups-and-project-tool.md` §11.5 status (✅ shipped — single-repo
nested tree apply; multi-repo single-owner + per-env approval gating deferred
per §11.1) + CLAUDE.md current-focus.
Gates: fmt, clippy -D warnings, cargo test --workspace, check-versioning (50
migrations — Phase 5 added none), schema snapshot unchanged, full journey suite
108/108. (Pre-existing flake `queue_e2e::queue_receive_acks_on_success` — a
racy immediate `count==0` after the async ack; flaky at the pre-Phase-5
baseline too, unrelated to this work.)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -986,6 +986,37 @@ Resolved items now live inline next to their topic. What genuinely remains:
|
||||
> delete itself stays `RESTRICT`).
|
||||
5. **Project tool maps onto groups.** Nested manifests, attach point, single-owner, server-computed
|
||||
tree plan, per-env approval gating.
|
||||
|
||||
> **Status (Phase 5): ✅ shipped — single-repo nested tree apply, atomic.** A directory tree of
|
||||
> `picloud.toml` manifests (each declaring an `[app]` or `[group]` node) applies as ONE
|
||||
> server-computed plan in ONE Postgres transaction. Per the §11.1 review, the **multi-repo
|
||||
> single-owner / attach-point / takeover** layer (§7) is **deferred** for the solo-dev / single-repo
|
||||
> start, as is **per-env approval-policy gating** (`[project.environments]`); env overlays
|
||||
> (`picloud.<env>.toml`) already exist. Groups must **pre-exist** (`pic groups create`) — a manifest
|
||||
> owns each node's *content*, not the tree *shape* (declarative group create/reparent is a later
|
||||
> add).
|
||||
>
|
||||
> Shipped surface:
|
||||
> - **Engine:** the reconcile engine generalized from app-only to an `ApplyOwner { App | Group }`
|
||||
> (a group node has only scripts + vars; routes/triggers/secret-values stay app-only). The in-tx
|
||||
> reconcile is `reconcile_node_tx`, shared by single-node and tree apply. `apply_tree` locks every
|
||||
> node key (sorted), reconciles **groups first** (recording each group's `name → id`), then apps —
|
||||
> so an app route/trigger can bind a group script **created in the same transaction** (resolved
|
||||
> nearest-ancestor-wins across the in-tree index + pre-existing ancestors; the pool resolver can't
|
||||
> see uncommitted rows). One commit, one post-commit route refresh.
|
||||
> - **Bound plan covers structure:** the tree token folds every node's `state_token` **plus every
|
||||
> in-scope group's `structure_version`**, so a reparent (or content edit) between plan and apply
|
||||
> trips `StateMoved` — the §4.2 "content **and** tree-structure version" check.
|
||||
> - **API:** `POST /api/v1/admin/{groups/{id},tree}/{plan,apply}`; per-node capability gating (the
|
||||
> actor must hold the read/write caps for **every** node touched).
|
||||
> - **CLI:** a `[group]` manifest kind; `pic plan/apply` on one node (app or group); `pic
|
||||
> plan/apply --dir <root>` discovers + applies the whole tree, with a single `<tree>` bound token.
|
||||
>
|
||||
> Live- and journey-validated: a group + nested app apply atomically (app route binds the group's
|
||||
> same-apply script); re-plan is all-noop; one invalid node aborts the whole tree (nothing written);
|
||||
> a `pic groups reparent` between plan and apply is refused. The §5.1 materialized effective-view +
|
||||
> fan-out invalidation was **not** built — group config/scripts resolve **live** (Phase 3/4),
|
||||
> so the tree apply needs no cache-invalidation protocol.
|
||||
6. **(Much later) group-level collections/topics** — the v1.3 cross-app data-sharing problem, with a
|
||||
real shared-scope authz model. Optionally, trigger/route **templates** (§4.5) if cardinality
|
||||
demands.
|
||||
|
||||
Reference in New Issue
Block a user