Rename Castle -> Wild PC across the repo

Repo-side rename only (Phases 1-3 of the migration plan); the live box
(~/.castle, systemd units, /data/castle, domains) is a separate cutover.

- Slug `castle` -> `wildpc`: CLI command, module names (wildpc_core/cli/api),
  dist names, entry point `wildpc = wildpc_cli.main:main`.
- Identifiers: CastleConfig/NATSClient/DirError/MDNS -> Wildpc*.
- Env/constants: CASTLE_* -> WILDPC_*; ~/.castle -> ~/.wildpc, castle.yaml ->
  wildpc.yaml, /data/castle -> /data/wildpc.
- Systemd UNIT_PREFIX castle- -> wildpc-; own programs castle-api/gateway/etc.
- Display prose "Castle" -> "Wild PC" in docs, agent-guide files, README, frontend.
- Package dirs and bootstrap yaml renamed via git mv; lockfiles regenerated;
  redundant nested uv.lock files dropped (workspace root lock is authoritative).

Tests: core 273, cli 47, wildpc-api 120 all pass. Frontend type-checks + builds.
Fixed a stale test fixture (secret_env_path kind arg) broken pre-rename.
This commit is contained in:
2026-07-18 22:55:08 -07:00
parent 25d7a522cc
commit 05b28cb584
190 changed files with 2428 additions and 3337 deletions

View File

@@ -1,13 +1,13 @@
# Supabase Apps in Castle
# Supabase Apps in Wild PC
> **This is a stack — creation-time guidance for writing _new_ database-backed
> web apps.** A stack is a template + conventions, not a runtime requirement.
> `castle program create --stack supabase` scaffolds from it and seeds the
> `wildpc program create --stack supabase` scaffolds from it and seeds the
> program's default dev-verb commands. See @docs/registry.md for `commands:`,
> `stack:` (optional), and the deployment `manager` (and derived `kind`).
How to build tiny, database-backed web apps as castle programs that target a
**shared Supabase substrate**. This is Castle's "a stack whose default is a
How to build tiny, database-backed web apps as wildpc programs that target a
**shared Supabase substrate**. This is Wild PC's "a stack whose default is a
substrate": the app owns its code (and stays repo-durable), and rents the boring
backend — Postgres + auth + storage + RLS — that an app can't reliably reinvent.
@@ -16,7 +16,7 @@ backend — Postgres + auth + storage + RLS — that an app can't reliably reinv
Unlike the other stacks (which scaffold a self-contained process), a supabase app
is **code + migrations that deploy against a shared backend**:
- **The substrate** is one castle service (`supabase`, the `supabase-substrate`
- **The substrate** is one wildpc service (`supabase`, the `supabase-substrate`
repo) running self-hosted Supabase via a `manager: systemd` deployment with the
`compose` launcher. It is shared by
every supabase app. Stand it up once (see that repo's README).
@@ -27,10 +27,10 @@ is **code + migrations that deploy against a shared backend**:
Apps are isolated on the shared instance by their **own Postgres schema + RLS**
(and Storage buckets), under **one identity pool** — correct for a single-operator
datalake. Each app owns a schema named after the program (`my-app` → schema
`my_app`); `castle program build` creates and grants it, tracks migrations in a
per-app `<schema>.schema_migrations`, and PostgREST exposes it (castle derives the
`my_app`); `wildpc program build` creates and grants it, tracks migrations in a
per-app `<schema>.schema_migrations`, and PostgREST exposes it (wildpc derives the
substrate's `PGRST_DB_SCHEMAS` from the registered apps). This gives a clean
teardown — `castle delete --purge-data` runs `drop schema <app> cascade` — and
teardown — `wildpc delete --purge-data` runs `drop schema <app> cascade` — and
means migration version tokens never collide across apps. Substrate-per-app is
deliberately not supported: ~14 containers per app doesn't scale to "lots of small
ideas," and a DB-backed app is a pet either way.
@@ -69,14 +69,14 @@ gateway serves `public/` in place at `<name>.<gateway.domain>` (its own subdomai
```yaml
name: my-app
substrate: supabase # the shared castle service this app deploys against
substrate: supabase # the shared wildpc service this app deploys against
auth: public # public | private | shared: [handles]
schema: my_app # this app's isolated Postgres schema (frontend: db.schema)
```
## Migrations
`migrations/*.sql` are **numbered, forward-only, and idempotent**. `castle program
`migrations/*.sql` are **numbered, forward-only, and idempotent**. `wildpc program
build my-app` runs the versioned migration runner: it creates + grants the app's
schema, ensures a per-app `<schema>.schema_migrations` table, reads applied
versions, and applies only the **unapplied** files (in filename order) with
@@ -112,14 +112,14 @@ const db = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, { db: { schema: SCHEMA
### Teardown
An app's rows live only on the substrate, so an ordinary `castle delete my-app`
An app's rows live only on the substrate, so an ordinary `wildpc delete my-app`
leaves the schema intact (and says so). To destroy the data too:
```bash
castle delete my-app --purge-data # drop schema my_app cascade
wildpc delete my-app --purge-data # drop schema my_app cascade
```
`castle apply` then prunes the schema from `PGRST_DB_SCHEMAS`; **restart the
`wildpc apply` then prunes the schema from `PGRST_DB_SCHEMAS`; **restart the
`supabase` service** for PostgREST to pick up the added/removed schema list.
## Auth, RLS & the three privacy layers
@@ -158,17 +158,17 @@ service itself is likewise at `supabase.<gateway.domain>`.) See
## Commands
```bash
castle program create my-app --stack supabase --description "..." # scaffold + register
castle program build my-app # apply unapplied migrations to the substrate
castle program test my-app # deno test over functions/ (if deno present)
castle apply # serve the static UI at <name>.<gateway.domain>
wildpc program create my-app --stack supabase --description "..." # scaffold + register
wildpc program build my-app # apply unapplied migrations to the substrate
wildpc program test my-app # deno test over functions/ (if deno present)
wildpc apply # serve the static UI at <name>.<gateway.domain>
```
## Scaffolding
`castle program create --stack supabase` generates the full layout above and
`wildpc program create --stack supabase` generates the full layout above and
registers the program as a static frontend. Set the anon key in `public/config.js`
(`cat ~/.castle/secrets/SUPABASE_ANON_KEY`), edit your migrations, and build.
(`cat ~/.wildpc/secrets/SUPABASE_ANON_KEY`), edit your migrations, and build.
See @docs/registry.md for the `compose` launcher, the substrate deployment definition,
and the full registry reference. The substrate itself lives in the