The watch.* family (3 verbs). Every verb enters through the one front door: it is capability-checked, permission-checked, scope-checked and audited before it runs (see Security & permissions). Each entry below lists its capability, risk class (which fixes the minimum autonomy level), the minimum caller permission, its availability tier, whether it is idempotent, and any outbound egress.
Addwatch.add
| Property | Value |
|---|---|
| Capability | watch.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Subscribes the CALLER to the object’s change signals.
Watching grants ZERO access (the read is still gated by acl/visibility - ADR-0042 decision 6). The
object need only exist in the workspace (a watcher may follow a workspace-visible object they can
already see; a restricted object they cannot see is simply never fanned to them in practice, and the
watch row alone never opens it). Upserts (re-watching is idempotent; auto may flip false→true).
Input { objectType, objectId, auto? } (fields ending in ? are optional)
Call POST /v/watch.add with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool watch.add.
Listwatch.list
| Property | Value |
|---|---|
| Capability | watch.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
The caller’s own watches (optionally filtered by object_type). An actor
sees ONLY its own watch list (the recipient-scoping IDOR fence - actor_id = ctx.actor.id, the same
posture as inbox.list).
Input { objectType? } (fields ending in ? are optional)
Call POST /v/watch.list with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool watch.list.
Removewatch.remove
| Property | Value |
|---|---|
| Capability | watch.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Unsubscribes the CALLER. Idempotent: removing a non-watch is a no-op success. Recipient-scoped: a caller can only remove its OWN watch (the WHERE keys actor_id).
Input { objectType, objectId } (fields ending in ? are optional)
Call POST /v/watch.remove with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool watch.remove.