load affordances and append them to every claude session
The platform hosts the agent and never introduces itself. An agent gets a shell, a filesystem and a prompt; everything about the CLIENT on the other end has to be guessed. It writes , nothing renders, and nothing says why — because an <img> carries no bearer token and it is the user's DEVICE that fetches the URL. servers/affordances/load.ts reads capabilities/affordances/ and compiles one block; claude-manager passes it as systemPrompt.append with the claude_code preset, so the harness keeps its own prompt. Passed there rather than written to a file because it is the one place every session goes through, owner and member alike. A generated CLAUDE.md cannot do that — user-instance.ts deliberately refuses to write one for the owner, since it would pollute the personal ~/.claude/CLAUDE.md they maintain themselves. Read per session, not cached: capabilities/ is already read fresh each session, so a plugin installed an hour ago is live on the next message. Synchronous because createSession is not async, and making it so to read a few kilobytes would ripple through every caller. No filtering. Everything is loaded into every conversation, because the axis to filter on is not one dimension — for image rendering it is what the CLIENT renders, for gitea what TOOLING exists on the machine. Fine at two files, not at twenty; TODO.md carries the argument. Opencode gets nothing, and that is recorded as a gap rather than hidden: an affordance that holds on one harness is the drift this removes. Deliberate — opencode is paused pending v2 and the work would be thrown away. Nine tests, aimed at the failure that matters: a file that silently does not reach the agent looks exactly like one nobody wrote. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -304,20 +304,25 @@ Agreed and written down in `plugins/CLAUDE.md`; **nothing is built**. An afforda
|
||||
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).
|
||||
|
||||
To build:
|
||||
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 clone is future work; the directory is not.
|
||||
- A compiler: parse the tree, take each body under its `name` as a heading, produce one small block.
|
||||
Per session, not per boot — `capabilities/` is already read fresh each agent session, and a plugin
|
||||
installed mid-day should be live on the next message.
|
||||
- Delivery. Claude sessions take `systemPrompt: { type: 'preset', preset: 'claude_code', append }`,
|
||||
which nothing passes today. **Opencode has its own driver and would need the same**, or the affordance
|
||||
is a claim that only holds on one harness — which is the drift this exists to remove. A bare `claude`
|
||||
run in a terminal on the host gets neither unless a file is also written.
|
||||
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: an `affordances/` directory in the plugin repository, copied to
|
||||
`capabilities/affordances/<publisher>/<plugin>/` on install and removed on uninstall. Same shape as
|
||||
`assets/` and `publishAssets`.
|
||||
`assets/` and `publishAssets`. **Nothing does this yet** — gitea will be the first.
|
||||
|
||||
Open, and deliberately deferred:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user