Abilities: bounded data, frozen turns
Part III — The Paradigm · Chapter 7 of 9
The Ambient layer answered where evidence lives. This chapter is the other half of an assistant that acts: what it knows how to do. Bonnie's answer is the Ability.
The system at a glance
Three words, three jobs:
An Ability is what Bonnie knows how to do. A Skill is one machine-readable instruction inside it. A Capability is the contract — effect, permissions, limits — that makes the Skill safe to run.
So writing is an Ability; writing.type-at-cursor is a Skill inside it; text.write-at-surface is the Capability it requires. (A model-visible name like type_at_cursor is just the Skill projected into a provider's wire format — it is not the Skill itself.)
And the tie into the rest of the system is one loop. An Ability ships as a .bonnie package; validators admit it or refuse it; each turn freezes a snapshot of everything admitted; the model invokes a Skill from that snapshot; the Capability contract is re-checked; an adapter does the work; a receipt records what changed.
One naming collision to flag before going further: Anthropic's ecosystem uses "skill" for something else — an Agent Skill is a SKILL.md folder of markdown instructions loaded into an agent's context when relevant. The end of this chapter compares the two directly. Until then, "Skill" means Bonnie's.
One last piece of vocabulary: every Ability declares a paradigm — discipline, applicationExpertise, systemControl, or reasoning. In the schema's own words: "One can be good in design and an expert in Sketch, while being good in design but an amateur in Figma." Design is portable craft; Sketch is expertise in one tool. The split pays off at the end of this chapter.
Bounded data, never prose
A .bonnie package is canonical JSON — sorted keys, so the bytes are reproducible — integrity-digested and optionally Ed25519-signed. Ten ship with Bonnie today, among them browsing, coding, scrivener, sketch, window-management, and writing. The rule governing everything inside is the sentence I'd keep if I could keep only one:
Everything a package authors is bounded data. Tokens, closed enumerations, typed expressions, byte limits — never prose, never code. The engine owns every sentence it speaks; a package only fills typed slots.
Here is one Skill from writing.bonnie (abridged):
{
"id": "writing.type-at-cursor",
"kind": "effectful",
"access": "reversible",
"execution": {
"kind": "binding",
"bindings": [{ "adapterID": "typer",
"operation": "type_at_cursor",
"targetClasses": ["editable-prose-surface"] }]
},
"modelExposure": {
"enabled": true,
"invocationName": "type_at_cursor",
"parameters": [{ "name": "text", "type": "string", "required": true }]
},
"requirements": {
"capabilities": ["text.write-at-surface"],
"optionalInteractions": ["interaction.text-selection"],
"supportingAbilities": ["window-management"]
},
"routing": { "conflictPolicy": "preferDirectInteraction" }
}Everything load-bearing is a typed field: effect class, required Capability, consumable interactions, supporting Abilities, routing policy, and the adapter operation that does the work. Descriptive strings are UI metadata — they never become system-prompt authority, no matter who signed the package.
And admission is real: a package is bytes until validators accept it — identity, skills, schema references, paradigm honesty, plus a graph pass across everything installed (one owner per schema id, no colliding invocation names, no dependency cycles). A package declaring a destructive capability without a confirmation requirement is refused before it ever meets a turn.
The frozen turn
Declaring capability is half the mechanism. The other half is when capability may change.
At turn entry, Bonnie freezes one immutable AbilityRuntimeSnapshot — the whole registry, as a UUID-addressed revision — and the entire turn runs against it: one turn can never begin under one schema revision and dispatch under another. Edit a package in the Ability Studio mid-turn and the new registry activates for the next turn; the in-flight turn keeps its world.1
Dispatch re-checks everything. A provider's "tool"-shaped call (that word is quarantined to provider adapters) is translated back into a Skill invocation immediately, then the frozen contract and local safety are revalidated before anything executes. Capability constraints are a hard floor Bonnie owns — payload limits, duration, confirmation, staging, target allowlists — and no package preference can bypass them.
And an unmet requirement is not an error. Effectful Skills exist for a turn only while a compatible adapter is installed and ready; remove the adapter and they vanish from the next turn's roster, install it and they reappear. Dormant, not broken. Hold that thought for chapter 8.
Teaching without code
The shipped packages include scrivener.bonnie: a complete integration with a third-party manuscript application — binder manipulation, editor splitting, document corpus reading — expressed entirely as declarative data. In the specification's words, "there is no Scrivener source file in the tree."
A dynamic plugin declares the application it drives and, for each operation, a recipe built from a finite step vocabulary — typed expressions over literals, declared inputs, and observed geometry. One compiled, Bonnie-owned engine — Remote Hands, working through the visible macOS interface — interprets every recipe. The package carries knowledge, never an interpreter: teaching a new application takes a .bonnie file; adding a new input faculty takes a Bonnie release.
Because Remote Hands operates the same interface the person does, its rules are human-first — it pins the process, snapshots the user's world, and cancels the moment physical input arrives:
The person always wins. After physical input cancels a run Bonnie does not reclaim focus or move the cursor back underneath them. This is visible automation.
Where SKILL.md stops
Credit first: Agent Skills' progressive disclosure is good design — names and descriptions preloaded cheaply, the body loaded when relevant, files read on demand. As a way to give one agent deep reference material, it works.
But a SKILL.md is, structurally, prose injected into one agent's context, and each consequence of that shape lands on a mechanism this chapter already described. Six pairs, as of this writing:
Loading is one-way. Once a skill's body enters the conversation, only lossy compaction evicts it. An Ability is never "in" a conversation — removed means absent from the next snapshot. Unloading is the ordinary lifecycle, not garbage collection.
Dependencies can't be declared. A skill cannot say "I require the calendar," activate when it appears, or deactivate when it leaves — composition is the model happening to have read both. A Bonnie Skill's requirements block is typed and resolved by the runtime every turn against what's actually installed and ready.
Instructions are advisory. A skill influences the model, and the model may attend elsewhere; the ecosystem's own guidance for must-happen behavior is a different mechanism (hooks). A .bonnie package doesn't ask nicely: validators refuse it at admission, and Capability constraints hold at dispatch.
Discovery has a budget. The skill listing is capped, and least-used descriptions drop first — so the rare, high-value skill is precisely the one that goes invisible. Bonnie's roster is not prose competing for attention: routing predicates and per-turn arbitration decide, and rarity costs nothing.
Pre-approval is not restriction. A skill's tool allowances pre-approve; every tool remains callable. A Capability contract confines — effect class, permissions, limits, confirmation — and Bonnie owns it, so a package cannot vote itself power.
Portability is narrow. Personal skills live on one machine and degrade off their home path. A .bonnie package is canonical bytes: CI rebuilds sketch.bonnie from its own documentation walkthrough and asserts byte-for-byte equality with the shipped file. Portability is a test, not a claim.
None of this is an accusation — Agent Skills solve a different, narrower problem: augmenting one agent's context, on demand, with text. The claim I am making is that "what the assistant knows how to do" deserves the same architectural seriousness as "what the assistant remembers," and prose in a context window is not an architecture. It's a hint.
The framing underneath that claim — a model as a state machine whose only alphabet is language, and what follows for anything you try to configure it with — is its own essay: Linguistic State Machines. This chapter is the mechanism; that one is the derivation.
The payoff: a profile keyed by craft
There's a quiet reward for structuring capability this way. Bonnie accrues a behavioural profile of how you work — style tenets, mined from your actual documents — and keys it by Ability, not application. Your prose voice, learned in Pages, is a fact about your writing — so it's there when you write in Scrivener, which didn't exist in the system when the tenet was learned. That's the discipline / applicationExpertise split from the top of this chapter, cashing out.
And tenets are governed like evidence, not cache: breadth before belief, hysteresis before demotion, and a multi-week decay to a floor — a curve, not a cliff, because "a person does not stop writing one way on a Tuesday; they drift, and a cliff cannot see a drift."
Capability as bounded, validated, per-turn data; personalization keyed by craft; both portable. That's the upgrade.
A capability you cannot unload is not installed — it is remembered.
Footnotes
-
The word "frozen" earned a pause while editing this chapter (August 2026): freezing the world per turn is a design decision, not a law. What I'd defend is only the invariant it protects — execution never straddles two configurations — and a better mechanism that keeps that promise could replace the snapshot system, word and all. ↩