Commit Graph
9 Commits
Author SHA1 Message Date
pastilhasandClaude Opus 5 b63badaf67 remove the email residue the extraction left in the platform
a sweep for remnants after 2026-08-18. nothing was broken - no dangling
import, symbol, route or permission key anywhere in src/ - but the platform
was still speaking the plugin's vocabulary in a dozen places.

the one that mattered is live code rather than prose: ChatPanelWrapper
hardcodes workspace.id === 'email' to send context: 'email', which is the
frontend half of the pair whose backend half (resolveEmailCwd) carries a
fifteen-line justification. the two ends now both say so, including that
adding a SECOND id there is the signal the platform needs a real way for a
plugin to declare a chat context.

the rest: two dead imports left by removing the settings section, an empty
'Email' type-section header, a protocol.ts section header with no members
naming the plugin's SSE design, and a queue comment pointing at
sidecar/email/sync-runner.ts - a path in another repository now.

CLAUDE.md, AGENTS.md and working-on-officer.md described email as a platform
feature, an app permission and a pm2 process. those are the files a fresh
agent reads first, so they were the highest-risk staleness in the tree.

TODO.md's whole Email section moved to the plugin's own repository. it held
OPEN items pointing at sidecar/email/store.ts, which is exactly how a leftover
list sends someone to edit files that do not exist.

the delete-account dialog promised it would remove email accounts and
playlists. both tables belong to plugins now, so that cascade only happens
where the plugin is installed - it now says 'anything an installed plugin
keeps for them' instead of naming two it cannot guarantee.

imapflow and mailparser STAY in package.json. the plugin has no package.json
of its own and resolves from the platform's node_modules, so removing them
would break the installed plugin's sidecar. the fix is giving plugins their
own dependency manifest, not deleting these.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 01:01:23 +00:00
pastilhasandClaude Opus 5 27aa72d923 finish the offscale sweep: two real remnants and eleven stale names
Asked for a thorough check that nothing of offscale is left in the platform. The
extraction was sound — no router, no permission entry, no app-store entry, no
screen, no panel app, no env var anything reads. Two things were genuinely wrong,
and both were in setup rather than in the server.

── The secret store minted a key for a plugin ──

`officer-setup` bootstrapped two purposes: `jwt` and `headscale`. The second was a
key for a PLUGIN, under a name the rename had already replaced, on a machine where
the plugin is not installed and nothing would ever ask for it. offscale encrypts
under `offscale`, and `getKey` creates on demand — which is precisely what lets
core know nothing about plugins. Now core bootstraps `jwt` alone.

── `.env.example` documented variables for a deleted router ──

HEADSCALE_URL, HEADSCALE_API_KEY and HEADSCALE_USER were described as driving
`/api/vpn`. That router was deleted on 2026-08-14 and nothing has read any of them
since. Left as a note saying where the tailnet's credentials live now, because
somebody with an older `.env` will otherwise wonder why setting them does nothing.

── Names that outlived the thing ──

Eleven comments referred to the plugin's route, panels, console or server registry
as "headscale": three sidecar config files describing their own shape by pointing
at it, two screens citing `/headscale` as the example of a Workspace/Panel route,
the terminal's note about the Console, and the photos types. Also `catalogue.ts`,
which still claimed headscale "is CORE now", and `working-on-officer.md`, which
told the reader a core install runs six processes including `officer-headscale`.

Upstream references are deliberately untouched: "Headscale's API", "the Headscale
admin credential", "is this a Headscale server?" all name the thing the plugin
drives, and renaming those would make the sentences false.

`docs/secret-store.md` argued headscale must be core because the tailnet is the
perimeter. Marked superseded rather than deleted, with the distinction that
settles it: the perimeter is the tailnet EXISTING, which machine-setup still
arranges on a core install — not the platform shipping the screen that
administers it.

Verified by counting: live code, setup provisioning, env references, permission
entries, app-store entries, hono mounts, dock defaults, screens and panel apps all
zero. What is left is generated files (Plugins.gen, plugin-schemas.gen), the
bundled catalogue entry, test fixtures using "offscale" as an example app name,
and history.

tsgo clean, frontend builds, 873 pass / 7 fail unchanged, setup scripts parse.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 11:24:23 +00:00
pastilhas 027b10bd6e step 4/4: the docs say permissions too, and capability means one thing again
44 files of prose — CLAUDE.md, AGENTS.md, TODO.md, 20 docs, both plugin design
documents, and the comment surface the earlier steps could not reach.

Applied against an explicit keep-list, not swept, because the word turned out to
have SIX meanings in this repository rather than the three the offscale doc
recorded:

  permissions          renamed (steps 1–2)
  $OFFICER_ROOT/capabilities/  KEPT — the item store, and now the only thing
                               the word means that is ours
  sidecar routing keys renamed to `handles` (step 3)
  Lightning wallet     KEPT — a domain term, and on the wire to the mobile apps
  terminfo queries     KEPT — XTGETTCAP, in the pty sidecar
  InvoiceShelf         KEPT — per-resource { write, bulkDelete } flags

The sweep still falsified two things, both caught by checking rather than by
review, and both in prose that discusses more than one meaning at once:

CLAUDE.md began claiming the item store lives at `$OFFICER_ROOT/permissions`.
It does not; that directory is on disk and full of skills and tools.

And the offscale doc's own note about the collision became
"Named `permissions`, NOT `permissions`" — a sentence that had eaten the thing
it existed to warn about.

Both restored, and the note rewritten to say what is now true: capability means
one thing of ours, and three that belong to somebody else's vocabulary.

