docs+install: sweep deploy/start → castle apply

Update the README, AGENTS.md, install.sh, and docs/ for the converge
model: one `castle apply [name] [--plan]` replaces `deploy && start` and
the per-kind enable/disable/install/start/stop verbs. CLI references now
list apply + restart (the imperative bounce) + logs; recipes use
`castle apply`; "turn it off" is documented as `enabled: false` + apply.
install.sh's next-steps collapse to a single `castle apply`.

Verified: no retired-verb command instructions remain in any markdown;
install.sh syntax OK; live `castle apply --plan` reports converged;
doctor all-green; core 129 / cli 31 / api 59 pass.
This commit is contained in:
2026-07-02 11:54:31 -07:00
parent f422c1879d
commit 9abef4ac34
10 changed files with 79 additions and 76 deletions

View File

@@ -204,7 +204,7 @@ A service's env is exactly its `defaults.env` — castle injects nothing
implicitly. Values may use `${port}`/`${data_dir}`/`${name}`/`${secret:…}`
placeholders, which deploy resolves into the registry's flat `env`.
**`$CASTLE_HOME/artifacts/specs/registry.yaml`** (per-node, not in the repo, generated by `castle deploy`) — Node config:
**`$CASTLE_HOME/artifacts/specs/registry.yaml`** (per-node, not in the repo, generated by `castle apply`) — Node config:
```yaml
node:
@@ -228,7 +228,7 @@ deployed:
```
The node config says what's deployed *here* and with what concrete
values. `castle deploy` reads the spec from the repo, resolves the
values. `castle apply` reads the spec from the repo, resolves the
`defaults.env` placeholders and secrets, resolves binary paths,
and writes the registry. Systemd units and Caddyfile are then generated
from the registry — never from the spec directly.
@@ -280,7 +280,7 @@ programs on a single node and across multiple Castle nodes.
**MQTT topics:**
- `castle/{hostname}/registry` — retained JSON, full NodeRegistry.
Published on connect and after `castle deploy`.
Published on connect and after `castle apply`.
- `castle/{hostname}/status``"online"` (retained) / `"offline"` (LWT).
LWT ensures nodes are marked offline if they disconnect unexpectedly.
@@ -457,7 +457,7 @@ $CASTLE_HOME/ ← Config & artifacts (default ~/.castle)
├── code/ ← Program source (your programs)
│ └── <name>/
├── artifacts/
│ ├── specs/ ← Generated by `castle deploy`
│ ├── specs/ ← Generated by `castle apply`
│ │ ├── Caddyfile
│ │ └── registry.yaml ← Node config (what's deployed here)
│ └── content/ ← Built frontend assets
@@ -491,7 +491,7 @@ Castle's architecture parallels Erlang/OTP, mapped onto Unix:
| Application | Component (independent, self-contained) |
| Application resource file | Component spec in `castle.yaml` |
| Release config (sys.config) | Node config in `$CASTLE_HOME/artifacts/specs/registry.yaml` |
| Release assembly | `castle deploy` (spec + node config → runtime) |
| Release assembly | `castle apply` (spec + node config → runtime) |
| Supervisor | systemd (restart policies, ordering) |
| Process | Running service/worker/job |
| Application env | Env vars |
@@ -527,12 +527,12 @@ What exists today:
- **CLI** — `castle` command, installed via `uv tool install --editable cli/`
- **Three packages** — `castle-core` (models, config, generators),
`castle-cli` (commands), `castle-api` (HTTP API)
- **Source/runtime split** — `castle.yaml` (spec) → `castle deploy`
- **Source/runtime split** — `castle.yaml` (spec) → `castle apply`
`$CASTLE_HOME/artifacts/specs/registry.yaml` (node config). Systemd units and
Caddyfile generated from registry with fully resolved paths. No repo references
in runtime artifacts.
- **Explicit env with placeholders** — a deployment's env is exactly its
`defaults.env`; `castle deploy` resolves `${port}`/`${data_dir}`/`${name}`/
`defaults.env`; `castle apply` resolves `${port}`/`${data_dir}`/`${name}`/
`${secret:…}` into concrete values. No hidden convention injection.
- **Gateway** — Caddy on port 9000, Caddyfile generated from registry
- **API** — `castle-api` on port 9020, reads from registry (optional