SOLID was born in object-oriented software, but its real subject was never classes. Its subject was change. Agents make that harder to hide because an agent can change its role, tools, memory, authority, model, data source, UI, and proof obligation in the same run.
SOLID for agents is not a nostalgia exercise. It is the fastest way to tell whether an agent system has real boundaries or only a convincing personality. The unit is no longer the class. The unit is the skill, the tool interface, the state contract, and the receipt another operator can inherit.
Robert C. Martin's 2020 restatement of SOLID says SRP means grouping things that change for the same reasons and separating things that change for different reasons. That is exactly the agent problem. A bad class becomes a god object. A bad agent becomes a god intern: it reads everything, calls everything, remembers vaguely, explains confidently, and leaves no replayable evidence.
The counterintuitive research finding
The agent ecosystem is not converging on raw autonomy. It is converging on bureaucracy. Skills package procedures. MCP formalizes tools, consent, schemas, roots, and sampling. Apps split transcript-visible data from component-only hydration state. Enterprise frameworks add checkpointing, human review, type-safe routing, memory, middleware, and telemetry. Connector platforms turn apps into governed action surfaces. Sandbox clouds separate execution from reasoning. Web-data tools make acquisition a bounded capability.
That is not the language of magic. It is the language of institutions.
The best context is often unloaded.
Agent Skills work because the agent sees tiny metadata first, then loads
SKILL.md, references, and scripts only when needed. Unused expertise
sitting on disk can be more useful than a giant prompt already crowding the model.
Permission is not a description.
MCP says tool descriptions and annotations should be treated cautiously. Apps SDK read-only, destructive, and open-world hints help the host frame approval, but servers still have to enforce authorization.
A handoff is a tool call wearing a social mask.
OpenAI's Agents SDK represents handoffs to other agents as tools. That makes Liskov concrete: a substitute agent is safe only if the interface, authority, output, and verifier still mean the same thing.
Memory is a dependency, not a soul.
Stateful runtimes and sessions are powerful, but every memory surface becomes a reason to change. The right question is not "does it remember?" It is "which state is allowed to affect this run?"
Receipts compete with privacy.
Traces, skills, and run logs make systems inspectable, but the same proof surface can create retention and exposure risk. Auditability is not free; the receipt needs its own scope.
The UI boundary is an architecture boundary.
Apps SDK structuredContent and content are visible to the
transcript, while _meta hydrates the component without being shown to
the model. That is dependency inversion in product form.
The new SOLID
S: one operational reason to change
Classic SRP asks whether a module has one reason to change. For agents, the sharper version is this:
An agent or skill should have one operational reason to change.
Role names are not enough. A "research agent" that can scrape the web, edit the repo, deploy the site, send email, update CRM, and rewrite memory is not single-purpose just because it has a tidy name. Its responsibilities change when sources change, when tool permissions change, when proof requirements change, when state changes, when the artifact changes, and when the rollback path changes.
A better split follows the receipt:
- Research skill: gather sources and uncertainty.
- Synthesis skill: turn evidence into claims and counterclaims.
- Build skill: change files inside a known workspace.
- Review skill: verify contracts, tests, links, and claims.
- Publish skill: push, deploy, and prove the public route.
- Receipt skill: record what changed, what passed, what failed, and who inherits it.
The design test is simple: if two users would ask for different verifiers, you probably have two responsibilities.
O: extend with skills, not prompt surgery
Open/Closed becomes obvious once skills enter the picture. Anthropic's Skills docs and
the Agent Skills specification both describe a filesystem package: metadata, a
SKILL.md, and optional scripts, references, and assets. The important part
is progressive disclosure. Metadata is cheap. Instructions load when the task triggers
them. Resources and code load only when needed.
That is OCP for agents. The core agent remains closed to random mega-prompt edits and open to new capability packages.
A prompt library is advice. A skill package is installable operational memory. It can carry a validator script, a template, a reference, a fixture, and a receipt format. It can also be audited as software, which matters because Anthropic explicitly warns that skills can contain instructions and code capable of tool misuse, data exposure, and external dependency risk.
Rule: when a workflow repeats three times, stop improving the prompt. Create a skill.
L: substitute by contract, not vibes
Liskov is often taught as inheritance trivia. Martin's restatement is more useful: a user of an interface must not be confused by an implementation of that interface. That is the entire agent-substitution problem.
You should be able to swap a hosted model for a local model, a human reviewer for an AI reviewer, a connector layer for a direct API, or a sandbox for a local shell. But only if the contract holds.
agent_contract:
input: task, allowed_sources, tool_scope
authority: read, write, delete, deploy, send
output: artifact, claim, evidence, uncertainty
verifier: command, human review, source check, browser proof
receipt: state_before, action_taken, state_after, risk
rollback: path_if_wrong
OpenAI's Agents SDK makes this concrete: agents, tools, handoffs, guardrails, sessions, tracing, MCP integration, and sandbox agents are separate primitives. Handoffs are represented to the model as tools. Guardrails run at specific points in the workflow, and tool guardrails do not automatically apply to every hosted or handoff path. That means the interface has to say where validation actually happens.
Rule: never substitute an agent by personality. Substitute by artifact contract.
I: split tools by authority
Interface Segregation becomes security design for agents. The failure mode is the tool buffet: one agent sees shell, browser, database, deploy, email, calendar, payments, files, app connectors, and cloud consoles. Then the model has to infer not only what to do, but what not to touch.
The right split is not by vendor. It is by authority:
- Read tools: search, list, fetch, inspect, summarize.
- Draft tools: propose, render, simulate, stage.
- Write tools: edit, create, update, label.
- Destructive tools: delete, overwrite, revoke, reset.
- External-action tools: send, buy, post, deploy, publish.
- Host-operation tools: shell, filesystem, sandbox, credentials.
MCP's trust language is blunt: tools are arbitrary code execution and users should understand and authorize tool use. Its roots feature is even more revealing: roots tell servers what directories are relevant, but the spec says they are informational guidance, not access control. The product lesson is uncomfortable: tool surfaces can describe boundaries, but enforcement still lives in the host, server, and verifier.
Rule: if approval would differ, the interface should differ.
D: depend on capabilities, not vendors
Dependency Inversion for agents says the mission should depend on capability contracts, not a specific model, SDK, connector, or UI host.
Bad:
Use one named model, this exact browser plugin, this exact CRM action,
and this exact host UI to update the workflow.
Better:
capabilities:
retrieve_account_context
draft_update
validate_policy
request_approval
write_final_change
emit_receipt
Then inject the adapters: OpenAI, Anthropic, local vLLM, Microsoft Agent Framework, Pydantic AI, Vercel AI SDK, Google ADK, CrewAI, Zapier MCP, Composio, E2B, Firecrawl, or a human reviewer. The provider matters, but it should not own the mission logic.
The most interesting DIP example is not a model adapter. It is Apps SDK
_meta. The component can receive hydration data hidden from the model while
transcript-visible structuredContent remains concise. The high-level
mission does not depend on every UI detail. It depends on the declared result contract.
The anti-patterns
- God agent: one agent owns research, writing, build, deploy, email, and memory.
- Mega prompt: every new capability becomes another instruction paragraph.
- Tool buffet: every integration is visible to every run.
- Memory theater: the system "remembers" but cannot replay evidence.
- Invisible authority: no one can say what the agent was allowed to do.
- Unreceipted output: the answer exists, but the proof trail does not.
- Provider lock-in by accident: business logic quietly depends on one runtime quirk.
The cure is not more prompting. The cure is smaller agents, richer skills, narrower tools, explicit state, stronger verifiers, and receipts that survive the session.
The Chopshopr pattern
Chopshopr is strongest when it treats AI work as an inspectable operating surface: prompt, model or tool boundary, artifact, source trail, verifier, receipt, and next owner. The trust-packet article already names the safe unit: intent, authority, context, constraints, tool scope, evidence, verifier, receipt, rollback, and handoff. SOLID gives that packet a design vocabulary.
A serious agent run should end like this:
solid_trust_packet:
claim: what changed or should change
responsibility: one reason this skill exists
extension_point: how to add capability without prompt edits
substitution_contract: what another agent must preserve
exposed_interfaces: tools visible to this run
dependencies: capability contracts and concrete adapters
evidence: files, links, traces, screenshots, commands
verifier: pass/fail check
rollback: what to do if wrong
next_owner: human, agent, queue, or route
Build the Agent SOLID Audit next
The smallest useful product surface is not another manifesto. It is a lab that turns a messy agent description into a scorecard and one generated trust packet.
One bad example should be enough for the first release: a god agent with shell, email, browser, CRM, deploy, and memory access. The lab should return the top three violations, the skill split, the exact tools each skill may see, and a trust packet a stranger can inspect in under a minute.
The one-minute trust test
Ask this before calling the system production-ready:
Could a stranger trust the smallest agent run in under 60 seconds because the receipt names the goal, allowed tools, state before, action taken, state after, verifier, rollback, and next owner?
If yes, the agent has architecture. If no, the agent has theater.
Sources
- Robert C. Martin on SOLID relevance
- Anthropic Agent Skills overview
- Agent Skills specification
- Model Context Protocol specification and trust guidance
- MCP roots and boundary guidance
- OpenAI Agents SDK overview
- OpenAI Agents SDK guardrails
- OpenAI Apps SDK reference
- Microsoft Agent Framework overview
- Pydantic AI overview
- Vercel AI SDK DevTools
- Zapier MCP
- Composio documentation
- E2B documentation
- Firecrawl overview
- Chopshopr trust-packet field note
- Chopshopr skill-development field note