docs: working-on-officer catches up to the code
It described four capability kinds and said terminal, chat and files can never be granted. There are five, and those three moved to `confined` on 2026-08-11 — the kernel enforces the boundary because the account has its own Linux user, and a grant means nothing without one. The layout diagram was missing dockers/ and secrets/, and implied the paths are configured. They are derived from the working directory, which is why the pm2 cwd pin and assertInstallLayout exist. Adds what is switched off as of tonight: six core processes, every plugin router commented out beside its capability claim, the ecosystem files now generated, and .env down to three values with the keys in the secret store. First of a documentation sweep. 42 docs; this one first because it is the operational guide somebody actually reaches for. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,27 +7,53 @@ agent sessions start.
|
|||||||
Three directories sit there, and knowing which one a change belongs in is most of the job:
|
Three directories sit there, and knowing which one a change belongs in is most of the job:
|
||||||
|
|
||||||
```
|
```
|
||||||
officer/
|
$OFFICER_ROOT/
|
||||||
├── platform/ the application — a git repo
|
├── platform/ the application — a git repo
|
||||||
├── capabilities/ what the agent can do — a separate git repo
|
├── capabilities/ what the agent can do — a separate git repo
|
||||||
└── data/ runtime state — NOT version controlled
|
├── data/ runtime state — NOT version controlled
|
||||||
|
├── dockers/ containers the app store provisioned
|
||||||
|
└── secrets/ the key store — 0600, and NOT in your data backup
|
||||||
```
|
```
|
||||||
|
|
||||||
|
None of those paths is configured. `src/servers/data-path.ts` derives the root as
|
||||||
|
`resolve(process.cwd(), '..')` and hangs the rest off it, which is why the pm2 `cwd` pin matters and
|
||||||
|
why `assertInstallLayout` refuses to boot from the wrong directory.
|
||||||
|
|
||||||
Officer is a self-hosted platform: an AI agent, a terminal, a file browser, a code editor, email, a
|
Officer is a self-hosted platform: an AI agent, a terminal, a file browser, a code editor, email, a
|
||||||
bitcoin wallet, a remote desktop and dashboards, behind one web app. **It is built around one owner**
|
bitcoin wallet, a remote desktop and dashboards, behind one web app. **It is built around one owner**
|
||||||
— user id 1, role `Super Admin`, who bypasses every permission check — and since 2026-08-07 also
|
— user id 1, role `Super Admin`, who bypasses every permission check — and since 2026-08-07 also
|
||||||
admits **additional accounts holding a strict subset of it**, governed by per-role capability grants.
|
admits **additional accounts holding a strict subset of it**, governed by per-role capability grants.
|
||||||
|
|
||||||
So "which user" has two answers depending on the surface. For the **app** capabilities (gitea, music,
|
So "which user" has three answers depending on the surface. For the **app** capabilities (gitea,
|
||||||
photos, email, calendar…) it is a real question with a real answer. For anything that executes code or
|
music, photos, email, calendar…) it is a real question with a real answer. For **confined** ones —
|
||||||
touches the disk — terminal, chat, tasks, files, desktop, browser — it is still always the owner:
|
terminal, chat, files — it is also real, because the account has its own Linux user and the kernel
|
||||||
those are `kind: 'execution'` in `platform/src/servers/capabilities/registry.ts` and can never be
|
enforces the boundary; a grant there means nothing without that user, and `authorize.ts` drops it.
|
||||||
granted, because they run as the owner's OS user in the owner's home.
|
For **execution** — tasks, items, desktop, browser — it is still always the owner, and those can
|
||||||
|
never be granted at any level.
|
||||||
|
|
||||||
|
That is five kinds, not four: `core`, `app`, `confined`, `execution`, `admin`. Terminal, chat and
|
||||||
|
files moved from `execution` to `confined` on 2026-08-11 with per-user Linux accounts.
|
||||||
|
|
||||||
This paragraph said "there is no tenancy, no roles, no other users" until 2026-08-07. Four roles exist
|
This paragraph said "there is no tenancy, no roles, no other users" until 2026-08-07. Four roles exist
|
||||||
and five non-owner accounts are live; treat the capability registry as the source of truth over any
|
and five non-owner accounts are live; treat the capability registry as the source of truth over any
|
||||||
prose, here or elsewhere.
|
prose, here or elsewhere.
|
||||||
|
|
||||||
|
## What is switched off (2026-08-13)
|
||||||
|
|
||||||
|
A core install runs **six** pm2 processes: `officer`, `officer-anthropic-proxy`,
|
||||||
|
`officer-claude-code`, `officer-opencode`, `officer-pty`, `officer-headscale`. Everything else is a
|
||||||
|
plugin, and every plugin router is commented out in `hono.ts` with its capability's `api` claim
|
||||||
|
commented beside it — they must move together or `assertCapabilityTotality` refuses to boot.
|
||||||
|
|
||||||
|
The implementations are all still on disk. Nothing was deleted; the mounts were switched off pending
|
||||||
|
extraction into the plugin system.
|
||||||
|
|
||||||
|
Also gone: the four ecosystem files (generated now, at setup, and gitignored), origin validation,
|
||||||
|
`OFFICER_OS_USERS` (per-user Linux accounts are unconditional), and the Task Logs feature.
|
||||||
|
|
||||||
|
`.env` holds three values — `PORT`, `PUBLIC_URL`, `POSTGRES_URL`. Every key lives in
|
||||||
|
`$OFFICER_ROOT/secrets/officer-keys.db`, one per purpose. See `docs/secret-store.md`.
|
||||||
|
|
||||||
`platform/` and `capabilities/` each have their own `CLAUDE.md` with detail. This file is the layer
|
`platform/` and `capabilities/` each have their own `CLAUDE.md` with detail. This file is the layer
|
||||||
above them: where things live, how to change them safely, and the things that are true of the running
|
above them: where things live, how to change them safely, and the things that are true of the running
|
||||||
system but written down nowhere else.
|
system but written down nowhere else.
|
||||||
|
|||||||
Reference in New Issue
Block a user