plan for 2026.08.23.06
Carries the SQL, because bun db:push cannot apply this one and will not say so: dropping provisioning_script while adding two columns makes drizzle-kit ask whether it is a rename, and with no terminal it bails while the wrapper exits 0. Tested against a scratch database — applies, re-applies cleanly once the column is already gone, and refuses to drop a provisioning_script anything actually wrote. Also carries a one-off cleanup that no plan format covers. alpha, fofos and production-pertento-bridge each hold capabilities/affordances/officerdev/gitea/, a copy from the mechanism this release removes. The gitea plugin still ships that affordance in its own directory and affordances are deliberately not de-duplicated, so without the removal the agent reads the same guidance twice. The verification step is a chat rather than a query, because the failure mode of the capability refactor is an agent that quietly knows less rather than an error. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
# 2026.08.23.06
|
||||
|
||||
A plugin's capabilities are read where they live instead of being copied into `capabilities/`, dev tools
|
||||
become a property of a role rather than a hardcoded name, and Whisper learns 23 more languages.
|
||||
|
||||
**There IS a schema change, and `bun db:push` cannot apply it.** Read "The schema change" below before
|
||||
running anything — it will stop and ask a question no terminal is there to answer, and then exit 0.
|
||||
|
||||
**There is also a one-off cleanup on three hosts**, and skipping it means the agent reads one affordance
|
||||
twice. See "The orphan copies".
|
||||
|
||||
**No dependency change.** `bun.lock` is untouched. **Do not run `bun install`.**
|
||||
|
||||
## What is in it
|
||||
|
||||
- **A plugin's capabilities are LOADED, not copied.** Installing used to publish a plugin's affordances,
|
||||
notifications and skills into `capabilities/` — a repository meant to be forked, so a fork accumulated
|
||||
files it did not author. They are now read from each installed and enabled plugin's own directory. A
|
||||
copy also went stale on `plugins:update` and survived `plugins:disable`; neither can happen now.
|
||||
- **Notification codes moved from the path to the manifest.** They were derived from the copy's location,
|
||||
`<publisher>/<appName>/file.yaml`. Read in place there is no such path, so every plugin code would have
|
||||
vanished silently. The identity comes from the manifest instead, which is validated at discovery.
|
||||
- **Roles phase 3.** `rolePermitsDevTools()` was `role === 'Developer'` — one line gating a Postgres login
|
||||
role with CREATEDB and a rootless Docker daemon. Two boolean columns carry it now, so a role created at
|
||||
runtime can hold dev tools. `provisioning_script` is dropped rather than left dead.
|
||||
- **Whisper priming prompts for 23 more languages**, Swedish included. The table had `en` and `pt`; every
|
||||
other language got no prompt, which is why non-English transcription had nothing steering its
|
||||
punctuation or diacritics. Inert on every host until an STT server is configured, which none is.
|
||||
- **The mailbox picker** in the email plugin, reaching the multi-account backend that shipped without a UI.
|
||||
|
||||
## The schema change
|
||||
|
||||
Two columns added to `roles`, one dropped.
|
||||
|
||||
**`bun db:push` will not do this.** Dropping a column while adding another makes drizzle-kit ask whether
|
||||
it is a rename:
|
||||
|
||||
```
|
||||
Is grants_postgres column in roles table created or renamed from another column?
|
||||
```
|
||||
|
||||
With no terminal it bails, the wrapper still exits 0, and the `postdb:push` seed then fails against an
|
||||
unchanged schema — reporting a missing column several steps from the thing that actually stopped. Verified
|
||||
on `officer-dev` on 2026-08-23. See `src/databases/CLAUDE.md`.
|
||||
|
||||
Run this **first**. It is idempotent and safe to run twice.
|
||||
|
||||
```sql
|
||||
-- Nothing ever wrote this column. Prove it rather than assume, before dropping it.
|
||||
DO $$
|
||||
DECLARE used int;
|
||||
BEGIN
|
||||
SELECT count(*) INTO used FROM roles WHERE provisioning_script IS NOT NULL;
|
||||
IF used > 0 THEN
|
||||
RAISE EXCEPTION 'STOP: % role(s) have a provisioning_script. Do not continue; report this.', used;
|
||||
END IF;
|
||||
EXCEPTION WHEN undefined_column THEN
|
||||
NULL; -- already dropped by a previous run
|
||||
END $$;
|
||||
|
||||
ALTER TABLE roles ADD COLUMN IF NOT EXISTS grants_postgres boolean NOT NULL DEFAULT false;
|
||||
ALTER TABLE roles ADD COLUMN IF NOT EXISTS grants_docker boolean NOT NULL DEFAULT false;
|
||||
ALTER TABLE roles DROP COLUMN IF EXISTS provisioning_script;
|
||||
```
|
||||
|
||||
Then verify **by query**:
|
||||
|
||||
```sql
|
||||
SELECT name, is_system, grants_postgres, grants_docker FROM roles ORDER BY name;
|
||||
```
|
||||
|
||||
Four rows. **`Developer` must have both flags true and the other three both false** — that is exactly the
|
||||
behaviour `rolePermitsDevTools` had, preserved. If Developer comes back false, the seed did not run: fix
|
||||
it before restarting, or Developer accounts silently lose their Postgres role and Docker daemon on their
|
||||
next provisioning.
|
||||
|
||||
`provisioning_script` must be absent from the column list.
|
||||
|
||||
## The orphan copies
|
||||
|
||||
**`alpha`, `fofos` and `production-pertento-bridge` each have `capabilities/affordances/officerdev/gitea/`
|
||||
— a copy published by the old mechanism.** The gitea plugin still ships that affordance in its own
|
||||
directory, and affordances are deliberately NOT de-duplicated, so after this release both load and the
|
||||
agent reads the same guidance twice.
|
||||
|
||||
Remove the copy on those three hosts. `deadpool-rezio-bridge` does not have one; check anyway.
|
||||
|
||||
```bash
|
||||
cd "$(dirname "$OFFICER_PLATFORM_DIR")/capabilities" # or the capabilities dir beside the checkout
|
||||
git status --porcelain # expect only ?? extensions/ afterwards
|
||||
rm -rf affordances/officerdev
|
||||
```
|
||||
|
||||
Safe because it is a copy: the source is `plugins/gitea/affordances/` and that is what now gets read.
|
||||
|
||||
**`extensions/` stays.** It is written by the platform's own bootstrap every boot, not published by a
|
||||
plugin. This release gitignores it, and the ignore arrives with the capabilities pull in step 4.
|
||||
|
||||
## Every host
|
||||
|
||||
1. `git fetch origin --tags` then `git merge --ff-only deploy/2026.08.23.06`
|
||||
2. **The SQL above**, then the verification query. Stop on the `RAISE EXCEPTION` and report it.
|
||||
3. `bun db:push` — expect **no changes and no prompt**. If it asks anything, the SQL did not take.
|
||||
4. `bun run plugins:update` — this pulls the capabilities repository too, which is how the new
|
||||
`.gitignore` arrives.
|
||||
5. **The orphan removal above**, on the three hosts that have one.
|
||||
6. `pm2 restart officer`
|
||||
|
||||
`officer` only at step 6. Step 4 restarts each plugin's own sidecar, which belongs in the report.
|
||||
|
||||
**`macbookpro`:** append `/opt/homebrew/bin` to PATH for the `bun` commands, run `pm2` separately. It now
|
||||
has `psql` at `/opt/homebrew/opt/libpq/bin/psql` and a `.zshenv` that puts it on a non-interactive PATH,
|
||||
so the SQL above can be run there directly rather than through Bun.
|
||||
|
||||
## What to check, this release
|
||||
|
||||
**Open a chat and confirm the agent still has its skills.** The preamble is built from a new code path —
|
||||
`capability-sources.ts` resolving roots per session — and the failure mode is an agent that quietly knows
|
||||
less rather than an error. Ask it what skills it has; it should name the commander, deploy and platform
|
||||
ones, plus anything a plugin ships on that host.
|
||||
|
||||
On a host with the gitea plugin, confirm the gitea affordance appears **once**.
|
||||
|
||||
No direct SQL beyond the block above is needed, and none is authorised.
|
||||
|
||||
## Hosts
|
||||
|
||||
- **`edge-pertento-bridge`** — skipped. Down, per `docs/servers.md`.
|
||||
- **`officer-dev`** — skip it. The schema is already applied there and verified by query, its capabilities
|
||||
repository is already clean, and restarting `officer` on the host running the rollout ends the rollout.
|
||||
Name it as skipped and say it is current.
|
||||
Reference in New Issue
Block a user