TODO.md had reached 1050 lines and 72 open items across 28 sections, read mostly on a phone. It is now a directory: todo/<theme>/<item>.md, one card per file, with frontmatter carrying id, status, created date and order, and the prose body copied across verbatim. TODO.md becomes a generated index (bun run todo:index). Dates: where an item's prose stated one it is used; otherwise its old section's; otherwise 2026-08-20, floored at the day before the split rather than invented. date_source records which. Shaped for a two-way Kanban board, filed as todo/tooling — a card is a file, id is the identity, frontmatter is the machine's half and the body is the owner's. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
50 lines
3.4 KiB
Markdown
50 lines
3.4 KiB
Markdown
---
|
|
theme: affordances-runtime
|
|
heading: "Affordances (2026-08-19)"
|
|
kind: theme
|
|
---
|
|
|
|
Agreed and written down in `plugins/CLAUDE.md`; **nothing is built**. An affordance is what the surface
|
|
on the other end offers the agent — declared by the code that implements it, read at runtime. The first
|
|
two are image rendering (core) and gitea (`git` for git, `tea` for everything else).
|
|
|
|
Built 2026-08-19: `servers/affordances/load.ts` reads the tree and compiles one block, and
|
|
`claude-manager.ts` appends it to every Claude session via
|
|
`systemPrompt: { type: 'preset', preset: 'claude_code', append }`. Read per session, so a plugin
|
|
installed an hour ago is live on the next message.
|
|
|
|
Still to build:
|
|
|
|
- `capabilities/affordances/` created by the setup script, with `officer/core/` populated from an
|
|
officer-capabilities repository. The directory exists on this machine by hand; a fresh install gets
|
|
nothing, so the first affordance is currently a local artefact rather than a shipped one.
|
|
- **Opencode delivery.** It has its own driver and gets nothing, so image rendering is currently a claim
|
|
that holds on one harness — exactly the drift affordances exist to remove. Deliberate: opencode work is
|
|
paused pending its v2 migration and this would be thrown away. Revisit when v2 lands.
|
|
- A bare `claude` run in a terminal on the host gets nothing either, since it never passes through
|
|
`claude-manager`. Would need a generated file, which is the thing `user-instance.ts` refuses to write
|
|
for the owner.
|
|
- ~~Plugin contribution~~ — built 2026-08-19 (`affordances/publish.ts`). An `affordances/` directory in
|
|
the plugin repository is copied to `capabilities/affordances/<publisher>/<plugin>/` on install and
|
|
removed on uninstall. Gitea is the first to ship one.
|
|
- **The other categories.** A plugin can contribute affordances and nothing else. Skills, tools, tasks
|
|
and processes are the obvious next ones and were deliberately left out — one mechanism, proven, before
|
|
five. When they land, `publishAffordances` generalises rather than gaining siblings.
|
|
- **`officer/core` and `officerdev/<plugin>` are both correct — do not normalise them.** The path uses
|
|
`publisher` verbatim, so a plugin published by officerdev lands under `officerdev/`. `officer/core` is
|
|
not a plugin at all: it is the PLATFORM's own, shipped by the setup script from the capabilities
|
|
repository. Two spellings marking two different things, arrived at by accident and kept on purpose.
|
|
Anyone tidying this into one name is removing the distinction, not the inconsistency.
|
|
|
|
Open, and deliberately deferred:
|
|
|
|
- **Scoping.** Everything is loaded into every conversation. Fine at two files, not at twenty. A
|
|
`surface` field was drafted and dropped because it was doing two jobs at once: for image rendering it
|
|
means _what the client renders_ (a phone, a web bubble, a cron run with nobody watching), for gitea
|
|
_what tooling exists on this machine_. Those are different axes and one field cannot be both. Decide
|
|
the axis before adding the field — and note this codebase has already been bitten by a field that
|
|
validated itself and was never consumed (`unauthenticatedPaths`, see `plugins/public-paths.ts`).
|
|
- **Drift.** The rule is "declared where implemented", but a hand-authored markdown file in a repository
|
|
is not that — `ChatImage` could stop rendering images and no file would notice. Accepted for now
|
|
because prose that reaches every harness beats a registry that reaches one; revisit if it bites.
|