todo: let people see and switch off the affordances reaching their agents

They are global — affordanceBlock() reads every file and is called with no user context, so every
account gets every one in every conversation.

Fine while they are uncontroversial, and not fine straight after. "Wait for the question" was written
today to one owner's taste, is probably what most people want, and nobody asked anyone. An affordance
nobody can see and nobody can decline is a preference imposed as a fact.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-21 03:07:33 +00:00
co-authored by Claude Opus 5
parent 3fb439fabf
commit 4984fdc3a2
+21
View File
@@ -12,6 +12,27 @@ below that proposed deleting it have been removed rather than left to mislead th
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.
## Affordances
- [ ] **No way to see which affordances are reaching your agents, or to turn one off.** They are global:
`affordanceBlock()` reads every file under `capabilities/affordances/` and is called with no user
context (`claude-manager.ts:582`), so every account gets every one, in every conversation.
That is fine while they are uncontroversial and stops being fine immediately after. "Wait for the
question" was written to one owner's taste on 2026-08-21 — probably what most people want, and
nobody has asked anyone. An affordance nobody can see and nobody can decline is a preference
imposed as a fact.
Wants: a settings screen listing every affordance with its name, description, where it came from
(`officer/core` versus a plugin) and its body, plus a per-user toggle. Storage is one table keyed
on user and the affordance's namespaced id. The work is threading a userId into `affordanceBlock`,
which today takes only a root path.
Two things to decide when it is built rather than now: whether a plugin can ship an affordance that
is off by default, and whether disabling one should be visible to the agent at all — an agent told
"this client renders images" behaves differently from one told nothing, and a THIRD state, "you
were told not to", is a different thing again.
## Plugin infrastructure
- [ ] **A plugin cannot claim a WebSocket provider.** `pluginPermissions` in mount.ts sets `api` and