From b46667c309cce5bce6820d3a2cfa76396e88b549 Mon Sep 17 00:00:00 2001 From: MechaCat02 Date: Thu, 25 Jun 2026 07:12:25 +0200 Subject: [PATCH] docs: reconcile the groups/project-tool initiative into the roadmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The groups/project-tool work had no home in the blueprint's version scheme, two "Phase N" numbering schemes overlapped, and CLAUDE.md's "current focus" was stale (claimed v1.1.0 SDK foundation; we're at v1.1.9 with the SDK line complete). Reconcile all three: * blueprint §12 Phase 5 (v1.2, already titled "Advanced Workflows & Hierarchies") — split into a Hierarchies track (the groups + project tool initiative, with §11 Phases 1–3 marked shipped) and a Workflows track, with sequencing flagged as an open call. This gives the work an explicit version home: the Hierarchies half of v1.2. * design doc header — Status Draft → Active, "scheduled as the Hierarchies track of v1.2", and an explicit warning that §11's local Phase 1–6 numbering is distinct from the blueprint product-phase numbering. * design doc §11.1 — a post-Phase-3 re-sequencing review: resolve Phase 4 scripts LIVE (drop the fan-out-invalidation sub-project, per the Phase 3 result); consider a "Phase 5-lite" (declarative apply of vars/secrets + app scripts) before the hard group-scripts work; and force the two deferred decisions (trigger/route templates vs tenant cardinality; multi-repo ownership vs a single-repo start). * CLAUDE.md — refresh "current focus" to v1.2 Hierarchies, and correct the now-broken "every v1.1+ table is app_id NOT NULL" invariant: the new group-inheritable config tables (vars, secrets) use a polymorphic owner (group_id XOR app_id), not app_id NOT NULL. Doc-only; no code change. Co-Authored-By: Claude Opus 4.8 (1M context) --- CLAUDE.md | 6 ++++- docs/design/groups-and-project-tool.md | 34 ++++++++++++++++++++++++-- serverless_cloud_blueprint.md | 22 +++++++++++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 804beba..c33d0b6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,11 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co Authoritative design: [serverless_cloud_blueprint.md](serverless_cloud_blueprint.md). The blueprint is a living document — when architecture decisions are made in conversation that contradict it, treat the latest decision as truth and update the blueprint. -**Current focus (Phase 4, v1.1.0):** SDK foundation + stdlib utilities — the shape every v1.1.x service module hangs off, see [docs/sdk-shape.md](docs/sdk-shape.md). Stdlib reference at [docs/stdlib-reference.md](docs/stdlib-reference.md). Subsequent v1.1.x releases (KV in v1.1.1, docs in v1.1.2, …) fill it in; see blueprint §12 for the full table. Phase 3 shipped end-to-end: admin auth, multi-app scoping, and Phase 3.5 capability gating (`manager-core::authz::{can, require, Capability}` + migration `0006_users_authz.sql`). Every v1.1+ table starts with `app_id UUID NOT NULL REFERENCES apps(id) ON DELETE CASCADE` and every Rhai SDK call resolves its app from the execution context. +**v1.1.x — SDK foundation + services — is complete.** The SDK shape (handle pattern, `::` namespaces, `Services`/`SdkCallCx`; see [docs/sdk-shape.md](docs/sdk-shape.md), stdlib at [docs/stdlib-reference.md](docs/stdlib-reference.md)) fixed in v1.1.0, then KV, docs, modules, HTTP, cron, files, pub/sub, email, users, and durable queues + `invoke()` filled it in through **v1.1.9** — blueprint §12 has the table. Earlier groundwork: blueprint Phase 3 (admin auth, multi-app scoping, Phase 3.5 capability gating — `manager-core::authz::{can, require, Capability}`, migration `0006_users_authz.sql`). + +**Current focus: v1.2 _Hierarchies_ — groups + the declarative project tool** ([docs/design/groups-and-project-tool.md](docs/design/groups-and-project-tool.md)). That doc's §11 uses its own **Phase 1–6 numbering, distinct from the blueprint product-phase numbering above — do not conflate them** (its "Phase 3" = group-inherited config, not admin auth). Implemented on `feat/groups-*` branches: §11 Phase 1 (declarative `pic plan`/`apply`/`prune` + env overlays), Phase 2 (single-parent groups tree + hierarchy-aware RBAC), Phase 3 (group-inherited, env-scoped `vars` + secrets resolved **live** via a recursive CTE — no materialized cache). Next: group-owned scripts/modules (§11 Phase 4) and the project tool mapping onto groups (§11 Phase 5). + +**Data-model invariant:** app-owned data-plane tables (KV, docs, files, …) start with `app_id UUID NOT NULL REFERENCES apps(id) ON DELETE CASCADE`; the group-inheritable _config_ tables (`vars`, `secrets`) instead carry a **polymorphic owner** — nullable `group_id` and `app_id` with an exactly-one CHECK and per-owner partial-unique indexes. Every Rhai SDK call resolves its app from `cx.app_id`, never a script-passed arg (the cross-app isolation boundary). ## Three-Service Architecture diff --git a/docs/design/groups-and-project-tool.md b/docs/design/groups-and-project-tool.md index 3703a42..bcc7af6 100644 --- a/docs/design/groups-and-project-tool.md +++ b/docs/design/groups-and-project-tool.md @@ -1,9 +1,13 @@ # Groups, Projects & the Declarative Project Tool -> **Status:** Draft — design discussion captured 2026-06-18, revised 2026-06-20 with resolutions +> **Status:** Active — design discussion captured 2026-06-18, revised 2026-06-20 with resolutions > grounded in precedent (GitLab, Kustomize, Helm, Terraform, Kubernetes Server-Side Apply, Pulumi) > and corrected against the codebase after three independent review passes (consistency, gaps, -> feasibility). Not yet scheduled into a phase. +> feasibility). **Scheduled as the *Hierarchies* track of v1.2** (blueprint §12 Phase 5). §11 Phases +> 1–3 (project tool, groups + hierarchy RBAC, group-inherited config) are **shipped**; Phases 4–6 +> remain. NB: §11's own Phase 1–6 numbering is local to this initiative and is **distinct from the +> blueprint product-phase numbering** — "Phase 3" here = group-inherited config, not the blueprint's +> admin-auth phase. > > **Scope:** turns the imperative `pic` CLI into a declarative, file-based project tool, and > introduces a server-side **groups** hierarchy so apps can share and inherit config/scripts @@ -944,6 +948,32 @@ Resolved items now live inline next to their topic. What genuinely remains: real shared-scope authz model. Optionally, trigger/route **templates** (§4.5) if cardinality demands. +### 11.1 Re-sequencing review (post-Phase-3) + +A review after Phase 3 shipped surfaced three adjustments to the 4→6 plan; carried here as decisions +to take, not yet taken: + +- **Phase 4 should resolve scripts *live*, not materialize.** §11.4 carries "cache-invalidation + fan-out hardening" as a deliverable, a holdover from the materialized-view model. Phase 3 proved + **live resolution** (recursive CTE per call) is sufficient and sidesteps the §10 invalidation SLA, + and script *bodies are already live-resolved per request today* (§5.1). So Phase 4 should resolve + group-owned scripts live too and **drop the fan-out-invalidation sub-project** unless a *measured* + hot-path cost appears. This removes the scariest item from Phase 4; the real remaining cost is the + **module/import resolver redesign** (§5.5), which is unaffected by this and stays the gating risk. +- **Consider a "Phase 5-lite" *before* Phase 4.** The declarative project tool already applies app + scripts (Phase 1) and Phase 3 shipped the group vars/secrets CRUD, so a project tool that declares + **group vars/secrets + app scripts** needs *nothing* from Phase 4 (group-owned scripts). The + highest-leverage day-to-day workflow (declarative config apply) can ship ahead of the hard + module-resolver work. Phase 4 then adds group-owned *scripts* to an already-working project tool. +- **Two deferred decisions to force, not default:** + - *Trigger/route templates (§4.5):* bundled into Phase 6 as "much later," but the per-app binding + tax bites in Phase 5 at high tenant cardinality (100 tenants × 5 triggers = 500 declarations). + Decide against **actual** target tenant counts before defaulting it late. + - *Multi-repo ownership (§7):* the single-owner / attach-point / takeover machinery is substantial + and only earns its keep with a **second** managing repo. For a solo-dev / single-repo start, a + "one repo owns the whole subtree" model covers the near term; confirm the multi-repo need exists + before building the ownership layer. + --- ## 12. Contracts still to draft diff --git a/serverless_cloud_blueprint.md b/serverless_cloud_blueprint.md index 27a3226..641e87a 100644 --- a/serverless_cloud_blueprint.md +++ b/serverless_cloud_blueprint.md @@ -1256,6 +1256,28 @@ Released in patch steps (v1.1.0 → v1.1.8), each landing one focused capability --- ### Phase 5: v1.2 (Advanced Workflows & Hierarchies) + +Two tracks under the same minor line. The **Hierarchies** track is in active development; the +**Workflows** track follows it (or runs in parallel — sequencing is an open call, see the design doc's +§11 re-sequencing note). + +**Hierarchies — groups + the declarative project tool** (the detailed design and 6-phase breakdown +live in [docs/design/groups-and-project-tool.md](../docs/design/groups-and-project-tool.md) §11; this +absorbs the original one-line "Hierarchies" bullet into a full initiative): +- A single-parent **groups** tree above apps, with hierarchy-aware RBAC (inherited membership). *(§11 + Phase 2 — shipped: `0047_groups.sql`, `effective_app_role`/`effective_group_role`.)* +- **Group-inherited, environment-scoped config** — `vars` + group secrets, resolved **live** (recursive + CTE, no materialized cache) with the §3 proximity/merge/tombstone rule; the group-secret AAD scheme; + masked secrets (an app runs with config its own devs cannot read). *(§11 Phase 3 — shipped: + `0048_vars.sql`, `0049_group_secrets.sql`.)* +- A **declarative, file-based project tool** (`pic plan`/`apply`/`prune`, env overlays, the three-state + `enabled` lifecycle, bound-plan staleness check). *(§11 Phase 1 — shipped.)* +- Remaining: group-owned **scripts/modules** with the scope-aware import resolver (§11 Phase 4); the + project tool **mapping onto the group tree** (nested manifests, attach points, ownership — §11 Phase + 5). Group-level shared *data* (collections/topics) stays in v1.3 (the cross-app-sharing problem + below). + +**Workflows:** - Function workflows (DAG execution, conditional branching, error handling) - Nested workflows - Call graph visualization + execution tracing