diff --git a/deploy/2026.08.29.02.md b/deploy/2026.08.29.02.md new file mode 100644 index 00000000..8c9346d6 --- /dev/null +++ b/deploy/2026.08.29.02.md @@ -0,0 +1,119 @@ +# 2026.08.29.02 — a plugin can ship a commander + +**This one changes the database.** Two columns, both nullable additions, on a table that already exists. +There is no rename in it, nothing is dropped, and no existing row changes — but `db:push` is still not +to be trusted on its exit code, so there is a per-host query below and the report must carry its answer +for each host. + +No dependency change: `package.json` and `bun.lock` are untouched since `2026.08.29.01`. **There is no +`bun install` step in this plan** — which also sidesteps the step-order problem the last rollout found, +where the standard `plugins:update` ran before the plan's install. + +## What is in it + +- **Plugins can ship commanders.** A plugin with `commanders//COMMANDER.md` offers one; it appears + in Command HQ under a new **From plugins** section, arrives **not running**, and must be configured + before it can arm. +- **av-club ships the first one** — *Convert on arrival*: watches a folder, converts what lands in it. + It reaches each host through the standard `bun run plugins:update` step, not through this plan. +- Marketplace, file browser and Convert Image work from earlier today rides along. + +## Schema — CHANGED. `db:push` is required. + +``` +command_hq_sessions + + plugin text null which plugin's template made this commander + + plugin_config jsonb null the owner's answers to that template's inputs +``` + +Verified as the whole of it: + +```bash +git diff --name-only deploy/2026.08.29.01..deploy/2026.08.29.02 | grep -iE 'schema|/db/|databases' +# → src/databases/officer_db/src/command-hq/queries.ts +# src/databases/officer_db/src/command-hq/schema.ts +``` + +`queries.ts` is code, not schema. The only structural change is the two columns above. + +**Both are nullable with no default and no constraint**, so every existing row is valid the moment they +exist and there is nothing to backfill. This is the shape `db:push` handles cleanly — there is no +create-then-constrain here, and no `--force` is needed or permitted. + +## Every host — the commands + +After the standard steps in `prompts/deploy-commander.md` (dirty check, `git fetch origin --tags`, +`git merge --ff-only deploy/2026.08.29.02`, `bun run plugins:update`), in the checkout from PM2's +`pm_cwd`: + +### 1. Back the database up first + +```bash +pg_dump "$(grep -m1 -E '^(OFFICERDEV_)?POSTGRES_URL=' .env | cut -d= -f2-)" > ~/db-backups/officer-$(date +%Y%m%d-%H%M).sql +``` + +Read the variable name rather than assuming it: **several hosts use `OFFICERDEV_POSTGRES_URL`**, not +`POSTGRES_URL`. `mkdir -p ~/db-backups` first if it is not there. + +### 2. Push the schema + +```bash +bun db:push < /dev/null +``` + +**stdin closed**, so it can never sit waiting on a prompt in an unattended run — it fails instead, which +is the outcome you want. Expect `[✓] Changes applied` and then the two post-push scripts. + +### 3. VERIFY BY QUERY. The exit code is not the answer. + +```bash +bun -e " +const { db } = await import('officerdb/db'); const { sql } = await import('drizzle-orm'); +const r = await db.execute(sql\`select column_name from information_schema.columns + where table_name='command_hq_sessions' and column_name in ('plugin','plugin_config') order by column_name\`); +console.log([...((r as any).rows ?? r)].map((x:any)=>x.column_name).join(' ')); +process.exit(0)" +``` + +Must print exactly: + +``` +plugin plugin_config +``` + +**Put that line in the report, per host.** Not "schema ✓" — the output. A host printing one column, or +none, is a **failed host**: report it, move on, and do not attempt a repair you invented. + +### 4. Restart + +```bash +pm2 restart officer +``` + +`officer` only. `plugins:update` has already restarted the plugin sidecars itself. + +### 5. Check it came back + +`pm2 jlist`: `officer` online and `restart_time` moved, then `/api/health` on the host's own port +(9010 on `macbookpro` and `production-pertento-bridge`, 9000 elsewhere). `200` or `401` are both healthy. + +## Per host + +| Host | Note | +| --- | --- | +| `officer-dev` | **SKIP ENTIRELY.** The rollout runs here. Its schema is already pushed; nothing else is needed. Name it as skipped. | +| `alpha` | Nothing special. | +| `fofos` | The one that matters this time — `av-club` is installed there and the commander template is the point of the release. | +| `macbookpro` | macOS, port **9010**, a laptop. Unreachable is a SKIP with a note. | +| `macbruno` | macOS, login `brunoalcadapadezmonteirodaconceicao`. | +| `production-pertento-bridge` | Port **9010**. | +| `edge-pertento-bridge` | Nothing special. | +| `deadpool-rezio-bridge` | Login **`br`**, checkout `/home/br/officerdev/platform`. | + +## What "done" looks like + +Per host: HEAD before and after, whether the backup was written, `db:push` result, **the exact output of +the verification query**, and `officer` back online with a moved `restart_time`. + +The line that matters in the summary: **which hosts print `plugin plugin_config`**. That is the only +thing this release actually changes about a machine. diff --git a/package.json b/package.json index b5ddf56c..f809b015 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "officer", - "version": "2026.08.29.01", + "version": "2026.08.29.02", "private": true, "type": "module", "workspaces": [