# 2026.09.09.01 — ten days of platform work, and one new table **Twenty-seven commits**, `deploy/2026.08.30.03..fafc1adb`. The fleet is ten days behind; this is a catch-up release rather than a fix for anything found in the last one. The larger threads in it, so a host that misbehaves has somewhere to point: - **Plugin ports** — the platform can allocate a plugin a stable port and remember it (`518d329c`, `d9110c37`). This is the schema change; see below. - **Publishing is a tag** — the marketplace reads releases, not working trees (`78e89ebc`, `19bbbab9`). - **Plugin routing** — a plugin owns the routing under its mount and can declare its own routes (`89820972`, `1fe767ea`), with `:section` given back to the fifteen plugins the splat took it from (`eaa92738`). - **The code editor's tree and file browser** are exported for plugins to reuse (`fb530456`, `5fa3f3ec`, `da07048f`). - **`anthropicViaProxy`** (`fafc1adb`) — the boundary through which platform-side code, including a plugin's server routes, reaches Claude on the owner's own subscription. ## The schema change — one new table, one nullable column Verified rather than assumed: ```bash git diff --name-only deploy/2026.08.30.03..master | grep -iE 'schema|databases/' ``` Two files, and they are **not** equally in scope: 1. **`officer_db` — `plugin_ports`, a brand-new table.** No foreign key onto it and no existing column pointing at it, so this is not the create-then-constrain shape that `db:push` cannot do. A plain `bun db:push` is enough, and it is a create on every host. 2. **`marketplace_db` — `plugins.release_tag`, a nullable text column.** **Out of scope for this rollout.** `bun db:push` covers `officer_db` only, and the marketplace runs on exactly one machine: ``` officer-marketplace → officer-dev only (verified 2026-09-09, pm2 jlist on all six) ``` `officer-dev` is the host the rollout skips. So no target needs it, and nothing should improvise a second push to reach it. It is named here so that when `officer-dev` is restarted deliberately, the marketplace database is known to be the one outstanding piece. ## Dependency change — `bun install` is required ```bash git diff --name-only deploy/2026.08.30.03..master -- package.json bun.lock # both changed ``` `@anthropic-ai/sdk@^0.71.0` was added (plus its `json-schema-to-ts` dependency). The lockfile is committed and matches, so the frozen-lockfile default resolves from it — **plain `bun install`, never `--no-frozen-lockfile`.** A host that cannot resolve from the lockfile is a finding, not something to force past. ## Every host — the commands The standard steps in `prompts/deploy-commander.md` are the rollout (dirty check — TRACKED only, `git fetch origin --tags`, `git merge --ff-only deploy/2026.09.09.01`, `bun run plugins:update`), plus, in this order: ```bash bun install bun db:push < /dev/null pm2 restart officer ``` `bun install` **before** `plugins:update`, because the plugin installer runs against the platform's own resolved modules. `db:push` after both, because `gen-plugin-schemas` runs inside it and reads the plugins as they now are. `< /dev/null` on the push is not decoration: stdin closed means a push that wants to ask a question fails instead of hanging forever in an unattended run. This change should ask nothing — a create of a table nothing else references — so **a prompt here is a finding.** `pm2 restart officer` only. `plugins:update` has already restarted the plugin sidecars itself. ### Verify it came back — three checks, per host, by query Exit 0 from `db:push` is not evidence; `drizzle-kit push` can fail and still exit 0. 1. **The table exists**, asked of that host's own database: ```bash psql "$DB_URL" -tAc "select to_regclass('public.plugin_ports')" # → plugin_ports ``` Read the URL from that checkout's `.env` — several hosts use `OFFICERDEV_POSTGRES_URL`, not `POSTGRES_URL`. 2. **`pm2 jlist`** — `officer` is `online` and its `restart_time` moved. 3. **HTTP** — `/api/health` on the host's own port. `200` or `401` are both healthy. The port is in `.env` and is **9010 on `macbookpro`**, 9000 elsewhere. ## Per host | Host | Login | State before | Note | | ----------------------- | -------------- | ------------------------------ | --------------------------------------------------------- | | `alpha` | `pastilhas` | `19bbbab9`, 8 commits past the tag | Partially pulled at some point; the fast-forward is shorter than the others'. | | `fofos` | `pastilhas` | `fafc1adb` — already at master | Already carries every commit; the merge is a no-op that only moves the tag onto it. Still runs install/push/restart. One untracked file — a note, not a skip. | | `macbookpro` | `pastilhas` | `c97da029` (`2026.08.30.03`) | Laptop. Asleep is a SKIP with a note. `export PATH=$PATH:/opt/homebrew/bin` for `bun`, and run `pm2` as a separate command. Port **9010**. | | `deadpool-rezio-bridge` | **`br`** | `c97da029` (`2026.08.30.03`) | Not `pastilhas`. | ### Skipped, deliberately — not failures - **`officer-dev`** — the host the rollout runs on. Skipping it entirely is the rule; restarting `officer` there ends the rollout mid-report. It is at `fafc1adb` and therefore **not behind** in code; what it does still want is the marketplace column above, whenever the owner restarts it. - **`macbruno`** — unreachable at cut time (`connect to host macbruno port 22: Connection timed out`, verified 2026-09-09). A Mac, so most likely asleep. - **Both Pertento hosts** — on the deliberately-skipped list in `docs/servers.md` since 2026-09-08. Owner's call, no fault on either box. ## What "done" looks like Four hosts attempted: `alpha`, `fofos`, `macbookpro`, `deadpool-rezio-bridge`. Each at `deploy/2026.09.09.01`, `plugin_ports` present by query, `officer` back online, health answering on the right port. A host that fails does not stop the rollout. It gets its own line saying which step failed and what never ran. ## Known and carried, not introduced here `bunx tsgo` reports one pre-existing type error in `src/servers/sidecar/claude/claude-manager.ts:667` (`SdkUserMessage` vs `SDKUserMessage`, from the agent SDK's own types). It is present on `master` before this release's commits, it is type-only, and Bun strips types at run time — so it does not affect the rollout. Named here so it is not discovered mid-deploy and mistaken for something this release did.