From 9b4a8346272a61ef8b1f0827d69b6884d0cf1bac Mon Sep 17 00:00:00 2001 From: MechaCat02 Date: Sat, 30 May 2026 18:58:29 +0200 Subject: [PATCH] =?UTF-8?q?chore(claude-md):=20refresh=20for=20v1.1.0=20?= =?UTF-8?q?=E2=80=94=20focus,=20working=20rules,=20env=20vars?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Current focus moves to v1.1.0 (SDK foundation + stdlib) with a pointer to docs/sdk-shape.md. Notes Phase 3.5 capability gating is shipped end-to-end. - Tech-stack line drops the misleading "v1.1+ hstore" mention; v1.1+ data-plane tables now use JSONB (see blueprint §8.1). - New Working Rules bullet for the handle pattern + SdkCallCx rule: services derive app_id from cx.app_id, never from a script-passed arg. That is the cross-app isolation boundary. - New "Runtime configuration" table documenting every env var the picloud binary consumes — including the new PICLOUD_MAX_CONCURRENT_EXECUTIONS alongside the existing PICLOUD_BIND, DATABASE_URL, session TTL, and sandbox knobs. Co-Authored-By: Claude Opus 4.7 (1M context) --- CLAUDE.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index bd5ec44..9e27af9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,7 @@ 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):** data-plane SDKs — KV store, then document store, then HTTP client, then cron triggers. See blueprint §12. Phase 3 (admin auth + multi-app scoping) shipped; 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. +**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). 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. ## Three-Service Architecture @@ -48,7 +48,7 @@ Caddy fronts everything. Same Caddyfile shape works for single-node and cluster - **Rust 1.92+** workspace, pinned via `rust-toolchain.toml` - **Axum** for HTTP, **Tokio** async, **sqlx** for Postgres - **Rhai** embedded scripting (in `executor-core`) -- **PostgreSQL 15+** with `pgcrypto` and (v1.1+) `hstore` +- **PostgreSQL 15+** with `pgcrypto`. v1.1+ data-plane tables use JSONB for value columns (hstore was considered for KV and rejected — see blueprint §8.1). - **SvelteKit** dashboard, static adapter, CodeMirror 6 for the script editor - **Caddy 2** reverse proxy (auto-HTTPS in prod) - **Docker Compose** for dev and single-node prod @@ -103,9 +103,22 @@ docs/ - **Honor the three-service boundary.** Don't reach across `*-core` crates. If `orchestrator-core` needs something from `manager-core`, define a trait in `shared` and inject the impl. - **`executor-core` has no Postgres dependency.** Data-plane services (kv, docs, users — v1.1+) come in via injected `ServiceProvider` traits. - **Database writes only from `manager-core`.** `orchestrator-core` reads scripts (cached); `executor-core` doesn't touch the DB. +- **Stateful SDK services use the handle pattern + `SdkCallCx`.** Collection-scoped surfaces look like `kv::collection("x").get(k)`, not `kv::get("x", k)`. Every service trait method takes `&SdkCallCx` and **MUST** derive `app_id` from `cx.app_id` — never trust a script-passed `app_id`. That is the cross-app isolation boundary. See [docs/sdk-shape.md](docs/sdk-shape.md). - **MVP builds only the `picloud` all-in-one binary.** The three split binaries exist as skeletons so the crate boundaries stay honest; flesh them out only when cluster mode is being implemented. - **Trunk-based dev.** See [docs/git-workflow.md](docs/git-workflow.md). No long-lived branches. Feature flags for incomplete work. +## Runtime configuration + +Environment variables consumed by the `picloud` binary: + +| Variable | Default | Purpose | +|---|---|---| +| `PICLOUD_BIND` | `0.0.0.0:8080` | HTTP listen address. Port 8080 is owned by another process on this host — override locally. | +| `PICLOUD_MAX_CONCURRENT_EXECUTIONS` | `32` | Global concurrency cap on data-plane script executions. Overflow returns HTTP 503 with `Retry-After: 1` immediately (no queue). | +| `DATABASE_URL` | — | Required. Postgres connection string. | +| `PICLOUD_SESSION_TTL_HOURS` | `24` | Sliding-window session lifetime. | +| `PICLOUD_SANDBOX_MAX_*` | conservative defaults | Per-knob admin ceilings on Rhai sandbox overrides. See `manager-core::sandbox::SandboxCeiling`. | + ## Out of MVP Queue triggers, cron triggers, SMTP ingress, KV / docs / email / users / HTTP SDKs in scripts, interceptors, workflows, function-to-function `invoke()`, secrets, metrics dashboard. All deferred to v1.1+ per the blueprint. Don't pre-build for them — but don't make decisions that close the door on them either.