Compare commits
3
Commits
dc91f78f4f
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89fc3241f6 | ||
|
|
3552a5a7df | ||
|
|
7c41c56577 |
+47
-15
@@ -55,18 +55,33 @@ This file captures the **cross-cutting operational reality** that neither of tho
|
|||||||
process that runs `claude` was spawned by the main server, so PM2's tree-kill took it down every time.
|
process that runs `claude` was spawned by the main server, so PM2's tree-kill took it down every time.
|
||||||
A restart now costs the agent a socket reconnect, not the session, and output produced while officer is
|
A restart now costs the agent a socket reconnect, not the session, and output produced while officer is
|
||||||
down survives — the sidecar writes to `chat_session_events` itself. There is no `officer-claude`.
|
down survives — the sidecar writes to `chat_session_events` itself. There is no `officer-claude`.
|
||||||
- **Officer is twenty PM2 entries** (verified 2026-08-07 with `pm2 jlist`): `officer`,
|
- **Officer is TWENTY-SIX PM2 entries here today** (verified 2026-08-27 by `bun run docs:check`, which
|
||||||
`officer-anthropic-proxy`, `officer-agent`, `officer-opencode`, `officer-email`, `officer-pty`,
|
fails if this drifts): the five core processes — `officer`, `officer-anthropic-proxy`,
|
||||||
`officer-vnc`, `officer-music`, `officer-vault`, `officer-slskd`, `officer-headscale`,
|
`officer-claude-code`, `officer-opencode`, `officer-pty` — plus `officer-notify`, `officer-marketplace`,
|
||||||
`officer-transmission`, `officer-invoiceshelf`, `officer-wallet`, `officer-photos`, `officer-notify`,
|
`officer-oas`, and one per installed plugin.
|
||||||
`officer-caldav`, `officer-memos`, `officer-jellyfin`, `officer-gitea`.
|
|
||||||
**`pm2 list` shows twenty-two** — `mybiblepal-api` and `mybiblepal-audio` are a different project sharing
|
|
||||||
this PM2 daemon, and nothing here should touch them.
|
|
||||||
Never `pm2 restart ecosystem.config.cjs` — it bounces every
|
|
||||||
sidecar including the vault. Use `--only <name>`, or restart the single process the change needs.
|
|
||||||
This list goes stale every time a sidecar lands; `pm2 jlist` is the source of truth.
|
|
||||||
|
|
||||||
## Environment (this machine)
|
It was thirteen this morning. **Nothing about the platform changed**: all 21 plugins were installed on
|
||||||
|
this machine so the marketplace UI had something real to render. That is the paragraph below working
|
||||||
|
exactly as written, not an exception to it.
|
||||||
|
|
||||||
|
It was fifteen on 2026-08-25; `officer-minesweeper` and `officer-transcribe` were uninstalled since,
|
||||||
|
which is the point of the paragraph below rather than an exception to it.
|
||||||
|
|
||||||
|
**This number tracks PLUGIN INSTALLS, not platform releases.** It went to fourteen when Minesweeper was
|
||||||
|
installed and back to thirteen when it was removed, with no platform change either time — installing a
|
||||||
|
plugin that declares a sidecar writes it into the generated ecosystem file. Do not read a change here as
|
||||||
|
a platform change, and do not expect two machines to agree.
|
||||||
|
|
||||||
|
It said "twenty" and listed a different set until 2026-08-23 — including `officer-vault`, `officer-slskd`,
|
||||||
|
`officer-headscale`, `officer-transmission`, `officer-invoiceshelf`, `officer-wallet`, `officer-photos`,
|
||||||
|
`officer-jellyfin`, `officer-gitea`, `officer-music`, `officer-vnc`, none of which run here, while omitting
|
||||||
|
six that do. That is what a hand-maintained list of processes becomes: accurate on 2026-08-07, and nobody
|
||||||
|
re-derives a list while editing the sentence around it. `mybiblepal-api` and `mybiblepal-audio` are also
|
||||||
|
gone; nothing shares this daemon today.
|
||||||
|
|
||||||
|
Never `pm2 restart ecosystem.config.cjs` — it bounces every sidecar. Use `--only <name>`, or restart the
|
||||||
|
single process the change needs. `pm2 jlist` is still the source of truth; the check exists so the copy
|
||||||
|
cannot silently stop matching it.
|
||||||
|
|
||||||
- `OFFICER_ITEMS_DIR=/home/pastilhas/dockers/officer.dev/capabilities` ← items live here
|
- `OFFICER_ITEMS_DIR=/home/pastilhas/dockers/officer.dev/capabilities` ← items live here
|
||||||
- `DATA_PATH=/home/pastilhas/dockers/officer.dev/data`
|
- `DATA_PATH=/home/pastilhas/dockers/officer.dev/data`
|
||||||
@@ -167,10 +182,17 @@ keyed on **role**, never on a user, and live in `role_capabilities`; absence den
|
|||||||
capabilities (terminal, chat, files, tasks, items, desktop, browser) run as the owner's OS user in the
|
capabilities (terminal, chat, files, tasks, items, desktop, browser) run as the owner's OS user in the
|
||||||
owner's home and are **never grantable at any level** — that is structural, not a policy default.
|
owner's home and are **never grantable at any level** — that is structural, not a policy default.
|
||||||
|
|
||||||
What is NOT built: **there is no way to create a second account.** `createUser` has one call site,
|
**Account creation now exists** — `POST /api/users`, owner-gated, with a form under Settings → User
|
||||||
`api/auth/bootstrap.ts`, gated on an empty `users` table. No signup route, no invites, no admin
|
Management, plus role change, password reset, Linux provisioning and delete. It landed in `69a31051`; this
|
||||||
create-user handler — the six accounts in Postgres were inserted by hand. Details and the open defect
|
file claimed the opposite for days afterwards, and so did `platform/CLAUDE.md` and
|
||||||
list are in `platform/TODO.md` → "Multi-user"; the design write-up is `COMMS/capability-permissions-2026-08-07.md`.
|
`docs/roles-and-teams.md`, which sequenced a phase around building the thing that already existed.
|
||||||
|
|
||||||
|
Roles are a table as of 2026-08-23, with `users.role` and `role_permissions.role` as foreign keys onto
|
||||||
|
`roles.name` with `ON UPDATE CASCADE`. `USER_ROLES` is gone and `UserRole` is `string`, so the guard the
|
||||||
|
compiler used to provide is now a runtime check at every write path that takes a role from outside.
|
||||||
|
|
||||||
|
The design write-up is `COMMS/capability-permissions-2026-08-07.md`; the roles plan and what is still open
|
||||||
|
is `docs/roles-and-teams.md`.
|
||||||
|
|
||||||
The single-user claims that used to be all over this repo's docs were corrected on 2026-08-07. If you
|
The single-user claims that used to be all over this repo's docs were corrected on 2026-08-07. If you
|
||||||
find another one, it is stale — `platform/src/servers/capabilities/registry.ts` is the authority.
|
find another one, it is stale — `platform/src/servers/capabilities/registry.ts` is the authority.
|
||||||
@@ -231,6 +253,16 @@ actually reset at the providers — it is the only record of which ones.
|
|||||||
|
|
||||||
## Working agreement
|
## Working agreement
|
||||||
|
|
||||||
|
- **Delegate the writing.** When a feature is agreed and what remains is typing — a change repeated
|
||||||
|
across many files, translations, a form, a migration over a list of call sites — hand it to a cheaper
|
||||||
|
agent, keep working, and review the DIFF when it returns. The owner's architecture, somebody else's
|
||||||
|
typing, your review in the middle. This is the default here, not a per-task decision, and it does not
|
||||||
|
need asking for. Read `capabilities/skills/delegating/SKILL.md` before writing the brief: an agent that
|
||||||
|
has to ask a question has already cost more than it saved. **Pick the cheapest model that will get it
|
||||||
|
right** — Haiku for mechanical, Sonnet by default, Opus only when the work still holds a decision, which
|
||||||
|
usually means the brief needs finishing rather than a bigger model. Do NOT delegate anything where a
|
||||||
|
wrong guess is quiet and expensive — permission checks, credentials, anything that deletes — because reviewing
|
||||||
|
those properly costs as much as writing them.
|
||||||
- **Fix what you find.** If a defect is diagnosed and you know the fix, apply it — don't stop to ask.
|
- **Fix what you find.** If a defect is diagnosed and you know the fix, apply it — don't stop to ask.
|
||||||
The owner retests immediately and restarts cost nothing. Still ask when it's a genuine product
|
The owner retests immediately and restarts cost nothing. Still ask when it's a genuine product
|
||||||
decision rather than a defect, when it widens scope, or when it's hard to reverse.
|
decision rather than a defect, when it widens scope, or when it's hard to reverse.
|
||||||
|
|||||||
Reference in New Issue
Block a user