assertPermissionTotality exists to refuse a surface nobody has gated, and it was reading the wrong list: Object.keys(handlers) — the map of implementations — while Bun served a hand-written route table twenty lines away. The comment beside it said neither could be a stale copy of the other. That was false, and it had a live instance: /api/cliamp/ws and /api/cliamp/audio/ws stayed in the route table for two days after their handlers and registry claims were commented out. Not exploitable — isWsProviderAllowed finds no permission and 403s a member, while the owner upgrades onto a dead socket — but precisely the drift the guard is for, invisible to the guard. Now there is one declaration. WS_ROUTES maps path → provider, the route table is generated from it, and the check reads it. A socket route cannot exist without being checked. Two smaller guards arrived with it. A route naming a provider with no handler refuses to boot, with the path in the message, instead of 500-ing on first connect. And the provider union that was inline in upgradeWs is named, so the route table typechecks against what that function can actually serve — which caught my first attempt, where WS_ROUTES was Record<string, string>. sidecar and dev-proxy are listed explicitly as served-but-absent-from-WS_ROUTES, because they upgrade through their own handlers rather than upgradeWs. Named so the absence cannot read as an oversight. Half the TODO was stale and it is recorded as such rather than quietly closed: the eight red tests it cites have been green since cliamp was deleted on 2026-08-15. Deleting cliamp removed the symptom and left the shape, which is the more interesting half. Verified against the real prefix lists rather than by reasoning: the served set passes, one unclaimed provider is refused by name, all five generated routes answer 401, and the server boots. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
76 lines
5.4 KiB
Markdown
76 lines
5.4 KiB
Markdown
# TODO — the index
|
|
|
|
Deferred work. **The items live in `todo/`, one file each**, grouped by theme; this file is the map
|
|
over them and is GENERATED — run `bun run todo:index` after any change rather than editing it here.
|
|
Format and the two-way-sync contract: `todo/README.md`.
|
|
|
|
**Context, corrected 2026-08-07.** This list used to open by saying Officer was "collapsing from
|
|
multi-tenant / open-source-ready to a **single-user platform**", and told you to treat multi-tenant
|
|
indirection as accidental complexity. **That direction was reversed.** The permission model shipped on
|
|
2026-08-07 to serve a real goal — deploy to the company server, onboard people, give each one their own
|
|
Gitea account through the platform. Per-user scoping is now a requirement, and the items that proposed
|
|
deleting it have been removed rather than left to mislead the next reader.
|
|
|
|
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.
|
|
|
|
## Urgent
|
|
|
|
- **due 2026-08-22** — **Settings to choose which server each feature uses** — [fleet/settings-to-choose-which-server-each-feature](todo/fleet/settings-to-choose-which-server-each-feature.md)
|
|
|
|
## Themes
|
|
|
|
**86 open, 23 closed**, across 29 themes.
|
|
|
|
| Theme | Open | Closed |
|
|
| --- | --- | --- |
|
|
| [Affordances](todo/affordances/) | 1 | 0 |
|
|
| [Speaking into a session from the backend](todo/agent-delivery/) | 2 | 0 |
|
|
| [Backburner](todo/backburner/) | 2 | 0 |
|
|
| [Background jobs](todo/background-jobs/) | 2 | 0 |
|
|
| [Chat interface](todo/chat/) | 1 | 0 |
|
|
| [Code editor](todo/code-editor/) | 1 | 0 |
|
|
| [Components — the shared UI layer](todo/components/) | 1 | 0 |
|
|
| [File watchers](todo/file-watchers/) | 1 | 0 |
|
|
| [Fleet — one command across every server](todo/fleet/) | 5 | 2 |
|
|
| [Headscale](todo/headscale/) | 0 | 5 |
|
|
| [Infra (alpha)](todo/infra/) | 6 | 0 |
|
|
| [Known bugs](todo/known-bugs/) | 4 | 1 |
|
|
| [Mobile apps](todo/mobile-apps/) | 3 | 0 |
|
|
| [Multi-user](todo/multi-user/) | 17 | 4 |
|
|
| [Notifications](todo/notifications/) | 1 | 0 |
|
|
| [Plugin ecosystem — before it opens to third parties (2026-08-18)](todo/plugin-ecosystem/) | 3 | 0 |
|
|
| [Plugin infrastructure](todo/plugin-infrastructure/) | 2 | 0 |
|
|
| [Plugin repos — what writing their READMEs turned up](todo/plugin-repos/) | 10 | 9 |
|
|
| [Plugin system — gaps the email extraction found (2026-08-18)](todo/plugin-system/) | 3 | 0 |
|
|
| [Prompt library](todo/prompt-library/) | 1 | 0 |
|
|
| [Settings — portable, and readable by an agent](todo/settings/) | 2 | 0 |
|
|
| [Shell — spotlight and the dock](todo/shell/) | 1 | 1 |
|
|
| [Sub-agents — agents spawning agents](todo/sub-agents/) | 1 | 1 |
|
|
| [Sudo terminal modal](todo/sudo-terminal-modal/) | 1 | 0 |
|
|
| [Tooling — the list about the list](todo/tooling/) | 1 | 0 |
|
|
| [Transmission](todo/transmission/) | 6 | 0 |
|
|
| [URL state — routing, query strings and selection](todo/url-state/) | 4 | 0 |
|
|
| [Waiting on the owner to run it](todo/waiting-on-owner/) | 2 | 0 |
|
|
| [Workspaces & Panels](todo/workspaces-panels/) | 2 | 0 |
|
|
|
|
## Records — no items, kept for the reasoning
|
|
|
|
- [Affordances (2026-08-19)](todo/affordances-runtime/_index.md)
|
|
- [Email](todo/email/_index.md)
|
|
- [Inputs outside forms (2026-08-19) — swept, fixed, closed](todo/inputs-outside-forms/_index.md)
|
|
- [Release-binary dependencies (2026-08-19)](todo/release-binaries/_index.md)
|
|
|
|
## Newest ten
|
|
|
|
- `2026-08-22` **A plugin's permission should be on for every role by default, off only on request** — [multi-user/a-plugin-s-permission-should-be-on-for-every](todo/multi-user/a-plugin-s-permission-should-be-on-for-every.md)
|
|
- `2026-08-22` **A user's settings should export and import as a plain file** — [settings/a-user-s-settings-should-export-and-import-as](todo/settings/a-user-s-settings-should-export-and-import-as.md)
|
|
- `2026-08-22` **The same for system settings, owned by the Super Admin** — [settings/the-same-for-system-settings-owned-by-the](todo/settings/the-same-for-system-settings-owned-by-the.md)
|
|
- `2026-08-21` **No way to see which affordances are reaching your agents, or to turn one off** — [affordances/no-way-to-see-which-affordances-are-reaching](todo/affordances/no-way-to-see-which-affordances-are-reaching.md)
|
|
- `2026-08-21` **Generalise it: deliver a turn to a named session, from anywhere in the backend** — [agent-delivery/generalise-it-deliver-a-turn-to-a-named](todo/agent-delivery/generalise-it-deliver-a-turn-to-a-named.md)
|
|
- `2026-08-21` **The cost of resuming grows with the transcript** — [agent-delivery/the-cost-of-resuming-grows-with-the-transcript](todo/agent-delivery/the-cost-of-resuming-grows-with-the-transcript.md)
|
|
- `2026-08-21` **'An agent spawned by a background job is invisible in the interface'** — [background-jobs/a-spawned-agent-is-invisible-in-the-interface](todo/background-jobs/a-spawned-agent-is-invisible-in-the-interface.md)
|
|
- `2026-08-21` **Show how long a turn took, beside its cost and tokens** — [chat/show-how-long-a-turn-took-beside-its-cost](todo/chat/show-how-long-a-turn-took-beside-its-cost.md)
|
|
- `2026-08-21` **Map every custom component, centralise it, and let a theme override it** — [components/map-every-custom-component-and-centralise-it](todo/components/map-every-custom-component-and-centralise-it.md)
|
|
- `2026-08-21` **Watch a directory, and attach actions to what lands in it** — [file-watchers/watch-a-directory-and-attach-actions-to-what](todo/file-watchers/watch-a-directory-and-attach-actions-to-what.md)
|