Roles become a table and localization phase 0 lands. Both groundwork; nothing in the UI changes and nothing reads the new table yet. Schema change, additive only — the roles table is new and no constraint is added to an existing column, so it cannot fail on existing data. postdb:push seeds it. No dependency change; the two lockfile lines are the local i18n workspace being declared as a dependency of officerdev. The plan names the check that matters: four rows in roles, per host, by query — db:push can fail and exit 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
3.2 KiB
2026.08.23.03
Roles become a table, and the localization infrastructure lands. Both are groundwork — nothing in the UI changes and nothing reads the new table yet.
SCHEMA CHANGE. bun db:push is a step, and postdb:push now seeds the new table automatically. The
roles table is new. Additive only: no constraint is added to an existing column, so this cannot fail on
existing data.
No dependency change. bun.lock gained two lines and they are the local i18n workspace package being
declared as a dependency of officerdev — a workspace path, not a registry fetch. Do not run
bun install.
What is in it
rolesis a table, seeded with the four the platform already had, each markedisSystembecause the code names it:rolePermitsDevTools()tests forDeveloper, bootstrap writesSuper Admin,users.roledefaults toMember. Nothing reads the table yet —USER_ROLESis still the type andauthorize.tsis untouched. There is deliberately no foreign key onusers.role; that change cannot go throughdb:pushand is a later release.- The seed runs from
postdb:push, so a host gets the four rows on its next schema push with no extra step here. It never overwrites an existing row. - Localization phase 0 — plural selection through
Intl.PluralRules, auseFormat()hook for dates and numbers, three namespaced catalogs deep-merged at the bridge,diron<html>, and key-parity tests that fail the build on a missing key. The language picker now offers only the two catalogs that exist rather than twenty codes, eighteen of which silently rendered English. Stored bare codes widen on read (en→en-GB), with no database migration. - SendOff's folder name is served rather than derived —
/sendoff/targetscarriesdisplayNameandmyFolderfrom the same helper the writer uses, so a picker cannot name a folder the writer will not create.
Every host
git fetch origin --tagsthengit merge --ff-only deploy/2026.08.23.03bun db:push— and per the procedure, verify by query, not by exit code. Check thatrolesexists and holds four rows on that host.db:pushcan fail and still exit 0.bun run plugins:updatepm2 restart officer
officer only. Step 3 restarts each plugin's own sidecar; that is the script's behaviour and belongs in
the report.
macbookpro: append /opt/homebrew/bin to PATH for the bun commands, run pm2 separately.
The check that matters this release
select count(*) from roles; -- expect 4
Four rows named Super Admin, Admin, Developer, Member. If a host shows the table but zero rows, the
postdb:push hook did not run — report it as a failure for that host rather than as a success, and say so
per host in the report.
No direct SQL is needed and none is authorised for this release.
Hosts to expect trouble from
edge-pertento-bridge— skipped, perdocs/servers.md. Name it and spend nothing on it.production-pertento-bridge— came back last release after two behind. Nothing special expected.
officer-dev — skip it
The rollout runs from here. It already holds the release and the four rows, verified locally.