diff --git a/TODO.md b/TODO.md index e08e432b..3108cd1c 100644 --- a/TODO.md +++ b/TODO.md @@ -14,9 +14,13 @@ 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 -**77 open, 18 closed**, across 28 themes. +**78 open, 18 closed**, across 28 themes. | Theme | Open | Closed | | ------------------------------------------------------------------------------------------ | ---- | ------ | @@ -29,7 +33,7 @@ the owner's OS user and can never be granted. Indirection there really is accide | [Components — the shared UI layer](todo/components/) | 1 | 0 | | [File watchers](todo/file-watchers/) | 1 | 0 | | [Files app — routing](todo/files-app/) | 3 | 0 | -| [Fleet — one command across every server](todo/fleet/) | 2 | 0 | +| [Fleet — one command across every server](todo/fleet/) | 3 | 0 | | [Headscale](todo/headscale/) | 0 | 5 | | [Infra (alpha)](todo/infra/) | 5 | 0 | | [Known bugs](todo/known-bugs/) | 2 | 1 | @@ -64,7 +68,7 @@ the owner's OS user and can never be granted. Indirection there really is accide - `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) +- `2026-08-21` **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) - `2026-08-21` **A way to mark a commit "this one ships", so a release is not just `master`'s tip** — [fleet/a-way-to-mark-a-commit-this-one-ships-so-a](todo/fleet/a-way-to-mark-a-commit-this-one-ships-so-a.md) - `2026-08-21` **iPhone Action Button → run an Officer task from a locked phone** — [mobile-apps/iphone-action-button-run-an-officer-task-from](todo/mobile-apps/iphone-action-button-run-an-officer-task-from.md) - `2026-08-21` **The mobile recorder app, and the dispatcher agent behind it** — [mobile-apps/the-mobile-recorder-app-and-the-dispatcher](todo/mobile-apps/the-mobile-recorder-app-and-the-dispatcher.md) -- `2026-08-21` **A plugin's settings routes are reachable by anyone the plugin is granted to** — [multi-user/a-plugin-s-settings-routes-are-reachable-by](todo/multi-user/a-plugin-s-settings-routes-are-reachable-by.md) diff --git a/scripts/todo-index.ts b/scripts/todo-index.ts index 371a390f..ea1eeeb6 100644 --- a/scripts/todo-index.ts +++ b/scripts/todo-index.ts @@ -17,6 +17,9 @@ export type Item = { theme: string; status: string; created: string; + /** `urgent` or empty — see todo/README.md for why there is no scale. */ + priority: string; + due: string; order: number; file: string; }; @@ -52,6 +55,8 @@ export function readTree(): { themes: { theme: string; heading: string; items: I theme, status: fm.status ?? 'open', created: fm.created ?? '', + priority: fm.priority ?? '', + due: fm.due ?? '', order: Number(fm.order ?? 0), file: `todo/${theme}/${f}`, }; @@ -103,8 +108,17 @@ function render(): string { // whole split risks. List them explicitly rather than letting them age out of view. const notes = themes.filter((t) => !t.items.length).map((t) => `- [${t.heading}](todo/${t.theme}/_index.md)`); + // Urgent goes above everything. An item the owner called urgent, sorted in among seventy-five others + // by theme, is an item nobody sees on the day it matters. + const urgent = themes + .flatMap((t) => t.items) + .filter((i) => i.status !== 'done' && i.priority === 'urgent') + .sort((a, b) => (a.due || '9999').localeCompare(b.due || '9999')) + .map((i) => `- ${i.due ? `**due ${i.due}** — ` : ''}**${i.title}** — [${i.id}](${i.file})`); + return [ HEADER, + ...(urgent.length ? [`## Urgent\n`, ...urgent, ``] : []), `## Themes\n`, `**${open} open, ${done} closed**, across ${rows.length} themes.\n`, `| Theme | Open | Closed |`, diff --git a/todo/README.md b/todo/README.md index ac9ef8a9..19cbf853 100644 --- a/todo/README.md +++ b/todo/README.md @@ -45,6 +45,11 @@ process everywhere, report which host is behind… `assumed` (unknown, floored at 2026-08-20, the day before the split — a bounded "before today" rather than an invented day). - **`order`** — position within the theme, preserved from the original list. What a board reorders. +- **`priority`** _(optional)_ — `urgent` when the owner says so, absent otherwise. There is no scale of + five: an item is either something he named as urgent or it is not, and a scale would only invite + everything to drift upward. Urgent items are listed first in the generated index. +- **`due`** _(optional)_ — a date the owner named. Only ever written because he said one; never inferred + from tone or from how the item is worded. - **The body is prose, and it is the point.** These entries carry the reasoning, what was verified versus assumed, and what was already tried. An item stripped to a title loses the thing that made this list worth keeping. diff --git a/todo/fleet/settings-to-choose-which-server-each-feature.md b/todo/fleet/settings-to-choose-which-server-each-feature.md new file mode 100644 index 00000000..1cad3b9c --- /dev/null +++ b/todo/fleet/settings-to-choose-which-server-each-feature.md @@ -0,0 +1,37 @@ +--- +id: fleet/settings-to-choose-which-server-each-feature +title: "Settings to choose which server each feature uses" +theme: fleet +status: open +priority: urgent +due: 2026-08-22 +created: 2026-08-21 +date_source: stated +order: 0 +--- + +**Settings to choose which server each feature uses.** Wanted 2026-08-21, **needed 2026-08-22** — the +owner named it urgent and named the case: **ReClip, for saving videos.** Now that there are several +servers, each functionality needs to be pointed at one deliberately, from Officer's settings, rather +than always resolving to whatever is local. + +**The blocker is concrete and small.** `api/file-browser/router.ts:1271` reads + +```ts +const RECLIP_BASE = process.env.RECLIP_URL ?? 'http://localhost:8899'; +``` + +— a module-level constant, read once at import, from an environment variable. So every install can only +ever reach its OWN ReClip, there is no way to say "download this on `omega`", and changing it means +editing `.env` and restarting rather than a setting. Five hosts hold a platform checkout +(`docs/servers.md`); three run it. + +The generalisation the owner asked for is the setting being **per feature**, not one global "which +server am I". Different functions belong on different machines — the box with the disks is not the box +with the GPU is not the box on the fast line — so this is a routing table, one row per capability. + +Worth knowing before designing it: the platform already has per-server registries for a plugin +(Jellyfin keeps servers with write-only access tokens; offscale keeps a server picker), so there is a +shape to copy rather than invent. And `docs/multi-server-push.md` is the same question arriving from the +other direction — a payload that does not say which server sent it — so whatever names a server here +should be the identifier that design settles on.