diff --git a/PLAN.md b/PLAN.md index 0170ed8..668fdd6 100644 --- a/PLAN.md +++ b/PLAN.md @@ -44,7 +44,7 @@ Decisions already made (2026-08-24): ## Architecture -### Setups and providers (decided 2026-08-28, superseding the below) +### Setups and providers (decided and built 2026-08-28, superseding the below) **A setup is a machine, and it carries the providers that machine has.** Optional ssh details, plus the list of what can be run there. Spawning is @@ -60,17 +60,23 @@ takes no host, so "Run on" is a control that silently does nothing for it). Grouping providers under the machine they exist on makes the picker show only what is true. -Open, and worth settling before this is built: +Settled while building it: -- **Where the built-in echo provider lives.** It needs no configuration - and is the connectivity check that costs no tokens, so probably a - provider of an implicit local setup rather than something configured. -- **Migration.** Sessions store the provider and host names they were - spawned with; they would store a setup and a provider instead. -- **Setups are edited from the phone**, not by hand in `config.ron` — the - standing preference for this app. Key material is the exception that - cannot travel, so a setup names an identity file that must already exist - on the backend machine. +- **Echo is seeded, not implicit.** It lives in the setup with no ssh, + because it runs in-process and has no transport to cross. It is written + into `config.ron` on first run rather than conjured at read time — a + provider nobody can see in the file is one nobody can edit from the + phone, which is the opposite of what this app is for. +- **No migration; a config in the old shape is refused** with instructions. + Unknown fields default away, so `providers:`/`hosts:` would have loaded + as an empty config and then been seeded over, losing everything + silently. +- **Still to do: editing setups from the phone.** `GET /setups` exists; + writing them is not built, so a new machine is still a hand edit on the + backend. That is the remaining gap against the standing preference that + configuration be reachable from the app. Key material is the honest + exception — a setup names an identity file that must already exist on + the backend machine, because a private key must not travel. The superseded model, for the reasoning it recorded: