From 4984fdc3a2e01887959687509a5e9d242b747157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Fri, 21 Aug 2026 03:07:33 +0000 Subject: [PATCH] todo: let people see and switch off the affordances reaching their agents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- TODO.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/TODO.md b/TODO.md index f3925c0a..75faf5f0 100644 --- a/TODO.md +++ b/TODO.md @@ -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