Verified live after restart: self and admin permission endpoints 200, gated
route 200, agent-status 200, 9 grants intact with 6 permissions offered.
tsgo clean, 797 tests, 787 pass, same 7.

The rename is done. Four steps, no data lost, no client break that survived
the step it was introduced in.
2026-08-15 16:31:11 +00:00
pastilhasandClaude Opus 5 8826c2847e 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>
2026-08-13 05:26:07 +00:00
pastilhasandClaude Opus 5 f1cfc0042f rename officer-agent to officer-claude-code
The old name said nothing about what the process runs, and it sits directly
beside officer-anthropic-proxy — a different process doing a different job — so
"the agent" was ambiguous exactly where it mattered. CLAUDE.md already had to
spend a paragraph insisting the two are not the same thing. It spawns `claude`;
the name says so now.

Only two references were functional: the generator's CORE_PROCESSES and the CORE
list in catalogue.test.ts. Everything else was prose or comments.

Left alone deliberately: `x-officer-agent-token`. It looks like the same string
and is not — it is the agent-handoff HTTP header, naming a per-panel bearer
token, unrelated to any pm2 process. Renaming it would have changed a wire
protocol to tidy a label.

Historical docs keep the old name. claude-sidecar-isolation.md and
open-threads-after-per-user-claude.md are dated investigations that record the
PREVIOUS rename, from officer-claude to officer-agent, and rewriting them would
make that history unreadable. CLAUDE.md notes the change instead, where somebody
reading those will be looking.

Also worth recording, from the owner: merging this with officer-anthropic-proxy
into one sidecar was investigated tonight and rejected. They stay separate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-13 03:10:39 +00:00
pastilhasandClaude Opus 5 d56be0301d 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>
2026-08-07 21:58:44 +00:00
pastilhasandClaude Opus 5 04c0d89057 docs: bring the live docs back in line with the code
First pass of the documentation audit. Every doc was read against what the code actually
does now; this commit fixes the ones worth keeping and deletes the ones that were only
describing a past.

Corrected:
- CLAUDE.md — said seven WebSocket providers (there are eight, and terminal/vault are byte
  relays now, not translating bridges), listed channels/ as "Telegram / WhatsApp / Discord
  bridges" (they are gone; what remains is how /chat drives an agent turn), missed
  officer-wallet in the PM2 list and notify/ in the layout, and described the per-account
  email SQLite stores without saying they are the sidecar's and that nothing in the platform
  opens them. Further Reading pointed at four files that no longer exist and missed the four
  newest.
- docs/working-on-officer.md — PM2 list was four sidecars short, and it still explained the
  officer-claude rename as news. Replaced with the thing a reader actually needs: which
  process to restart for which change, and why restarting officer no longer costs you a
  terminal or an agent session.
- TODO.md — the "dead username plumbing" item was mostly resolved by deleting the channels,
  and two email items pointed at api/email/email-db.ts, which is sidecar/email/store.ts now.
- AGENTS.md — trailing paragraph listed the design notes being deleted here.
- MUSIC_API.md — playlists were entirely undocumented: seven endpoints the phone app has no
  reference for. Added from the sidecar's own contract.
- docs/jobs-unification.md — phases 1-3 shipped, so it now says so at the top. Phase 4 (push
  notifications) is the only reason the file still exists, and email sync is explicitly no
  longer part of it.

Deleted, all superseded rather than merely old:
- PHONE_APP.md — a February plan for apps that now exist, with their own repo and README.
- MARKETING_WEBSITE.md — a plan for a site this repo does not contain.
- SECURITY_AUDIT.md + SECURITY_FIXES.md — a February audit of a codebase since restructured;
  it still cites queue/handlers, which is now empty.
- docs/DOCKERIZATION_PLAN.md — cites pty-sidecar, whatsapp and projects, all deleted.
- SETUP_GUIDE.md — documents systemd units and setup scripts replaced by PM2 and `bun setup`.
  Not harmless: /etc/systemd/system/officer-pty-sidecar.service is still enabled on this host,
  pointing at a `monorepo/` directory that no longer exists, and has been failing to start
  ever since. That guide is how it got there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 16:11:29 +00:00
pastilhasandClaude Opus 4.8 86930f5b17 rename officer-claude to officer-anthropic-proxy
the pm2 entry named officer-claude never ran an agent. it starts
sidecar/claude/index.ts, which registers as capabilities: ['proxy'] and only
holds the anthropic proxy secret and forwards api traffic. the process that
actually spawns claude is sidecar/claude/user-instance.ts, which had no pm2
entry at all and was spawned on demand by the main server.

that misnomer is how both CLAUDE.md files ended up claiming that restarting
officer does not disturb a running agent session. it does: the agent was a
grandchild of officer and died with it. correct the name so the next reader
starts from a true model, and fix the claim in both files.

no behaviour change — officer-agent arrives in the next commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-30 04:28:19 +00:00
brunorezioandClaude Opus 5 1192aa23fc docs: add the working-on-officer guide
The orientation layer above platform/CLAUDE.md and capabilities/CLAUDE.md: which
of the three directories a change belongs in, the two-repo git rules, how to run
and verify without disturbing the running server, and the task system's
conventions — including the ones capabilities/CLAUDE.md omits, like INPUT_INCLUDE
and inline: ask.

Also records failure modes found by running things rather than reading them: the
vision model inventing text for images that have none, Whisper's translate being
English-only, and the Host header that protected routes require.

Lives here rather than at the deployment root so it is versioned and reaches
every install; the root CLAUDE.md points at it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 04:19:46 +01:00