deploy 2026.08.23.05: five hosts, schema verified by query on each
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
# 2026.08.23.05 — deploy report
|
||||
|
||||
**5 of 5 target hosts succeeded.** Two hosts skipped by design: `officer-dev` (the host running the
|
||||
rollout) and `edge-pertento-bridge` (in the *Deliberately skipped* section of `docs/servers.md`).
|
||||
|
||||
Every target ended at `e15ab2303a17ed0e1d1cf59b35f34aec68875907` = `deploy/2026.08.23.05`, merged
|
||||
`--ff-only` onto the tag itself. No host was left on the branch, and no host is a commit past the tag.
|
||||
|
||||
Schema evidence is per host, by query, below. `--force` was never used and was never needed.
|
||||
|
||||
---
|
||||
|
||||
## Per host
|
||||
|
||||
### `alpha` — succeeded
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| Checkout (from PM2 `pm_cwd`) | `/home/pastilhas/officerdev/platform` |
|
||||
| HEAD before | `ff647fba` (`deploy/2026.08.23.04`) |
|
||||
| HEAD after | `e15ab230` (`deploy/2026.08.23.05`) |
|
||||
| Tracked changes before | none |
|
||||
| Untracked files | none |
|
||||
|
||||
Pre-check: `roles = 4`, orphan users `0`, orphan grants `0`.
|
||||
|
||||
SQL applied, exit 0. Verification query:
|
||||
|
||||
```
|
||||
conname | pg_get_constraintdef
|
||||
-------------------------------+-------------------------------------------------------------
|
||||
ck_role_permissions_not_owner | CHECK ((role <> 'Super Admin'::text))
|
||||
fk_role_permissions_role | FOREIGN KEY (role) REFERENCES roles(name) ON UPDATE CASCADE
|
||||
fk_users_role | FOREIGN KEY (role) REFERENCES roles(name) ON UPDATE CASCADE
|
||||
```
|
||||
|
||||
Both `fk_` present, `ON UPDATE CASCADE`, no `ON DELETE`. `ck_role_permissions_role` absent.
|
||||
`ck_role_permissions_not_owner` present. Re-queried after `db:push` — unchanged.
|
||||
|
||||
`bun db:push` ran clean. **It is not a no-op on this host** — see "The one thing that is not clean" below.
|
||||
|
||||
`bun run plugins:update`: `12/12 updated in 47s`, exit 0. That step restarted twelve plugin sidecars —
|
||||
atelier, bitcoin-wallet, email, gitea, invoices, jellyfin, music, offscale, photos, soulseek,
|
||||
transmission, vault.
|
||||
|
||||
`pm2 restart officer`: restart_time 70 → 71, `online`. All 19 `officer*` processes `online` afterwards.
|
||||
|
||||
### `fofos` — succeeded
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| Checkout | `/home/pastilhas/officerdev/platform` |
|
||||
| HEAD before | `ff647fba` (`deploy/2026.08.23.04`) |
|
||||
| HEAD after | `e15ab230` (`deploy/2026.08.23.05`) |
|
||||
| Tracked changes before | none |
|
||||
| Untracked files | `scripts/chk.ts` — left alone, not a reason to skip |
|
||||
|
||||
Pre-check: `roles = 4`, orphans `0` / `0`. SQL applied, exit 0. Verification query returned the same
|
||||
three rows as `alpha`: both `fk_` present with `ON UPDATE CASCADE`, `ck_role_permissions_role` absent,
|
||||
`ck_role_permissions_not_owner` present.
|
||||
|
||||
`bun db:push` clean; a second `push --verbose` said **`No changes detected`** — a genuine no-op.
|
||||
|
||||
`bun run plugins:update`: `1/1 updated in 7s`, exit 0. Restarted `officer-gitea`.
|
||||
|
||||
`pm2 restart officer`: 24 → 25, `online`. All 8 processes `online`.
|
||||
|
||||
### `production-pertento-bridge` — succeeded
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| Checkout | `/home/pastilhas/officerdev/platform` |
|
||||
| HEAD before | `ff647fba` (`deploy/2026.08.23.04`) |
|
||||
| HEAD after | `e15ab230` (`deploy/2026.08.23.05`) |
|
||||
| Tracked changes before | none |
|
||||
| Untracked files | none |
|
||||
|
||||
Pre-check: `roles = 4`, orphans `0` / `0`. SQL applied, exit 0. Verification query: same three rows,
|
||||
same verdict.
|
||||
|
||||
`bun db:push` clean; second `push --verbose` → **`No changes detected`**.
|
||||
|
||||
`bun run plugins:update`: `1/1 updated in 5s`, exit 0. Restarted `officer-gitea`.
|
||||
|
||||
`pm2 restart officer`: 3 → 4, `online`. All 15 processes `online` (this host also runs eight non-Officer
|
||||
PM2 entries — Crons/Dashboard/Tracking/Uptime — untouched and still `online`).
|
||||
|
||||
Cosmetic, pre-existing, not caused by this release: every `$SHELL -ic` command on this host prints an
|
||||
nvm warning about a `globalconfig`/`prefix` in `~/.npmrc`. Nothing failed because of it.
|
||||
|
||||
### `deadpool-rezio-bridge` — succeeded
|
||||
|
||||
Login `br`, per `docs/servers.md`.
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| Checkout | `/home/br/officerdev/platform` |
|
||||
| HEAD before | `ff647fba` (`deploy/2026.08.23.04`) |
|
||||
| HEAD after | `e15ab230` (`deploy/2026.08.23.05`) |
|
||||
| Tracked changes before | none |
|
||||
| Untracked files | none |
|
||||
|
||||
Pre-check: `roles = 4`, orphans `0` / `0`. SQL applied, exit 0. Verification query: same three rows,
|
||||
same verdict.
|
||||
|
||||
`bun db:push` clean; second `push --verbose` → **`No changes detected`**.
|
||||
|
||||
`bun run plugins:update`: `2/2 updated in 7s`, exit 0. Restarted `officer-email` and `officer-offscale`.
|
||||
|
||||
`pm2 restart officer`: 9 → 10, `online`. All 9 processes `online`.
|
||||
|
||||
### `macbookpro` — succeeded, and the host the plan flagged is now verified
|
||||
|
||||
Awake and reachable. macOS, so the PATH and `psql` notes in `docs/servers.md` all applied.
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| Checkout | `/Users/pastilhas/projects/officer-suite/platform` |
|
||||
| HEAD before | `6e092c32` (`deploy/2026.08.23.04-48-g6e092c32`) |
|
||||
| HEAD after | `e15ab230` (`deploy/2026.08.23.05`) |
|
||||
| Tracked changes before | none |
|
||||
| Untracked files | none |
|
||||
|
||||
It started 48 commits *past* the previous tag rather than on it — the tag was still an ancestor, so the
|
||||
fast-forward was legitimate and no reset was needed.
|
||||
|
||||
**The roles table the plan could not verify before the tag is now verified:** `roles = 4`, orphan users
|
||||
`0`, orphan grants `0`. The plan was right that there is no `psql` here — there is also no Homebrew
|
||||
postgres and no postgres container. The query went through **Bun's own `SQL` client** (`bun 1.3.14`)
|
||||
against the same `OFFICERDEV_POSTGRES_URL` the platform's `drizzle.config.ts` reads, so it is that host's
|
||||
own database and not an inference from another one.
|
||||
|
||||
SQL applied through the same client, no exception raised. Verification query:
|
||||
|
||||
```json
|
||||
[
|
||||
{ "conname": "ck_role_permissions_not_owner",
|
||||
"pg_get_constraintdef": "CHECK ((role <> 'Super Admin'::text))" },
|
||||
{ "conname": "fk_role_permissions_role",
|
||||
"pg_get_constraintdef": "FOREIGN KEY (role) REFERENCES roles(name) ON UPDATE CASCADE" },
|
||||
{ "conname": "fk_users_role",
|
||||
"pg_get_constraintdef": "FOREIGN KEY (role) REFERENCES roles(name) ON UPDATE CASCADE" }
|
||||
]
|
||||
```
|
||||
|
||||
Both `fk_` present with `ON UPDATE CASCADE` and no `ON DELETE`; `ck_role_permissions_role` absent;
|
||||
`ck_role_permissions_not_owner` present. Same verdict as the other four.
|
||||
|
||||
`bun db:push` ran clean. It is not a no-op here either — see below.
|
||||
|
||||
`bun run plugins:update`: exit 0, and its whole output was **`no plugins installed — nothing to update`**.
|
||||
No sidecar restarted. That is worth a second look and is covered below.
|
||||
|
||||
`pm2 restart officer`: 11 → 12, `online`. All 6 processes `online`.
|
||||
|
||||
---
|
||||
|
||||
## The one thing that is not clean
|
||||
|
||||
The plan says `bun db:push` should be a no-op after the SQL, and that anything it still wants to alter
|
||||
means the SQL was incomplete. On two hosts it still wants to alter something. **It is not the release's
|
||||
schema change, and the SQL was not incomplete** — the verification query above proves the constraints
|
||||
this release introduced are exactly right on all five hosts, and re-querying after `push` on `alpha`
|
||||
showed them unchanged.
|
||||
|
||||
What `push --verbose` still wants, after the SQL:
|
||||
|
||||
- **`alpha`** — drops and immediately re-adds `pk_music_now_playing` on `music_now_playing`, with an
|
||||
identical definition.
|
||||
- **`macbookpro`** — the same `music_now_playing` churn, plus two `atelier_collection_items` foreign
|
||||
keys dropped and re-added under names one character longer (`…_id_f` → `…_id_fk`).
|
||||
|
||||
Both are plugin tables, both are the documented drizzle-kit mis-diff on named composite constraints and
|
||||
on foreign keys whose generated name Postgres truncates at 63 characters. The `atelier` case is
|
||||
precisely the churn this release's notes claim to end "across the fleet's plugins" — and on `alpha`,
|
||||
where the plugins *did* update, the atelier churn is indeed gone and only the `music` one remains. On
|
||||
`macbookpro` the plugins did not update at all, so it still carries both.
|
||||
|
||||
`fofos`, `production-pertento-bridge` and `deadpool-rezio-bridge` all reported `No changes detected` —
|
||||
a true no-op, which is the outcome the plan expected.
|
||||
|
||||
I judged this not to be a stop condition and continued. The reasoning, so it can be overruled: the plan's
|
||||
"stop and report" is aimed at the roles/FK change being half-applied, that change is provably whole on
|
||||
every host, and the residue is a pre-existing self-cancelling churn on plugin tables that this release
|
||||
does not touch. If that call was wrong, the thing to re-examine is `music_now_playing`'s composite
|
||||
primary key — it is the one still churning on the host where plugins are current.
|
||||
|
||||
---
|
||||
|
||||
## What I did not do, and could not verify
|
||||
|
||||
- **`officer-dev` — skipped entirely.** Not pulled, nothing restarted. It is at `6cd99ddb`, one commit
|
||||
*past* the tag; that commit landed on `master` after the tag was cut and is a docs commit. Its schema
|
||||
change was already applied and verified before this rollout, per the plan. It is the only host not at
|
||||
the tag exactly, and restarting it is the owner's deliberate last step.
|
||||
- **`edge-pertento-bridge` — skipped, not a failure.** Listed in *Deliberately skipped* since
|
||||
2026-08-23. Nothing was spent on it: no SSH attempt, no retry.
|
||||
- **The five-language picker was NOT checked in a browser.** The plan's "what to check" asks for the
|
||||
profile settings picker to offer five languages and for a *panel* to be inspected in a non-English
|
||||
locale. That is a UI check and I did not perform it. What I can say is narrower: every host serves the
|
||||
tag's bundle and every host restarted `officer` afterwards, so the fix is present in the code each
|
||||
host is running. Whether it renders is unconfirmed.
|
||||
- **Minesweeper's absence was not checked.** `/minesweeper` was not requested on any host, and the dock
|
||||
was not inspected.
|
||||
- **`macbookpro` reports no plugins installed** while `gen-plugin-schemas` finds three schema files on
|
||||
disk (`atelier`, `kiosk`, `music`). So that host has plugin *schemas* without registered plugins. This
|
||||
predates the release and nothing in the plan covers it, so I left it alone — but it explains why the
|
||||
atelier constraint churn cleared on `alpha` and not here, and it means `macbookpro`'s plugins are not
|
||||
being updated by the deploy at all.
|
||||
- **`plugins:update` restarted sidecars on four hosts before the plan's own restart step**, as
|
||||
`docs/servers.md` warns. Counted per host above rather than left as "restarted: officer".
|
||||
|
||||
## One note for `docs/servers.md`
|
||||
|
||||
The database URL key is **not the same on every host.** `alpha` has only `POSTGRES_URL`; `fofos`,
|
||||
`production-pertento-bridge`, `deadpool-rezio-bridge` and `macbookpro` have only
|
||||
`OFFICERDEV_POSTGRES_URL`. `drizzle.config.ts` reads `OFFICERDEV_POSTGRES_URL ?? POSTGRES_URL`, so both
|
||||
work for the app — but a rollout that queries the database directly must follow the same precedence or
|
||||
it verifies the wrong database and says "schema ✓" about it. This cost one failed step on `fofos` before
|
||||
being caught, and I re-checked `alpha` afterwards to confirm it holds only the one key and that its
|
||||
verification was therefore sound.
|
||||
|
||||
`macbookpro` also has no `timeout(1)`. A remote command wrapping anything in `timeout` fails there with
|
||||
`command not found` — and it fails *silently* in the sense that what you see is the next command's error,
|
||||
not the missing binary's.
|
||||
Reference in New Issue
Block a user