cd /news/ai-agents/your-coding-agent-needs-more-than-in… · home › topics › ai-agents › article
[ARTICLE · art-159776] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=· neutral

Your coding agent needs more than instructions

A developer proposes Capability-Oriented Development (COD), an approach that makes architectural relationships explicit so coding agents can find the owner of a shared capability, its supported options and its extension rules instead of scattering ad-hoc CSS across views. The method pairs a capability catalog derived from contracts naming owners, consumers and extension rules with optional SCIP source indexes, and ties those obligations to checks like types, tests and dependency rules. The author argues agents are over-reliant on instructions such as "ALWAYS USE EXISTING COMPONENTS" and that making the wrong change harder is more effective than asking agents to do the right thing.

by read8 min views3 publishedOct 28, 2026

[Announcer voice]

You have a design system. You have components. You have instructions explaining when to extend them.

You see a Button on a page. You tell the LLM, "Oh, this button should look like a link."

You meant, "Change the variant value of the Button component to link." But we're humans, and we don't always say it that clearly.

A human developer brings millions of years of pattern-making brain evolution to this conversation. They recognize the component, look at its options, and probably change the prop. Maybe they miss the option and create a redundant LinkButton. Not ideal.

The LLM does something much, much stupider. It adds CSS to just that page, even though the button lives in a Header. The header appears somewhere else too, so the LLM says, "Oh ok," and vomits styles into that view as well.

For the vibe coder, nothing is noticed. It works. The tests pass. The responsible [cough] software engineer discovers that the LLM has smeared concerns across the codebase. You unleash expletives at the LLM, which then scolds you for abusive language and ends the conversation.

You calm yourself down, have some tea, and come back. You add instructions. You add skills. You write “ALWAYS USE EXISTING COMPONENTS” in capital letters in AGENTS.md, because surely the problem was insufficient capitalization.

Sometimes that helps. Too often, it doesn't.

I'm not about to announce that I've solved AI alignment in a blog post. But I do think we're leaning too hard on asking agents to do the right thing, without making it hard to do the wrong thing.

We already know how to do some of this. Types reject invalid calls. Tests reject broken behavior. Dependency rules reject forbidden imports.

What's often missing is the relationship between those things: this component owns this behavior, and these consumers must keep using it. A page can look correct today while quietly acquiring its own copy of a shared rule.

Humans infer those relationships. We recognize patterns, ask colleagues, and remember why an abstraction exists. Making every relationship explicit is extra work, so we leave quite a bit unsaid.

An LLM can generate and maintain more of that machinery. That doesn't make maintenance free, or its judgment reliable. But perhaps we should spend some of its effort making the architecture explicit, instead of repeatedly explaining that no, we did not want another button implementation.

What if we let LLMs code for LLMs?

