three new todos, seven closed, one real bug fixed on the way

Added: a Spotlight-style launcher on ctrl-space with the dock pruned behind it, plus dock effects and
auto-hide; a repeating-prompt option on the background-job starter, which is the Nudger in the place
it belongs — attached to a job already running rather than a schedule pointing at a session that may
not exist, and inheriting its three refusals; and a deep read of the Workspace/Panels framework, low
priority and explicitly not pain-driven, with the existing panel items folded into it because they are
symptoms of the same unexamined design.

Closed after checking rather than assuming — five of the seven were already done and the entries
outlived the work. The whole offscale rename debt is finished: panels read "Offscale", the picker
heading is right, console session keys were renamed on 2026-08-16, and there are zero stale
/headscale paths or PLUGIN.md self-references. The one remaining mention is a form placeholder,
https://headscale.example.com, which is correct — that IS a Headscale URL. offscale declares ssh as an
osDependency. The manifest module-cache is fixed by importFresh.

example/manifest.ts named web/Router.tsx as the frontend convention; discovery wants panels.ts and
layout.ts, by those exact names, or it refuses the plugin.

One that was NOT already done, and I nearly closed it by mistake: reindex-music.ts moved into the
music plugin but still read process.env.DATA_PATH, which stopped existing on 2026-08-13. Run from the
repo it looked in platform/data/music/.server — one level too deep — and reported the sidecar as not
running. It now imports DATA_PATH from the platform, which resolves to /home/pastilhas/officer-dev/data.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-21 03:38:37 +00:00
co-authored by Claude Opus 5
parent bcf8df9d32
commit ee7bc4920c
+60 -10
View File
@@ -12,6 +12,30 @@ below that proposed deleting it have been removed rather than left to mislead th
What did NOT reverse: `execution` permissions (terminal, chat, tasks, files, desktop, browser) run as
the owner's OS user and can never be granted. Indirection there really is accidental complexity.
## Shell — spotlight and the dock
- [ ] **A Spotlight-style launcher, on `ctrl-space`.** The dock is full and cannot grow; navigation
already borrows from macOS (see `docs/navigation-audit.md`), so the launcher is the same borrowing
taken one step further. Type a few letters, get routes, chats, files, plugins, settings sections —
and hit enter. Dock settings already exist, so the other half is pruning the dock down to what is
actually used and letting the launcher carry the rest.
**Trigger to confirm:** `alt-space` is the owner's preferred chord but is already load-bearing for
him elsewhere, so `ctrl-space` unless that clashes too.
- [ ] **Dock effects, and auto-hide.** Wanted alongside the launcher rather than after it: once the
launcher carries navigation, the dock stops needing to be permanently visible.
## Background jobs
- [ ] **A repeating prompt on the background-job starter.** An option beside the existing controls: send
this agent a message every N minutes or hours. This is the Nudger from 2026-08-20 in the place it
actually belongs — attached to a job that is already running, rather than a separate schedule
pointing at a session that may not exist.
The hard-won part is already written down: `api/chat/nudger.ts` refuses when the session is not
live, when it is generating, and when any other session is live in the same tree — because "not
generating" was once treated as permission and started a second agent in a repository another was
building in. Whatever shape this takes, it inherits those three refusals.
## Notifications
- [ ] **A push payload does not say which server sent it**, which is fine for one and breaks three things
@@ -258,6 +282,18 @@ day. Kept here for what the policy work turned up, which is not obvious from the
## Workspaces & Panels
- [ ] **A deep read of the whole framework, to understand it and then improve it.** Low priority and
explicitly not pain-driven — it works, and it works well. But it was built fast and then added to,
repeatedly, and nobody has since sat down and read the whole thing at once.
Three questions to answer rather than assume: can the query strings come out of the flow; is there
a better shape for panel-to-panel communication than the current channel/URL split; and what does
the layout tree cost that a simpler one would not.
**Fold the existing panel items into this** — the silent `key`/`appType` mismatch, the destructive
layout migration on a renamed key, and `docs/workspace-panel-todo.md`. They are symptoms of the
same unexamined design, and fixing them one at a time is how it stays unexamined.
Also a teaching exercise: the owner wants to understand it end to end, which is a reason to do it
properly rather than quickly.
Its own list — **`docs/workspace-panel-todo.md`** — because it is long and actively worked. Full
analysis behind it: `COMMS/workspace-panel-framework-analysis-2026-08-07.md`.
@@ -572,17 +608,24 @@ is. Everything below was found that way and none of it is fixed.
**Offscale is still branded headscale in shipped, user-visible places.**
- [ ] `web/panels.ts` registers three panels named "Headscale servers", "Headscale", "Headscale" — these
- [x] `web/panels.ts` registers three panels named "Headscale servers", "Headscale", "Headscale" — these
are what a user reads in the panel picker.
- [ ] `web/OffscaleServerPicker.tsx:26` renders the literal heading `Headscale`.
- [ ] `web/ConsoleView.tsx:22` mints terminal session ids as `headscale-console-<id>`. That is persisted
**Done.** Verified 2026-08-21: the three read "Offscale servers", "Offscale", "Offscale".
- [x] `web/OffscaleServerPicker.tsx:26` renders the literal heading `Headscale`.
**Done.** Verified 2026-08-21: it renders `Offscale`.
- [x] `web/ConsoleView.tsx:22` mints terminal session ids as `headscale-console-<id>`. That is persisted
state rather than a comment, so renaming it orphans live console sessions — cheap now, less so later.
- [ ] ~12 stale `/headscale` route paths in comments across `web/`, plus `App.tsx:78` in the platform.
- [ ] `PLUGIN.md` has ~11 stale self-references (`headscale_servers`, `listHeadscaleServers`, permission
**Done 2026-08-16**, and the file carries a comment recording it — a pty session KEY, not a label.
- [x] ~12 stale `/headscale` route paths in comments across `web/`, plus `App.tsx:78` in the platform.
**Done.** Verified 2026-08-21: none left in either. The one remaining mention is a form
placeholder, `https://headscale.example.com`, which is correct — that IS a Headscale URL.
- [x] `PLUGIN.md` has ~11 stale self-references (`headscale_servers`, `listHeadscaleServers`, permission
key `headscale`, `/api/headscale`, panel keys, `useHeadscaleSection()`).
**Documentation that actively lies.**
**Done.** Verified 2026-08-21: zero occurrences of either name.
- [ ] `plugins/offscale/PLUGIN.md:445-449` says the ACL assistant is deliberately unwired and must not be
wired up. It IS wired — `sidecar/assist.ts`, `claude-proxy.ts`, `web/PolicyAssistant.tsx` and the
manifest's `readOnlyWrites` all ship.
@@ -595,7 +638,7 @@ is. Everything below was found that way and none of it is fixed.
- [ ] `plugins/music/MUSIC_API.md` documents now-playing as one snapshot per user with no mention of
`?device=`, which the schema makes part of the primary key. A mobile client written to that doc is
correct only by accident.
- [ ] `plugins/example/manifest.ts:12` lists `web/Router.tsx` as the frontend convention; discovery
- [x] `plugins/example/manifest.ts:12` lists `web/Router.tsx` as the frontend convention; discovery
requires `web/panels.ts` AND `web/layout.ts`. The same file documents an `ownerOnly` field that does
not exist and never did.
- [ ] The Companion contract docs the offscale code cites (`COMMS/OFFSCALE_COMPANION_API.md`,
@@ -609,17 +652,24 @@ outside the example's new README:
pins `appTypes.allowed` with `fallback: allowed[0]`, so a typo renders the first panel.
- [ ] The `<appName>_` table prefix is unenforced. The barrel is `export *` across every plugin into one
`public` schema, so two plugins choosing the same unprefixed name collide with no error until push.
- [ ] A manifest is module-cached for the process lifetime: editing it does nothing until
- [x] A manifest is module-cached for the process lifetime: editing it does nothing until
`pm2 restart officer`, and `outdated` cannot see a version bump either.
**Fixed 2026-08-21 (`da30d1a6`).** `importFresh` keys the import on the file's mtime — a changed
manifest is re-read, an unchanged one is still a cache hit. Found the expensive way: a reinstalled
jellyfin was judged against the DELETED plugin's manifest, so it was ruled ineligible for the user
list and provisioning silently did nothing. Note the limit: only the named file is re-read, so a
plugin's own imports still need a restart.
- [ ] Permission-key prefixing is convention, not validation. Only a collision with a CORE key is refused,
silently, at mount, with a console error.
**Genuinely missing.**
- [ ] `plugins/offscale` spawns the `ssh` binary (`sidecar/ssh.ts`) but declares no `osDependencies`, so
- [x] `plugins/offscale` spawns the `ssh` binary (`sidecar/ssh.ts`) but declares no `osDependencies`, so
install never checks for it and the Console fails at runtime instead of refusing at install.
`PLUGIN.md:421` already lists it as a host dependency — the manifest is the file that is wrong.
- [ ] `scripts/reindex-music.ts` resolves its port file from `process.env.DATA_PATH ?? cwd/data`, and
**Already fixed** — the manifest declares `ssh` with per-manager packages, and its own comment
records the 2026-08-16 change. Verified 2026-08-21: the probe reports `offscale ssh=ok`. The entry
outlived the fix.
- [x] `scripts/reindex-music.ts` resolves its port file from `process.env.DATA_PATH ?? cwd/data`, and
`DATA_PATH` stopped being an env var on 2026-08-13. Run from the repo it looks in
`platform/data/music/.server` and never finds it. One line.
- [ ] `plugins/music/web/MusicPlayerHost.tsx` header says it is mounted once in the persistent