diff --git a/TODO.md b/TODO.md index b42bdc76..448fc3cd 100644 --- a/TODO.md +++ b/TODO.md @@ -36,6 +36,49 @@ the owner's OS user and can never be granted. Indirection there really is accide generating" was once treated as permission and started a second agent in a repository another was building in. Whatever shape this takes, it inherits those three refusals. +## Fleet — one command across every server + +**The list exists: `docs/servers.md`**, written 2026-08-21 and verified from this host. Five machines +hold a platform checkout, three run it, and it records how to reach each one. + +- [ ] **An orchestrator that acts on every server at once** — pull and update every platform, restart a + process everywhere, report which host is behind. The list is the input; this is the thing that + reads it. + + Three facts from writing the list decide the design, and all three are verified: the checkout + **path differs per host** (take it from PM2's `pm_cwd` for the `officer` process, never a + hard-coded path); `alpha` carries a **second, stale checkout** so pulling the wrong one succeeds + while changing nothing; and the **git remotes differ** — one host pulls over HTTPS and one points + at a different Gitea altogether. An orchestrator built on "ssh, cd to the same path, git pull" + is wrong on three counts before it starts. + + Open: whether this is a script over SSH, an Officer screen, or a chat capability; and whether + `headscale` and `omega` — checkout present, nothing running — are targets at all. Note the + platform already has an **Update button** for a single server (`03abdeb2`); this is that, fanned + out, and it should probably share the code rather than reimplement the pull. + +- [ ] **A way to mark a commit "this one ships", so a release is not just `master`'s tip.** Wanted + 2026-08-21. **No version numbers** — not now — and **not a tag**: the owner does not want a second + ref to mint and push for something the commit itself could carry. So a **codeword in the commit + message**, and the fleet updater pulls to the newest commit carrying it rather than to whatever + `master` points at. + + That distinction is the whole value: today a server updates to the tip, so an in-progress commit + ships the moment it is pushed. A marker makes shipping a deliberate act while leaving the push + unchanged. + + Shape to settle when it is built: + + - **A trailer, not a word in prose** — `Release: yes` on its own line, in the same family as + `Co-Authored-By`. `git log --grep='^Release:' --format=%H -1` then gives the target SHA in one + command, and no commit message that merely *talks* about a release matches by accident. + - **The trade against a tag, stated honestly:** a tag can be moved or deleted when a release turns + out to be bad; a commit message cannot be edited once pushed. Un-marking means marking a newer + commit — which is a forward-only, revert-shaped workflow. That is a fine answer, but it should + be a chosen one. + - The updater then does a checkout at that SHA, not a `pull` — same discipline the plugin-pinning + item asks for: **verify `rev-parse HEAD` matches, or refuse.** + ## File watchers - [ ] **Watch a directory, and attach actions to what lands in it.** Wanted 2026-08-21. The owner sets a diff --git a/docs/servers.md b/docs/servers.md new file mode 100644 index 00000000..31070584 --- /dev/null +++ b/docs/servers.md @@ -0,0 +1,62 @@ +# Servers — the running list + +Every machine the owner runs, how to reach it, and what of Officer is on it. Kept here so an +orchestrator ("pull and update every platform", "restart officer everywhere", "which host is behind") +has one place to read rather than a fact re-derived per session. + +**Started 2026-08-21.** Everything below was verified from `officer-dev` on that date by SSH and +`pm2 jlist`, except where marked assumed. Commit SHAs are a snapshot and go stale immediately — they +are here to show which checkout is live, not as a status board. + +## How access works + +All of it is over the tailnet. There is **no `~/.ssh/config`** — names resolve by MagicDNS and the +login is key-based, so `ssh ` as `pastilhas` is the whole story: + +```bash +ssh alpha +ssh fofos +``` + +Nothing here needs a password, a jump host or a port. A host that refuses port 22 is not +misconfigured — see "Not SSH-reachable" below. + +## Officer platforms + +| Host | Tailnet IP | Live checkout | Runs `officer` | Git remote | +| --- | --- | --- | --- | --- | +| `officer-dev` | 100.64.0.13 | `~/officer-dev/platform` | yes (this host) | `git@gitea.officer.dev:officerdev/platform.git` | +| `alpha` | 100.64.0.1 | `~/officerdev/platform` | yes | `git@gitea.officer.dev:officerdev/platform.git` | +| `fofos` | 100.64.0.17 | `~/officerdev/platform` | yes | `https://gitea.officer.dev/officerdev/platform.git` | +| `headscale` | 100.64.0.2 | `~/dockers/officerdev/platform` | no | `ssh://git@gitea.pastilhas.dev:2222/officerdev/platform.git` | +| `omega` | 100.64.0.3 | `~/projects/officerdev/platform` | no | none set | + +Three things an orchestrator has to handle, all verified and none of them cosmetic: + +- **The checkout path differs per host.** There is no single path to hard-code. Take it from PM2 — + `pm2 jlist` gives the `officer` process's `pm_cwd`, which is the checkout that is actually serving. +- **`alpha` has a SECOND, stale checkout** at `~/dockers/officer.dev/platform` (same remote, different + HEAD). Pulling the wrong one updates nothing and looks like success. PM2's `pm_cwd` is the tiebreak. +- **The remotes are not the same URL.** `fofos` pulls over HTTPS and `headscale` points at a different + Gitea entirely (`gitea.pastilhas.dev:2222`). An orchestrator that assumes SSH to `gitea.officer.dev` + breaks on two of five. + +`headscale` and `omega` hold a checkout but run no `officer` process (no PM2 on either). Whether those +are retired, staging or half-installed is **not established** — ask before treating them as targets. + +## Other machines on the tailnet + +- `gateway` (100.64.0.4) — reachable over SSH as `pastilhas`, no platform checkout, no PM2. +- **Not SSH-reachable** (port 22 refused): `edge-dns` (100.64.0.8), `edge-bridge` (100.64.0.15), + `gitea-bridge` (100.64.0.12), `officer-bridge` (100.64.0.5). Assumed to be service-only + containers rather than hosts to log into — not confirmed. +- **Client devices, not servers:** `macbookpro`, `iphone16`, `andres-ipad`, `pixel9a`, plus other + people's devices in the tailnet (`diogos-ipad`, `iphone-diogo`, `iphone-bruno`, + `guilhermes-macbook-pro`, `macbook-pro-de-joo`). + +## Keeping this list true + +It is a running list, so it is worth saying what makes it rot: a new server, a moved checkout, a +platform retired, or a remote changed. Re-verify with the same three commands the list was built from +— `tailscale status`, `pm2 jlist` for the `officer` entry's `pm_cwd`, and `git -C remote get-url +origin`.