Capability-Oriented Development, or COD, or “cape coding” as the kids call it (they do not; I've just made up these terms), is an approach built around those ongoing relationships.

A capability is something the system can do: render a button, check a permission, calculate a price. COD makes its owner discoverable, describes how it can be used and extended, and connects those obligations to checks.

Let's walk through the button request.

The agent starts at the page, follows the header to the shared Button, and finds its supported variants:

<!-- Before -->
<Button variant="outline" @click="retry">Try again</Button>

<!-- After -->
<Button variant="link" @click="retry">Try again</Button>

It still performs an action. We're changing its appearance, not turning it into navigation.

The capability map needs to be reachable from the instructions an agent actually reads. COD Kit derives a catalog from the contracts that name owners, consumers and extension rules; optional SCIP indexes add source references. A beautiful inventory nobody consults is mostly a decorative file.

“But,” you say, “what if link isn't an option?”

Then the agent needs more than a list of existing capabilities. It needs the rules for extending them: inspect sibling controls, follow the design system's conventions, and add the missing option at the responsible owner if the request justifies it.

Perhaps the underlying library already supports it and our wrapper merely needs to expose it. Perhaps another control is appropriate. None of that requires inventing a page-specific styling system or a speculative abstraction for every possible future button.

The growth path is part of the contract too.

A screenshot can confirm that the button looks right. It cannot tell us whether the page copied the styling.

Our runnable Vue example tests that distinction. It temporarily changes the shared button's appearance and observes the consumer. If the consumer follows the owner, good. If it preserves its own imitation, the check fails. Sharing a theme token alone isn't enough; the example probes component-owned behavior too.

Its behavior check is ordinary JavaScript:

async function behavior() {
  assert.deepEqual(await observe(), expected());
}

Here, observe() runs the component in a browser. expected() reads the contract's structured requirements: appearance, busy state, disabled state, and activation result. The contract isn't just English asking everyone to be good.

This is targeted evidence of delegation. It doesn't magically detect every possible duplication in a repository.

Change a requirement without updating incompatible code: the build fails. Change the component so it contradicts the requirement: the build fails.

And when the shared owner changes, its consumers must still follow it. That's the ongoing obligation a copied implementation breaks.

A compatible refactor can keep the same requirements; it shouldn't force meaningless edits everywhere. Reviews must be refreshed when their relevant inputs change, but a fresh review cannot turn failed behavior into a pass.

Our Button might come from a shared UI package. The agent still needs to find its owner and extension rules, rather than declaring the component someone else’s problem and reaching for CSS.

With the built COD CLI available and provider connections configured, an application can run:

cod catalog .
cod sync .
cod connections .

These derive the local map, retrieve connected contracts through Git, and show the results. The package revision actually used stays separate from newer discovery candidates. Fetching a catalog neither upgrades the package nor executes its code. Missing access or contracts remain visible gaps.

Refresh the maps as covered code and dependencies change; native consumer tests still decide whether the implementation conforms. Finding a contract is not satisfying it.

In an existing Vue application, I tested a request to make navigation show a busy state during background refresh. The underlying library supported the option; the application wrapper didn't expose it.

The COD-guided agent found that path, exposed the option, and used it from the screens. Browser checks covered blocked activation during refresh, restored activation afterward, and keyboard/focus behavior. They exercised real components with stubbed server responses.

The checks needed scrutiny too. An early version could inspect the idle screen and mistakenly call that evidence about refresh. I fixed it to establish the refresh lifecycle independently before checking the button. Another probe exposed code that called an owner but ignored its result.

A contract earns trust by catching a plausible mistake. A green badge attached to the wrong observation earns considerably less.

I also compared fresh Codex sessions using ordinary change requests, maintenance skills, Spec Kit's spec-driven workflow, and COD. Guided conditions received the same architecture facts.

All 24 checks of current behavior passed. The difference appeared when I changed a shared error-reporting rule: one request-only implementation had copied the old rule, so the update stopped reaching it.

Across two three-request sequences per approach, only one of the two request-only sequences preserved that relationship. Both sequences did with skills, both with SDD, and both with COD. These were small comparisons, not 24 independent trials or proof that COD always wins. In later button trials, agents with strong existing guidance found the same owners as COD.

The useful result is that good guidance helped preserve reuse, and COD added executable checks of the declared relationship. I haven't established that it saves time or maintenance cost. The runnable public examples let you inspect the enforcement without needing access to the private applications.

Complete determinism is hard. Types and dependency rules can give definite answers within their scope; browser checks depend on a controlled environment, and architectural decisions still need judgment. COD is a principled approach supported by a variety of tools, not a one-and-done setup. As the system changes, you revisit the map, the contracts, and the checks—including whether they still catch the mistakes you care about.

You don't need to replace your compiler, component tests, browser tests, or dependency rules with a grand new framework. Connect them to discoverable responsibilities and check the ways those responsibilities can be bypassed. COD Kit supports this workflow; existing tools can implement the approach too.

Spec-driven development helps define what to build. COD extends that discipline into ongoing obligations between owners and consumers. A good SDD workflow may already cover much of this. The distinction matters when the next change arrives and yesterday's specification has become background reading.

Start with a recurring mistake in your own codebase. Identify the owner, explain how it may grow, reproduce a realistic bypass, and make the appropriate check required. Keep humans involved where design judgment is still necessary. More machinery is not automatically better architecture, and I revised the COD guidance and machinery several times to try to find the right balance between effectiveness and simplicity.

Like all things AI, with Capability Oriented Development, your mileage may vary, and this implementation may not be best for you! But I think the question is worth exploring: do you need your LLMs to write code a human would write? Or do you need them to write code that is self-guiding for their next session (yet still understandable by the humans)?

Let me know if this helps! And if you have suggestions for improving this system or these tools, I would love to know!

COD Kit — Capability-Oriented Development · One rule. One place to change it.

The repository includes:

cod-adopt and cod-workflow skills for Codex, plus a local Claude Code plugin. The

── more in #ai-agents 4 stories · sorted by recency
── more on @cod kit 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/your-coding-agent-ne…] indexed:0 read:8min 2026-10-28 · —