Nobody installs the speed limit.
You can add a GPS to your car, parking sensors, a backup camera, that thing that beeps when someone's in your blind spot. Those are capabilities: the car does something it couldn't do before, and each one matters exactly when you need it. Nobody turns on the backup camera to drive down a highway.
Seatbelts and speed limits don't work that way. They aren't capabilities, they're constraints — they don't give you power, they take away options. And the difference becomes obvious the moment you imagine the alternative:
A seatbelt that fastens when you ask for safety isn't a seatbelt. It's a well-meaning ornament.
I kept that distinction because it explains a discomfort I couldn't name.
Skills, and the verb holding them up
There's an open format called Agent Skills, created by Anthropic and adopted by around forty AI coding tools. The idea is good and I'm a fan: a skill is a folder with an instructions file, plus optional references and scripts. The agent reads only the name and description of each skill at startup, and loads the full contents when the task matches that description.
It's well-designed context economy — an agent can have a hundred specialities on hand without carrying a hundred manuals at all times.
Notice the verb holding the mechanism up: matches.
That works perfectly for capabilities. "How to generate a PDF", "how to write an integration test", "how to format a deck". These answer how do I do X, and they only need to exist while someone is doing X.
The second kind of knowledge
But there's a second kind of knowledge we've been packaging in the same format without noticing it's a different animal. The question it answers isn't how do I do X. It's what may I never do, whatever X turns out to be.
Accessibility is like that. So is security. So is data protection. They aren't abilities the agent reaches for when the subject comes up; they're conditions that hold before the subject exists.
And the problem with treating them as capabilities is arithmetic, not philosophical: if the rule only loads when someone asks for accessibility, it arrives after the interface is built.
Accessibility that has to be asked for is already late. That's the same old audit, now with a markdown file in the middle.
This isn't a comfortable desk hypothesis. The WebAIM Million analyses a million home pages every year, and in 2026 it recorded the first regression in six years: 95.9% with detectable WCAG failures, at the exact moment AI agents began writing much of the world's interface code.
The models learned from the web that exists, and the web that exists is inaccessible. Their statistical default isn't neutral; it has a direction, and the direction is downhill. Against a slope like that, arriving at the right moment isn't an implementation detail. It's the whole thing.
The convergence, and the one place it breaks
I've spent the last few months building an open-source project called A11Y.md that does exactly that: a context file that injects accessibility rules into the agent before the first line of code.
fecarrico
/
A11Y.md
A context system for building accessible software by default — for developers and AI, with enforceable rules aligned to WCAG.
🇧🇷 Read in Portuguese: ./README.pt-BR.md
Project A11Y.md
The Persistent Context System for Accessibility
📖 Read the Official Wiki | 🌐 Official Website | 📝 Read the Manifesto (Substack)
A11Y.md is not a guideline. It is an accessibility validation protocol and a persistent context architecture for developing accessible software with AI. It is designed to integrate with AI agent systems (Cursor, Claude, Copilot) to ensure certifiable compliance from genesis.
We treat .gitignore, eslint, and CLAUDE.md as canonical truths in our repositories. But why isn't accessibility canonical? A11Y.md translates accessibility rules into a portable governance layer: a platform-agnostic normative core (POUR, compliance profiles, severity, governance) with mature web references and a native translation layer (iOS, Android, React Native, Flutter). Instead of generic coding advice, it forces any coding agent to strictly adhere to WCAG 2.2 AA and ADA standards from the very first line of generated UI code.
⚡ Core
…When I finally sat down with the Agent Skills specification, I got a slightly funny shock — the architecture I'd designed was the same one, down to the folder names. References loaded on demand, instructions at the root, scripts alongside. Independent convergence, which is usually the best news a project can get: it means the design wasn't stubbornness, it was the answer the problem was asking for.
And that's when the discomfort came into focus. My project fits the format entirely, except on one point: it can't wait for the task to match. It has to be there while the agent still doesn't know what it's about to build, because that's precisely where the wrong decision gets made — the div that became a button, the input with no label, the modal that traps the keyboard.
None of those come from a task called "accessibility". They all come from a task called "build a signup form".
The ecosystem already knows. It just hasn't named it.
Here's the part I didn't expect to find when I read the specs closely. Every extension the clients have added moves activation in the restrictive direction — never the permanent one:
| Client | Field they added | What it does |
|---|---|---|
| Cursor | disable-model-invocation |
runs only when you type its name |
| Claude Code | disable-model-invocation |
same |
| Claude Code | paths |
narrows activation to matching files |
| The spec itself | six fields, none of them | keeps a skill loaded |
Nobody added the reverse, because the reverse isn't a skill.
The prettiest proof is Cursor's migration tool, which converts old rules into the new format. It converts the dynamic ones — the rules that apply in certain situations. And it refuses to convert the ones marked always-apply, because those, in its own documentation's words:
retain explicit triggering conditions that differ from skill behavior
So always-on context does exist. It just lives outside the portable format, in each tool's proprietary layer — the rule files you have to rewrite for every client you support. Which means today's authors choose between:
- Portability — one skill, forty tools, one install.
- Guaranteed presence — one rule file per client, N times over.
Constraints are precisely the case where that trade-off hurts most.
Two words where we have one
| Capability skills | Constraint skills | |
|---|---|---|
| Answer | how do I do X | what may I never do |
| Activate | by subject | across a whole domain |
| How many | many, the more the better | few, or they stop being constraints |
| Failure mode | loads when it isn't needed | doesn't load when it is |
A capability that stays quiet when nobody calls it is working correctly. A constraint that stays quiet is broken — and looks identical from the outside.
What you can do today
The good news is the format handles both. What doesn't handle both is the mental model of activation. And there's a practical workaround that fits in one line: write your constraint skill's description by domain, never by desire.
# By desire — guarantees absence at the moment that matters
description: Use when the user asks about accessibility.
# By domain — the rule exists before anyone thinks to ask
description: Use whenever creating or modifying any UI, component,
or front-end code.
Change one sentence, change when the rule exists. It's a patch, and a good one — but still a patch on a model that assumes everything we package is an ability.
Where this goes
I'm not proposing a new standard, and I'm not complaining about the one we have. I adopted the format, it's good, and the industry just converged around it — Vercel, Amazon, Microsoft, OpenAI, Cursor and Google closed a packaging layer on top of it days ago.
When a space consolidates like that, arguing about vocabulary stops being pedantry and becomes infrastructure: the difference between "install the seatbelt when you want safety" and "the seatbelt comes fastened" is a design decision someone makes once and everyone inherits.
I took the question to the spec repository, where it belongs — discussion #484, if you'd like to argue with me there.
So, for the people building agents and the people writing specs: when the thing being packaged is a prohibition rather than an ability, is loading it on demand still the right call — or are we applying context economy exactly where it costs the most?
In the meantime, go check your skills' descriptions. That one line nobody reads is what decides whether the rule shows up before or after the damage.
Top comments (0)