Architecture for AI-Driven Development
An agent struggles with a tangled system just as much as a person does. Here's how repo structure, documentation, naming conventions, and autonomy boundaries determine how much an AI agent can actually help.
Why architecture is now part of the AI workflow, not just the human one
Good architecture has always made a human's job easier: a clear structure, explicit module boundaries, predictable conventions. An AI agent reads the same code and works under the same rules, but with one major difference: it doesn't have the years of accumulated context a human builds up just from working in this exact codebase for a long time.
That means architectural decisions that used to be a matter of taste, or that new hires absorbed gradually over months on the job, now directly affect how well an agent can navigate the system starting from its very first session. A poorly structured repo doesn't stop working, but it gets noticeably more expensive and slower to work with using AI, because the agent has to re-figure out, every single time, what a human could just hold in their head.
A telling observation: a lot of practices that were considered "good form" but often got sacrificed for speed (explicit documentation of decisions, modularity instead of convenient but tangled shortcuts, consistent naming conventions) have suddenly started paying off in measurable numbers: in the time an agent spends exploring context, and in the token cost of that exploration. What used to be a matter of engineering culture and personal discipline now has a direct, easily calculated dollar value.
This doesn't mean designing architecture specifically for AI agent convenience at the expense of everything else. Good architecture for a human is almost always good architecture for an agent too, because both need the same thing: clarity, predictability, and no hidden connections. The difference is that the cost of violating these principles now shows up faster and more visibly, because an agent runs into it fresh every session, rather than gradually, the way a human simply learns a project's quirks over time.
It helps to look at this through a simple metaphor: architecture is the environment both the human and the agent work in, and the quality of that environment determines how much effort goes into the actual work versus fighting the environment around it. A poorly lit, awkwardly laid-out workshop slows down any craftsperson regardless of skill, and an agent is no different in this respect: it too spends part of its "effort" (context window tokens and iteration count) just figuring out where things are and how they work, before it can even start on the actual task.
Worth stating the scope of these principles upfront. A small personal project run by one person and a commercial system with a team of fifteen developers need different degrees of formalization for architectural decisions: what's excessive bureaucracy for the first case is a necessary minimum for the second, without which an agent working across different sessions from different people starts proposing mutually contradictory solutions. What follows mostly covers principles that apply at both scales, with explicit notes wherever formalization only makes sense at a particular team or system size.
What follows: the specific architectural decisions that determine the quality of working with AI agents: repo structure, documentation, naming conventions, autonomy boundaries in production, and how to avoid a new kind of technical debt specific to agentic development.
How to structure a repo for effective AI agent work
Repo structure determines how much context an agent has to rebuild at the start of every session before it can even start on a task.
Practical principles that cut this overhead. A clear boundary between sub-projects in a monorepo, rather than a fuzzy structure where it's unclear which code belongs to which part of the system. One top-level instructions file (CLAUDE.md, AGENTS.md, or similar) that the agent reads automatically, rather than a scatter of disconnected READMEs spread across subfolders with no single entry point. And predictable placement of similar entities: if request handlers live in one directory with self-explanatory file names, the agent doesn't need to search the entire project every time to find the right file.
A telling example from this exact site: the backend is organized around "one file per resource" inside handlers/, a separate file for the blog, a separate one for projects, a separate one for settings. That's not an original architectural decision on its own, but it's exactly the predictability of that structure that lets an agent almost always guess which file to look in for a given task's logic, just from the entity's name, with no need to re-explore the structure.
A similar principle applies to database migrations. In this same project, the schema gets rebuilt idempotently on every app startup, rather than through a sequence of separate migration files, as is common in many other projects. That's a deliberate departure from the common pattern, and without an explicit explanation in the documentation, an agent will most likely try to "fix" it toward the more familiar approach, assuming it's an oversight rather than a deliberate architectural decision. Which points to a general rule: if a project deliberately departs from a common pattern, that departure needs to be explicitly documented, because an agent, like a new developer, defaults to expecting the common variant.
Another practical technique for repo structure: keep config files and secrets files explicitly separated from the rest of the code, not just for security reasons (covered separately in the piece on AI assistants), but because a clean split between "code" and "configuration" lowers the risk that an agent confuses one for the other during an autonomous edit. A project where secrets, environment settings, and business logic all sit mixed together in one directory structurally invites exactly this kind of mistake.
Directory depth deserves its own note. A structure where you have to descend seven or eight levels of nesting before reaching an actual code file loads down an agent's context almost as much as bloated documentation does: every level of the path is one more detail the model has to hold onto while constructing the full path to a file, and on deep structures, stray path mistakes (an extra or missing level) show up noticeably more often than on flat ones. A reasonable compromise: group by domain rather than by a formal taxonomy like "models / controllers / utilities" running through the entire system, which gets you a shorter, more predictable path to any given task.
Modular architecture: why small modules work better with AI
Small, loosely coupled modules make an agent's job easier for the same reason they make a human's job easier: the task can get solved while holding only the relevant part of the system in context, not the entire project at once.
The difference from human work is a matter of scale. A human can hold an informal map of the connections between a project's modules in their head for years, even if the architecture itself isn't perfect. An agent doesn't have that accumulated intuition, and every hidden dependency between formally independent modules raises the risk that an edit in one spot quietly breaks something else the agent didn't know about and couldn't have known about without an explicit note.
A practical rule: if a task requires explicitly explaining to the agent that module A is connected to module B in some non-obvious way, that's a signal the architecture itself carries hidden coupling, one worth either making explicit in the documentation or removing through a refactor. AI-driven development doesn't create a new need for modularity. It makes the always-existing cost of poor modularity far more visible and far more frequent.
A concrete rule of thumb for module size that holds up in practice: if explaining a module's purpose to an agent fits into two or three sentences without an "and" every other word, the module is probably focused enough. If the explanation turns into a long list of unrelated responsibilities, that usually means the module is doing too much at once, and modules like that are the most common source of unexpected side effects during autonomous edits, because an agent touching one part of the module doesn't always realize it's also touching other parts formally unrelated to the task.
There's also an opposite mistake that's easy to fall into once you get excited about small modules: excessive splitting, where a simple logical operation is broken across five tiny files chained together by imports. Formally each file is small and focused, but to understand the full execution path of one operation, the agent has to open all five files in sequence and hold the connections between them in context, which in practice creates the same load as one big module, just spread across the filesystem. A healthier target is "a small but coherent unit of responsibility" instead of just "a small file," even if implementing it takes a hundred and fifty lines in one place.
Nesting depth of abstractions deserves its own note too. Too many intermediate layers between the entry point and the actual business logic forces an agent (and a human) to walk a long chain of calls before reaching the substance, and in long chains the odds of the model missing one of the intermediate steps go up sharply. A reasonably flat structure, where the path from request to result can be traced in three or four steps rather than ten, cuts that risk down simply by reducing the volume of context that needs to be held at once.
Documentation as code: how AI uses project context
Documentation that used to get read rarely and go stale quickly now has a new practical role: it's the primary source of context an agent loads at the start of every session, and the quality of that source directly determines the quality of the result.
The difference between documentation for humans and documentation for an agent is a matter of priorities. Documentation for a human can afford general descriptions, because a human can ask a colleague a follow-up question or just poke around and figure it out. Documentation for an agent needs to contain exactly the details that aren't obvious from the code itself: why a specific data structure was chosen, what constraints aren't reflected in the types, which commands to use for specific operations, not just a general description of "what" the system does.
A practice that reduces the risk of going stale: keep documentation for the agent right next to the code it describes, not in a separate wiki disconnected from the repo. A file at the project root, edited in the same pull request as the code, goes stale noticeably slower than documentation living in a separate system the team physically never gets around to updating with every change.
A useful practice for teams: fold updating the agent's documentation into the definition of done for a task, the same way test updates already are. A pull request that changes architecturally significant behavior but doesn't touch the agent's documentation can be formally complete from a code standpoint and completely stale from the standpoint of the context the next session working on that part of the system will receive.
There's an opposite extreme worth explicitly avoiding too: overly detailed documentation trying to describe absolutely everything in the project. A file like that becomes hard to keep current on its own, and an agent reading an excessively long instruction set burns part of its context window on details irrelevant to the current task. A reasonable target: document what can't be reliably inferred from the code itself, and don't duplicate what's already obvious from the file structure and its contents.
CLAUDE.md, AGENTS.md, and conventions for AI agents: standards
Project instruction files are gradually turning into an industry standard on par with .gitignore or README.md: the specific filename depends on the tool, but the practice itself of explicitly describing context for an agent is becoming common.
A working structure for a file like this, one that scales from a small project to a large system: a top-level architecture overview (what parts the system consists of and what each is responsible for), commands for common operations (build, test, run locally), explicit project conventions that don't follow from the code itself, and a list of things the agent shouldn't do without explicit permission. For a monorepo with several subsystems, it makes sense to have a separate section for each part rather than one general section covering everything at once, so a task in one subsystem doesn't drag in irrelevant context from the others.
An important organizational point that often gets missed: the agent instructions file should go through the same review process as code, not get updated arbitrarily by anyone without coordination. A stale or contradictory instruction is worse than a missing one, because it steers the agent in the wrong direction with the same confidence a correct instruction steers it in the right one.
For teams with multiple developers, the question of personal, undeclared conventions deserves extra attention. A repo-level instruction file only works when it reflects what the team has actually agreed on, not the personal preferences of whoever originally wrote it. Periodically reviewing the file together (say, once a quarter, or whenever the project grows noticeably) helps keep it current and keeps the team's buy-in on the rules it locks in, instead of letting it turn into an artifact that only its original author actually follows.
Naming conventions for AI-readable code
Good naming has long been a marker of quality code, but with AI agents it's picked up an additional, quite measurable value: a meaningful function or variable name is context the agent gets for free, without having to read the entire implementation.
A function named calculateShippingCostForRegion tells an agent its purpose instantly. A function named calc or process forces it to either read the entire implementation or build assumptions that might turn out to be wrong. The difference is especially visible in large codebases, where an agent physically can't hold every implementation in context at once and has to lean on names as a compact summary of behavior.
This isn't a call for long names for the sake of length: an excessively wordy name hurts readability just as much as an overly short one. A practical target: a name should unambiguously answer "what does this do" with no need to look inside, and that same criterion works equally well for a human joining the project a year from now and for an agent reading the code for the first time this session.
A specific category of naming problem that's unique to agentic development: inconsistency between similar entities, arising because different sessions with the agent generated code independently of each other. One endpoint names a parameter userId, another in the same project calls it user_id, a third just uses id with no qualifier. Each of these choices might be reasonable on its own, but together they create confusion that forces both the agent and a human to double-check the exact parameter name every time instead of relying on developed intuition. A periodic check of naming consistency across the whole project, not just within a single task, catches divergences like this before they get permanently locked in.
Another practical detail: abbreviations that feel self-evident to a human who's worked in the domain for a long time are ambiguous to an agent with no extra context. A variable named qty is almost certainly a quantity, but crf or dlt with no explicit explanation in the documentation forces an agent to either guess from usage context or make up a meaning that might not match the original intent. The practical rule is simple: if an abbreviation isn't part of a common industry set (id, url, api, and similar), either spell out the full word or explicitly document what it stands for next to its first use.
Designing APIs that are readable by both humans and AI
Internal and external APIs suffer from the same problem of implicit contracts: behavior that isn't documented and doesn't follow directly from the signature regularly leads an agent (like a new developer) to make wrong assumptions about how to use it.
Practices that reduce this uncertainty. Explicit types instead of vague generic structures: a specific response type with named fields communicates more than an arbitrary-shape dictionary that has to be reverse-engineered from usage examples. Explicit errors instead of silent failures: a function that explicitly returns a described error is easier for an agent to understand than one that silently returns an empty value on any problem. And consistency between similar endpoints: if one resource supports pagination through a page parameter and another through offset with no clear reason for the difference, an agent (and a human) will regularly mix the two patterns up.
Another architectural principle worth applying deliberately: an API should explicitly describe not just the success case, but every expected error state as part of the contract, not something that only comes out from reading the implementation. If a public API returns different error codes in different situations, but that's nowhere explicitly described (not in the types, not in the documentation), an agent implementing client code against that API is forced to either guess or read the server implementation, if it even has access to it. An explicit, documented error contract removes this uncertainty for both sides of the integration.
A useful practice when designing a new API: ask the agent to try describing how it would use the API before the implementation is even finished. If the agent asks a lot of clarifying questions about what happens in specific edge cases, that's a good sign the contract itself isn't explicit enough, and it's worth refining ahead of time rather than after client logic has already been built on top of it.
API versioning deserves its own attention in this same context. Changing an existing endpoint with no versioning forces an agent, on every edit, to re-figure out which clients depend on the old behavior and whether the new one will break something for them. An explicit version in the path or request header removes this uncertainty: the agent can safely change the new version's behavior knowing old clients keep getting the previous contract, with no need to manually trace every usage of the endpoint across the codebase just to assess the risk of a change.
Test coverage as insurance for AI-driven development
The role of tests in agentic development is covered in detail in the piece on AI assistants. Here it's worth covering the architectural side of the question: test coverage isn't just insurance against regressions, it's the only objective way to check that an agent's autonomous edit didn't violate an assumption the agent itself didn't know about.
The architectural consequence of this principle: critical, easily violated invariants of the system (uniqueness of identifiers, consistency of related data, ordering of operations where it matters) are worth protecting with explicit tests before an agent with broad autonomy starts actively working on the project, not after the first incident. Test coverage functions as an architectural boundary in this sense: what's covered by tests can safely be trusted to an autonomous edit. What isn't covered needs a more careful, step-by-step approach, no matter how trivial the task looks.
A practical consequence for planning work: before expanding an agent's autonomy to a new part of the system, it makes sense to first invest time specifically in test coverage for that part, rather than immediately handing over a task with broad permissions on top of unverified code. This flips the usual order of "feature first, tests later if there's time": for agentic development, tests are more valuable written ahead of time, because they're what determines how much autonomy can safely be granted in the first place.
It's worth separately distinguishing tests that check behavior (what the system does given certain input) from tests that check implementation (that a specific function gets called in a specific way). The first kind stays useful through refactoring, because it doesn't depend on the code's internal structure. The second kind breaks on any implementation change, even when the system's behavior hasn't changed, and creates a false sense of regression where there isn't one. For agentic development, where refactoring happens more often and by an agent rather than only by a human, behavior tests turn out to be a substantially more reliable guide than implementation tests.
A practical question worth keeping in mind when building test coverage specifically for agentic development: what happens if the agent writes a test that passes but checks the wrong thing. That scenario comes up in practice more often than it sounds like it should: an agent asked to write a test for a specific function sometimes writes a test tailored to the function's current (possibly buggy) behavior, instead of one that checks the expected behavior. A practical safeguard: periodically, for critical modules, have a human explicitly verify not just that the test passes, but that it would actually fail on a plausible implementation bug: temporarily introduce that bug and confirm the test catches it.
Feature flags and AI-driven development: reducing risk
Feature flags, long used for gradual rollouts, pick up extra value in the context of working with AI agents: they give a way to bring agent-generated code into production gradually and reversibly, without relying on pre-merge review having caught absolutely everything.
A practical pattern: significant changes made with high agent autonomy are worth shipping behind a flag, turned on first for a small slice of traffic or for internal testing, and only later expanded to everyone. This turns a potential bug into a quickly detectable, easily reversible incident instead of a full-blown production outage that has to be rolled back through a full release. This approach is especially justified for tasks where the agent was given more autonomy than usual, precisely because the independent check wasn't as thorough as it would be for critical parts of the system.
A practical detail that often gets forgotten: the feature-flag mechanism itself also needs architectural discipline, or it turns into an extra source of complexity instead of a way to reduce risk. Flags nobody removes after a change fully rolls out pile up in the code and create a combinatorial explosion of system states that almost nobody explicitly tests. A sensible discipline: every flag needs an explicit owner and a lifespan, after which the flag either gets removed along with the code branch for the disabled state, or deliberately stays as a permanent toggle, rather than a temporary precaution forgotten forever.
Microservices vs. monolith in the age of AI agents
The perennial architecture debate between microservices and a monolith picks up a new practical argument in the context of agentic development, though it doesn't override the other, already-known considerations.
A monolith with good internal modularity gives an agent the advantage of full context: the entire system is available to read and analyze within one repo, and the agent can trace the data path from entry point to the end without switching between different codebases. A microservices architecture gives the advantage of isolation: an agent working on one service physically can't accidentally touch another service's code, because it's simply not in its working context.
The practical takeaway doesn't favor one approach: the choice between a monolith and microservices should still be driven by the same considerations as before (team scale, independent-deploy requirements, actual organizational structure), not by convenience for AI agents as such. But worth keeping in mind: if a monolith is chosen, the internal modularity covered above matters especially, because it's what compensates for the lack of physical isolation between parts of the system.
There's also a middle ground that often gets underrated: a modular monolith with clear internal boundaries enforced at the language level (separate packages or modules with an explicitly limited public interface), not just at the level of agreements between developers. A structure like this gives an agent the same isolation advantage as microservices (it can't accidentally touch another module's internals if that's restricted at the compiler or language module-system level) without the operational overhead of a full microservices architecture: network calls, distributed monitoring, cross-service version coordination. For small and mid-sized projects, this often turns out to be a sensible compromise between the two extremes.
AI-driven development and technical debt: how not to accumulate it faster
The kind of technical debt specific to AI-written code is covered in detail in the general piece on AI for developers. Here it's worth covering the architectural prevention measures that operate at the level of project structure rather than a single task.
A periodic architecture audit specifically targeting this kind of debt: a targeted search for duplicate implementations of the same logic, not a general correctness review, arising because the agent solved a similar task fresh in different sessions instead of reusing existing code. An explicit, maintained map of the main modules and their purpose in the project documentation, letting you quickly check before starting a new task whether a solution for a similar problem already exists. And a regular review of the agent's own instructions, because accumulated contradictory or stale guidance in CLAUDE.md over time creates architectural debt not in the code, but in the context the agent itself receives.
A specific variety of this debt unique to agentic development: the accumulation of "almost right" solutions, each acceptable on its own but together creating an inconsistency that noticeably lowers the system's predictability. One error handler is implemented through explicit return codes, another through exceptions, a third through a combination of both, because each was written in a separate session with no cross-check against the others. Each solution works on its own. Together they turn a simple task like "handle this error the same way it's handled everywhere else in the project" into a task that first requires figuring out what "everywhere else" even means, a question that never used to exist because the person writing all the code themselves intuitively held a single style in their head.
A practical prevention measure: at some regular interval, or once a noticeable volume of changes has accumulated, rather than after every individual task, run a targeted search across the project for exactly this kind of divergence in approaches to routine tasks: error handling, input validation, logging. Catching and unifying it early costs noticeably less than trying to clean things up after several different approaches have already taken deep root in different parts of the system.
Observability: tracking what the agent actually did
System observability (logs, metrics, tracing) has traditionally existed for diagnosing production problems. In the context of agentic development it picks up an extra function: the ability to trace exactly what the agent changed and how that affected the system's behavior, separately from general code changes.
A practice that pays off: tag significant changes made with high agent autonomy with explicit markers in the logging or tracing system, so that when an anomaly shows up in production, it can be quickly matched to a specific change instead of manually combing through all recent code. This doesn't need any special tooling beyond the existing practice of good logging, but it does need deliberate discipline: explicitly marking which changes went through with more autonomy and correspondingly deserve closer observation in the period right after deploy.
A useful practical pattern: temporarily elevated logging around code recently changed with high autonomy, which drops back to the normal level after a set period post-deploy if no anomalies show up. This gives more signal exactly when the risk of unexpected behavior is highest, without creating a permanent extra load on the logging system once a change has proven itself stable in practice.
Another aspect of observability specific to agentic development: tracking not just the system's behavior in production, but the agent's own working process, if the tool allows it. A saved record of which files the agent read and changed while carrying out a specific task turns into a useful artifact for a later post-mortem if something goes wrong: there's no need to guess what happened, just look at the recorded trail of actions.
It's also worth tracking metrics about the process of working with the agent itself, separately from system metrics: how many editing iterations a task took, how many times the agent came back to a file it had already changed within one session, how often a proposed solution got rejected in review. These numbers don't replace normal production monitoring, but over time they build a picture of which types of tasks the agent handles confidently on the first try and which systematically need several iterations or direct human intervention, useful to know ahead of time when planning the next task of a similar type.
Building CI/CD for a team where some commits come from AI
A continuous integration pipeline built purely around human commit pace starts behaving differently once a significant share of changes comes from an agent capable of generating pull requests noticeably faster than a person.
Practical adjustments worth making. Stricter automated checks before merge, because the volume of code passing through the pipeline grows while human attention to each individual pull request doesn't grow proportionally. An explicit split in levels of automatic approval: changes with a low cost of error (documentation, small refactors with full test coverage) can go through a lighter process than changes to critical parts of the system, regardless of whether a human or an agent made them. And separately monitoring merge speed as a metric: if pull requests from the agent systematically wait longer for review than ones from humans, because reviewers treat them more warily, that's worth either explicitly adopting as policy or deliberately fixing.
It's also worth revisiting who gets notified about new pull requests and how. If the volume of changes has grown noticeably with the adoption of agentic development while the number of reviewers has stayed the same, it helps to introduce prioritization: changes touching critical areas (authorization, payments, data migrations) should stand out and get assigned for review first, rather than drowning in the general stream alongside minor documentation edits. A simple risk-category label on pull requests, synced with the autonomy levels from the relevant section of CLAUDE.md, solves this without complex extra infrastructure.
The speed of the pipeline itself deserves a separate mention. While the build and tests ran in a few minutes and a human's pull request showed up once an hour, run duration barely affected the team's overall pace. Once an agent can prepare several pull requests in that same window, a slow pipeline turns into a bottleneck that limits the whole team's throughput more than the speed of the development itself does. That makes investing in test parallelization and build dependency caching noticeably more worthwhile than it was at a purely human commit pace.
Boundaries of AI agent autonomy in production systems
There's no universal answer to where an agent's reasonable autonomy ends, but there is an architectural principle that helps draw that line deliberately rather than by gut feeling.
The reversibility principle: the easier it is to undo the consequences of a change, the higher the autonomy it's reasonable to give an agent. A change that can be undone in one action with no lingering effects (a small refactor, a documentation update, test generation) can afford high autonomy. A change that touches already-stored data, external integrations, or irreversible operations (charging funds, sending user notifications, a data schema change with no rollback path) needs minimal autonomy no matter how trivial the code edit itself looks.
A practical mechanism that implements this principle at the architecture level, not just the process level: an explicit split of access levels for the agent, synced with this same reversibility criterion. Direct access to the production database shouldn't be available to the agent without explicit, one-time permission in a specific session, even if autonomy is otherwise high, simply because the cost of a mistake in this specific area is fundamentally higher than in most other tasks.
It's worth explicitly stating the boundary between code-level autonomy and infrastructure-level autonomy, because they're easy to conflate when framing access rules. An agent allowed to independently edit order-processing business logic doesn't necessarily need the same right to change a production server's configuration or cloud resource permissions: these are fundamentally different risk categories, and permission for one shouldn't silently imply permission for the other. An explicit, separate list of permissions for each category (code changes, infrastructure changes, access to secrets, access to production data) removes the need to redecide this boundary every time, in the moment, under the pressure of an urgent task.
A case study: refactoring architecture for AI agents
When I first started actively working with Claude Code on this site, the project structure was organized the way I'm used to structuring code for myself: convenient, but with no explicit explanation of why anything was set up the way it was. In the first few weeks, the agent regularly proposed architectural decisions that technically worked but didn't match patterns already established elsewhere in the project, simply because those patterns were never written down anywhere.
The turning point came when I spent one evening explicitly describing the structure of every part of the project in CLAUDE.md: not in general terms, but as a concrete table of directories with descriptions and ports, a list of commands for each part, and explicit notes like "migrations are written idempotently through INSERT OR IGNORE, not as separate files." After that, the quality of the agent's suggestions went up noticeably, not because the model got smarter, but because it no longer had to guess at context that used to exist only in my head.
A practical takeaway for myself: architectural decisions that feel self-evident because you made them yourself are only self-evident to you. Explicitly locking these decisions into documentation the agent reads pays off almost immediately, not through some abstract "time savings down the road."
Since then I've picked up a habit that seemed excessive at first and turned out in practice to be one of the most worthwhile ones: every time I notice I'm explaining something to the agent in a chat that's clearly not a one-off detail of the current task but a general project rule, I stop and move that explanation straight into CLAUDE.md, instead of just continuing with the explanation already given in the chat. It takes a minute or two, but a rule locked into the file never needs re-explaining in the next session, while a rule that only lives in the history of one specific conversation gets forgotten along with that conversation and only resurfaces the next time the agent trips over the same thing again.
Where to go from here
Architecture is only one part of the bigger picture of how AI is changing engineering work overall. AI for Developers: How AI Is Changing Software Engineering covers that full picture, including the role, hiring, technical debt, and the other processes that have changed.
If you're specifically interested in the day-to-day practice of working with a given agent (setup, CLAUDE.md, review, autonomy boundaries at the level of a single task rather than the whole architecture), AI Coding Assistants in Practice covers that in detail, with personal experience included.
Takeaways
- Architectural decisions that used to be a matter of convenience, or that new hires absorbed gradually, now directly determine how effectively an AI agent can work with a project starting from session one.
- Documentation for an agent (CLAUDE.md, AGENTS.md, or similar) needs concrete, actionable detail and has to update at the same pace as the code, not live separately from it.
- The reversibility principle is a working criterion for setting agent autonomy boundaries: the easier the consequences are to undo, the more autonomy it's reasonable to grant.
- Architectural decisions that are self-evident to whoever made them aren't self-evident to a new team member or to an agent. Explicitly locking these decisions in isn't bureaucracy, it's a direct investment in the quality of the result.
Comments
No comments yet. Be the first.