Swedish, plugin capabilities read where they live, dev tools as a property of a role, a commander as a directory, and atomic uploads. TWO schema changes and bun db:push can apply neither. Both drop a column while adding others, which is the shape drizzle-kit cannot tell from a rename — it asks, bails with no terminal to answer, and the wrapper still exits 0. The plan carries both blocks, guarded and idempotent, tested against a scratch database: they apply, re-apply cleanly once already applied, and the roles guard still refuses a host where anything wrote a provisioning_script. The command_hq block DELETES every commander rather than migrating one. That is the owner's call and the plan says to tell people what was removed and put it in the report — a commander is somebody's standing job, not a row. Also carries a cleanup no plan format covers: three hosts hold a copy of gitea's affordance published by the mechanism this release removes, and affordances are deliberately not de-duplicated, so without the removal the agent reads the same guidance twice. The verification step is a conversation rather than a query. The capability refactor's failure mode is an agent that quietly knows less, which no schema check can see. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
deploy/
One file per release, and one report per release.
deploy/
├── 2026.08.21.01.md the plan — what to run, in order, on which hosts
└── 2026.08.21.01.report.md what actually happened, written by the commander
The plan is written by hand before the release commit. The report is written by the deploy commander afterwards and pushed back here.
A release is a tag, deploy/<version>, and nothing else triggers a deploy — not a commit message,
not a branch. A tag cannot be written into prose by accident, which a code word can and which every
document about deploying does.
What marks a release deployed is LOCAL: $OFFICER_ROOT/data/deploys/<version>.done. Not the report.
If the lock were the pushed report, a failed push would mean the release looked undeployed and the next
tick would roll it out again — and pushes here fail for unrelated reasons. So the report is an artefact,
valuable and not load-bearing.
See prompts/deploy-commander.md.