Capabilities
A capability is the right to cause a class of side effects — where tools meet external resources. Agents already reason and speak; the gap is credentialed external actions: posting to Slack, commenting on GitHub, sending a webhook. The model wants both: tool records (what operation is possible) and resource records (what external thing it operates on). A tool without a target is abstract; a target without a tool is inert.
A capability is not a record type. It’s the derived answer to “can this agent use this tool against this resource?” — computed from the intersection of x on the tool record and x on the resource record. The existing permission system is the single authority. No separate capability grant table, no second ACL that can disagree.
At activation time, build the agent’s tool registry by pre-filtering: the spawned agent literally cannot see tools it shouldn’t use. Maps cleanly onto the permission model — no runtime checks during the agent loop. resolveCapabilities(agentId, db) → { tools, resources } returns the resolved permission intersection; secrets resolve via a runtime-injected callback. If we later need narrowing (rate limits, time windows, action subsets), those become constraint records attached to the agent-tool or agent-resource permission edge — but start without them; the permission system is already expressive enough for the hourly Discord test.
Resources have identity in the substrate so activation policies and audit trails reference them by record ID rather than opaque config blob — Discord channels, GitHub repositories, Linear workspaces, PagerDuty services, code-repo checkouts, durable streams, sandbox runtimes. Scoped to houses (the right permission boundary — a house admin controls which external targets are available within their scope). Resources do not carry secret references — many resources may share one credential, one resource may need several; credential binding is a separate concern.
Secrets are the one place “everything is a record” breaks down if taken too literally. A capability without secret management is theatre. Credentials should be referenced from records, not stored in plaintext in shared records. The vault holds values keyed by stable record IDs; binding records say which credential goes where and are auditable — you can answer “which agents have access to which credentials” without touching the vault. Many resources sharing one credential is the common case. One resource needing multiple credentials (OAuth + webhook secret) means multiple bindings pointing at the same resource.
Open question: should secret-binding records enumerate resource_ids and agent_ids explicitly, or use the permission system (agent has r on the secret-binding record → can resolve it)? The permission approach is more consistent but means secret access is governed by the same chain-walking as everything else — possibly too permissive for credentials. Explicit enumeration is safer but means a second access-control path. Leaning explicit — credentials deserve a tighter default.
See: thinking/record-types (resource / tool / secret-binding shapes), thinking/activation, system/secrets.