Files
platform/todo/tooling/a-kanban-board-over-todo-synchronised-both.md
T
pastilhasandClaude Fable 5 420cd07507 /todos: a kanban board over the todo/ tree, owner-only
The filesystem is the database: GET reads the tree through the same module the
index generator now imports, PATCH splices frontmatter (status, priority, due,
order) and never touches a body byte, and every write regenerates TODO.md.
Columns open/doing/blocked/done, native drag between them, selection and theme
filter in the URL. Registry entry 'todos' (kind admin, 22 entries, docs:check
green), isSuperAdmin double-gate on the router.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-25 00:18:14 +00:00

2.9 KiB

id, title, theme, status, created, date_source, order
id title theme status created date_source order
tooling/a-kanban-board-over-todo-synchronised-both A Kanban board over `todo/`, synchronised both ways tooling done 2026-08-21 stated 1

A Kanban board over todo/, synchronised both ways. Wanted 2026-08-21, and it is the reason the list became a directory rather than a file. Read the tree, render columns, and write changes back — drag a card to another column and the file changes; edit the file and the board follows.

The file system is the database. There is no second store to reconcile, which is the whole point: these items are already versioned, already reviewable, already synced between machines by git. A board that kept its own copy would be a second truth with no way to say which one is right — the failure this repository has already documented twice (command_hq_sessions refusing a status column, chat_session_events being derived rather than stored).

The contract it can rely on is written down in todo/README.md → "Two-way sync". In short: a card is a file, id is the identity so a retitle never orphans one, frontmatter is the machine's half and the prose body is the owner's, and TODO.md is generated output that the board must never write to.

Open, and deliberately not decided here: which columns (status today holds only open/done, so doing and blocked are new values whenever the board wants them); whether it is an Officer screen, a panel app or a plugin; and how it notices a change made on disk while the board is open — a watcher, a poll, or a refresh button, which is the cheapest thing that works.


Built 2026-08-24 — /todos, a core screen, deliberately not a plugin. The tree lives in the platform's own repo, and dev tooling about the platform's backlog has nothing to gain from being installable elsewhere.

What v1 is: GET /api/todos reads the tree (shared module api/todos/todo-tree.ts, which scripts/todo-index.ts now also imports, so the board and the generated index cannot disagree); PATCH /api/todos/item splices frontmatter — status, priority, due, order — and never touches a body byte, with tests asserting exactly that. Columns are open / doing / blocked / done; drag a card to move it, and every write regenerates TODO.md. Selection and theme filter are ?selected= / ?theme=, so cards are real links and a filtered board is an addressable page. Owner-only: todos is kind: 'admin' in the registry (now 22 entries, docs:check green) with an isSuperAdmin gate on the router as the second lock.

Answers to this item's open questions: the columns are those four statuses, new values are one edit to TODO_STATUSES; it is a screen, not a plugin; change detection is a 30s refetch — the cheapest thing that works, as predicted. Not done: creating or editing items from the board (the body is the owner's half, written in an editor), and drag does not reorder within a column — order is PATCHable but no gesture drives it yet.