retire the single-user claim from the docs it outlived
CLAUDE.md asserted "single-user is a hard invariant, not a stage" while users held six rows and role_capabilities held grants. Every doc that repeated it is corrected here, in prose and in the code comments that carried the same claim. The accurate statement is narrower: one owner who bypasses every check, other accounts holding only what their role is granted, and a set of capabilities — terminal, chat, files, tasks, items, desktop, browser — that are structurally ungrantable because they execute as the owner's OS user. TODO.md gains a Multi-user section for what the read turned up: no way to create a second account, dashboards.id colliding across users, authorize.ts untested, pty/vault/opencode taking no identity, Radicale still owner_only. claude-sidecar-isolation.md's open question is answered rather than left open — the per-email spawn model is dead weight, because chat is an execution capability and no second account can ever reach it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,16 +5,27 @@ Guidance for any coding agent working in the Officer platform repo.
|
||||
**The instructions live in [`CLAUDE.md`](CLAUDE.md). Read it first — this file only points there.**
|
||||
|
||||
Kept separate so agents that look for `AGENTS.md` by convention find the same guidance as those that
|
||||
look for `CLAUDE.md`, without the two drifting apart. The previous contents of this file had drifted
|
||||
badly: they described Officer as a multi-user intranet for small businesses, with a user-invitation
|
||||
API, a `bun dev` serving a separate dashboard on port 5000, and a closing instruction to be
|
||||
"multi-user aware — always consider user isolation and role-based access". None of that is true.
|
||||
look for `CLAUDE.md`, without the two drifting apart.
|
||||
|
||||
## Orientation
|
||||
|
||||
Officer is a self-hosted personal platform that **serves exactly one person — the owner of the
|
||||
server**. There is no tenancy, no roles, no user management. If a design question turns on "which
|
||||
user", the answer is the owner.
|
||||
Officer is a self-hosted platform built around **one owner** (user id 1, role `Super Admin`, who
|
||||
bypasses every permission check), which since 2026-08-07 also admits **additional accounts holding a
|
||||
strict subset of it**. Roles are `Admin` / `Member` / `Developer`; what each may reach is decided by
|
||||
per-role capability grants, resolved on every request.
|
||||
|
||||
If a design question turns on "which user", the answer depends on the surface: real for the **app**
|
||||
capabilities (gitea, music, photos, email, calendar…), and still always **the owner** for anything
|
||||
that executes code or touches the disk — terminal, chat, tasks, files, desktop, browser are
|
||||
`kind: 'execution'` and can never be granted. `src/servers/capabilities/registry.ts` is the authority.
|
||||
|
||||
**Mounting a router without a registry entry makes the server refuse to boot.** Read the "Capabilities"
|
||||
section of `CLAUDE.md` before adding one.
|
||||
|
||||
This file previously described Officer as strictly single-user with "no tenancy, no roles, no user
|
||||
management". That was written to correct an *older* drift in the opposite direction — a fictional
|
||||
multi-user intranet with a user-invitation API — and it overshot. Both are now superseded by the
|
||||
paragraph above; treat the capability registry as the source of truth over either.
|
||||
|
||||
This repo is one of two. The other, `capabilities/`, holds the agent's tasks, tools and skills as
|
||||
plain files, and is where most changes belong — adding or changing a task needs no code change here
|
||||
|
||||
Reference in New Issue
Block a user