<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Diogo Soares</title>
    <description>The latest articles on DEV Community by Diogo Soares (@soaresdiogo).</description>
    <link>https://dev.to/soaresdiogo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2746528%2F0d4de419-58e1-4947-9f07-71dba2d61114.jpeg</url>
      <title>DEV Community: Diogo Soares</title>
      <link>https://dev.to/soaresdiogo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/soaresdiogo"/>
    <language>en</language>
    <item>
      <title>Spec Before Code: How OpenSpec Keeps AI Coding Agents Building the Right Thing</title>
      <dc:creator>Diogo Soares</dc:creator>
      <pubDate>Fri, 16 Oct 2026 16:02:42 +0000</pubDate>
      <link>https://dev.to/soaresdiogo/spec-before-code-how-openspec-keeps-ai-coding-agents-building-the-right-thing-3hee</link>
      <guid>https://dev.to/soaresdiogo/spec-before-code-how-openspec-keeps-ai-coding-agents-building-the-right-thing-3hee</guid>
      <description>&lt;p&gt;Over the past few months I've changed a lot about how I work with coding agents, and one of the tools that made the biggest difference was &lt;a href="https://openspec.dev" rel="noopener noreferrer"&gt;OpenSpec&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The problem it solves is simple. When you ask an AI for something straight in the chat, &lt;strong&gt;the requirement only exists in that conversation&lt;/strong&gt;. The agent reads it its own way, and you often find out it misunderstood after 400 lines of code. Close the session and the context is gone with it.&lt;/p&gt;

&lt;p&gt;OpenSpec flips the order: &lt;strong&gt;before any code gets written, you and the agent agree on what will be built, in writing, inside the repository.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This post covers how OpenSpec is organized, what the workflow looks like with a concrete example, when it's worth the extra step, a weakness in the verification step that came up in a great discussion on LinkedIn, and how it relates to ADRs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What OpenSpec is
&lt;/h2&gt;

&lt;p&gt;OpenSpec is an open source (MIT), lightweight framework for spec-driven development with AI coding assistants. It works with Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode and 30+ other tools, through slash commands the agent understands.&lt;/p&gt;

&lt;p&gt;It isn't a new IDE or a platform you have to move to. It's a folder of Markdown files in your repository, a small CLI, and a set of instructions for your agent.&lt;/p&gt;

&lt;p&gt;Installing it takes two commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @fission-ai/openspec@latest
&lt;span class="nb"&gt;cd &lt;/span&gt;your-project
openspec init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;openspec init&lt;/code&gt; asks which tools you use and installs the matching commands and instructions for each of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it's organized
&lt;/h2&gt;

&lt;p&gt;Everything lives in an &lt;code&gt;openspec/&lt;/code&gt; folder, split in two:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openspec/
├── specs/                  # Source of truth: how the system behaves today
│   ├── auth/
│   │   └── spec.md
│   └── payments/
│       └── spec.md
└── changes/                # Proposed modifications, one folder each
    ├── add-password-reset/
    │   ├── proposal.md     # Why and what
    │   ├── design.md       # How (technical approach)
    │   ├── tasks.md        # Implementation checklist
    │   └── specs/
    │       └── auth/
    │           └── spec.md # Delta: what changes in auth
    └── archive/            # Finished changes, kept for history
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;specs/&lt;/code&gt;&lt;/strong&gt; describes how the system currently behaves, organized by domain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;changes/&lt;/code&gt;&lt;/strong&gt; holds proposed modifications. Each change is a self-contained folder, so two changes can be in progress at the same time without stepping on each other.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key idea is the &lt;strong&gt;delta spec&lt;/strong&gt;. A change doesn't restate the whole spec. It only describes what is being added, modified or removed. That makes OpenSpec work well on existing codebases, which is where most of our work actually happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  The workflow
&lt;/h2&gt;

&lt;p&gt;In practice, the flow looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Explore&lt;/strong&gt; (&lt;code&gt;/opsx:explore&lt;/code&gt;): the agent reads the codebase and helps you understand the problem and the options. No code, no commitment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Propose&lt;/strong&gt; (&lt;code&gt;/opsx:propose &amp;lt;name&amp;gt;&lt;/code&gt;): it drafts the change folder: proposal, delta specs, design and tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You review it.&lt;/strong&gt; This is the most important step. Fixing a paragraph is far cheaper than fixing a pull request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apply&lt;/strong&gt; (&lt;code&gt;/opsx:apply&lt;/code&gt;): the agent implements the tasks, checking them off as it goes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify&lt;/strong&gt; (&lt;code&gt;/opsx:verify&lt;/code&gt;): it checks that the implementation matches the spec. This one is part of the expanded workflow profile, which you enable with &lt;code&gt;openspec config profile&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Archive&lt;/strong&gt; (&lt;code&gt;/opsx:archive&lt;/code&gt;): the deltas are merged into &lt;code&gt;specs/&lt;/code&gt;, and the change folder moves to &lt;code&gt;changes/archive/&lt;/code&gt; with a date prefix.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After archiving, the spec describes the system as it is now, and the archived change keeps the full story of why it got that way.&lt;/p&gt;

&lt;p&gt;The steps aren't rigid gates. You can go back and update the proposal or the design at any point when you learn something during implementation. That flexibility is one of the things I like most about it compared with heavier spec frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  A concrete example: password reset
&lt;/h2&gt;

&lt;p&gt;Say you want users to reset their password by email, with a link that expires in 15 minutes. Here's what the main artifacts look like.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;proposal.md&lt;/code&gt;&lt;/strong&gt; captures the intent and, just as important, the scope:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Proposal: Add password reset by email&lt;/span&gt;

&lt;span class="gu"&gt;## Intent&lt;/span&gt;
Users who forget their password currently need to contact support.
Let them reset it themselves with a secure, short-lived link.

&lt;span class="gu"&gt;## Scope&lt;/span&gt;
In scope:
&lt;span class="p"&gt;-&lt;/span&gt; "Forgot password" request from the login screen
&lt;span class="p"&gt;-&lt;/span&gt; Single-use reset link sent by email, valid for 15 minutes
&lt;span class="p"&gt;-&lt;/span&gt; Revoking active sessions after a successful reset

Out of scope:
&lt;span class="p"&gt;-&lt;/span&gt; SMS or authenticator-based recovery
&lt;span class="p"&gt;-&lt;/span&gt; Changes to the sign-up flow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The delta spec&lt;/strong&gt; describes observable behavior with concrete scenarios:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Delta for Auth&lt;/span&gt;

&lt;span class="gu"&gt;## ADDED Requirements&lt;/span&gt;

&lt;span class="gu"&gt;### Requirement: Password reset by email&lt;/span&gt;
The system MUST let a user reset their password through a single-use
link sent to their registered email, valid for 15 minutes.

&lt;span class="gu"&gt;#### Scenario: Valid reset link&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; GIVEN a user requested a password reset 5 minutes ago
&lt;span class="p"&gt;-&lt;/span&gt; WHEN they open the link and submit a new valid password
&lt;span class="p"&gt;-&lt;/span&gt; THEN the password is updated
&lt;span class="p"&gt;-&lt;/span&gt; AND all of the user's active sessions are revoked
&lt;span class="p"&gt;-&lt;/span&gt; AND the link can no longer be used

&lt;span class="gu"&gt;#### Scenario: Expired link&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; GIVEN a reset link created 16 minutes ago
&lt;span class="p"&gt;-&lt;/span&gt; WHEN the user opens it
&lt;span class="p"&gt;-&lt;/span&gt; THEN the reset is refused with a "link expired" message
&lt;span class="p"&gt;-&lt;/span&gt; AND the password is unchanged

&lt;span class="gu"&gt;#### Scenario: Unknown email&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; GIVEN no account exists for the submitted email
&lt;span class="p"&gt;-&lt;/span&gt; WHEN a reset is requested
&lt;span class="p"&gt;-&lt;/span&gt; THEN the response is identical to the one for an existing account
&lt;span class="p"&gt;-&lt;/span&gt; AND no email is sent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last scenario is a good example of why the review step matters. "Don't reveal whether an account exists" is easy to forget in a prompt, and it's a security requirement. Written as a scenario, it's visible, reviewable and testable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;design.md&lt;/code&gt;&lt;/strong&gt; holds the technical approach (how tokens are generated and stored, rate limiting, which email service), and &lt;strong&gt;&lt;code&gt;tasks.md&lt;/code&gt;&lt;/strong&gt; is the checklist the agent follows during Apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## 1. Reset tokens&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [ ] 1.1 Generate single-use tokens with a CSPRNG; store only their hash
&lt;span class="p"&gt;-&lt;/span&gt; [ ] 1.2 Expire tokens after 15 minutes; invalidate on use
&lt;span class="p"&gt;-&lt;/span&gt; [ ] 1.3 Tests for valid, expired and reused tokens

&lt;span class="gu"&gt;## 2. API&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [ ] 2.1 POST /password-reset/request with identical responses for unknown emails
&lt;span class="p"&gt;-&lt;/span&gt; [ ] 2.2 POST /password-reset/confirm; revoke sessions on success
&lt;span class="p"&gt;-&lt;/span&gt; [ ] 2.3 Rate limit both endpoints per IP and per account
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The spec says &lt;strong&gt;what&lt;/strong&gt; the system must do. The design and tasks say &lt;strong&gt;how&lt;/strong&gt;. Keeping those apart is what lets you review the behavior without getting lost in implementation details.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to look for when you review
&lt;/h2&gt;

&lt;p&gt;Since the review is the step that pays for everything else, it's worth being deliberate about it. These are the questions I ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Is the scope right?&lt;/strong&gt; Is anything in scope that shouldn't be, or missing from the out-of-scope list?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Are the scenarios concrete?&lt;/strong&gt; "The link expires" is vague. "A link created 16 minutes ago is refused" is testable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Are the edge cases there?&lt;/strong&gt; Errors, empty states, abuse, permissions, concurrency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does anything conflict with existing decisions?&lt;/strong&gt; A new library, a new pattern, a different way of storing data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Could someone write a test from each scenario?&lt;/strong&gt; If not, it's still too ambiguous.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When it's worth using
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Features that touch several parts of the system.&lt;/strong&gt; The more the work spreads across the codebase, the more expensive a late misunderstanding gets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Existing codebases.&lt;/strong&gt; The agent needs to understand what's already there before changing it, and delta specs are designed for exactly that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Teams with more than one person (or more than one agent) on the same code.&lt;/strong&gt; Everyone works from the same document, not from different chat histories.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Requirements that are still moving.&lt;/strong&gt; Updating the spec and regenerating the tasks is easier than rewriting code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And when it isn't: one-line bug fixes, small visual tweaks, throwaway scripts. There, the process gets in the way more than it helps. OpenSpec's own docs push in the same direction: most changes should use a light spec, and the full treatment is for higher-risk work like API contracts, migrations and security changes.&lt;/p&gt;

&lt;p&gt;My rule of thumb: &lt;strong&gt;if I'd have to explain the task to a teammate before they started, it deserves a spec.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Verify trap: who checks the checker?
&lt;/h2&gt;

&lt;p&gt;When I posted about OpenSpec on LinkedIn, someone asked a question I think every team using spec-driven development should think about:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If the same agent that implemented the tasks also verifies the implementation against the spec, what stops it from misreading the spec the same way in both steps?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The concern is real. If the same agent, with the same context, implements and then verifies, &lt;strong&gt;it tends to repeat the same misreading&lt;/strong&gt;. The Verify step is good at catching what was left out or not done. It doesn't guarantee the interpretation was right in the first place.&lt;/p&gt;

&lt;p&gt;What you can do to reduce that risk:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Make the scenarios concrete.&lt;/strong&gt; The more specific they are, with real input and output values, the less room there is for interpretation. The spec review is the moment to remove ambiguity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Turn the scenarios into tests before Apply.&lt;/strong&gt; Essentially acceptance tests, written by a person or by a separate agent, based on the spec and not on the implementation. Each GIVEN/WHEN/THEN maps naturally to a test.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep those tests hidden from the implementing agent.&lt;/strong&gt; Run them only in CI, or block read access to that folder in the agent's permissions. Like a held-out evaluation set, this stops the agent from writing code just to make the tests pass.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify in a clean session,&lt;/strong&gt; with no history from the implementation. Using a different model can help too. OpenSpec's own docs recommend clearing the context before implementation, and the same hygiene applies to verification.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Let CI have the final word.&lt;/strong&gt; The tests running in the pipeline decide, not the agent saying everything matches.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The discussion went one step further: if someone outside the team, like a customer or an auditor, doubted a green run, how would they know the hidden tests weren't edited after the code was written, and that they ran against that exact build? The short answer involves locking the tests before Apply, pinning their commit in CI, and signed build provenance (SLSA, Sigstore). It's a big enough topic that I'll cover it in a separate post.&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenSpec and ADRs
&lt;/h2&gt;

&lt;p&gt;A question I get often: if I already write ADRs, do I need specs? They solve different problems and work well together.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;ADR&lt;/th&gt;
&lt;th&gt;OpenSpec&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Answers&lt;/td&gt;
&lt;td&gt;Why did we decide this?&lt;/td&gt;
&lt;td&gt;What should the system do?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unit&lt;/td&gt;
&lt;td&gt;One decision&lt;/td&gt;
&lt;td&gt;One change or capability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lifecycle&lt;/td&gt;
&lt;td&gt;Immutable; superseded by a new ADR&lt;/td&gt;
&lt;td&gt;Living; updated with every archived change&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leads to implementation?&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes: tasks, apply, verify&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Horizon&lt;/td&gt;
&lt;td&gt;Long term, history&lt;/td&gt;
&lt;td&gt;The current change and the current state&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;They meet in &lt;code&gt;design.md&lt;/code&gt;. A change's design often contains technical decisions. If a decision only matters for that feature, it can stay there. If it &lt;strong&gt;goes beyond the feature and affects the whole project&lt;/strong&gt; (switching databases, changing the authentication approach, adopting a queue), write an ADR and link it from the design.&lt;/p&gt;

&lt;p&gt;A practical rule: &lt;strong&gt;if someone will want to know in two years why something was done this way, write an ADR. If you want the agent to build the right thing now, write a spec.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I wrote more about ADRs and AI agents in &lt;a href="https://dev.to/soaresdiogo/adrs-are-the-guardrails-your-ai-coding-agent-is-missing-459c"&gt;ADRs Are the Guardrails Your AI Coding Agent Is Missing&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install the CLI and run &lt;code&gt;openspec init&lt;/code&gt; in an existing project.&lt;/li&gt;
&lt;li&gt;Pick a real feature of medium size, not a one-line fix and not a rewrite.&lt;/li&gt;
&lt;li&gt;Start with &lt;code&gt;/opsx:explore&lt;/code&gt; and let the agent map the code before proposing anything.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;/opsx:propose&lt;/code&gt;, then spend real time on the review. Rewrite vague scenarios until each one could become a test.&lt;/li&gt;
&lt;li&gt;Apply, verify, archive, and look at how &lt;code&gt;specs/&lt;/code&gt; changed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After one or two changes, you'll have a feel for which work deserves a spec and which doesn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;AI agents are very good at building what you asked for. The hard part is making sure what you asked for is what you actually meant. OpenSpec moves that agreement out of a chat window and into the repository, where both people and agents can read it, review it, and come back to it later.&lt;/p&gt;

&lt;p&gt;It isn't magic, and the verification step needs help from good tests to be trustworthy. But writing the spec before the code is one of the habits that improved my work with agents the most.&lt;/p&gt;

&lt;p&gt;How about you? Do you write the spec before asking the AI for code, or do you still go straight to the prompt?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>softwareengineering</category>
      <category>opensource</category>
    </item>
    <item>
      <title>From One Prompt to Every Screen: Claude Code's Editable Design Canvas</title>
      <dc:creator>Diogo Soares</dc:creator>
      <pubDate>Fri, 16 Oct 2026 15:54:52 +0000</pubDate>
      <link>https://dev.to/soaresdiogo/from-one-prompt-to-every-screen-claude-codes-editable-design-canvas-5792</link>
      <guid>https://dev.to/soaresdiogo/from-one-prompt-to-every-screen-claude-codes-editable-design-canvas-5792</guid>
      <description>&lt;p&gt;Every new product or feature starts the same way. Before anyone can discuss the idea, someone has to draw the obvious: login, home, a list, a detail page, a profile. Then the states nobody draws in the first version: empty, loading, error, success.&lt;/p&gt;

&lt;p&gt;It's necessary work, but it's not where design adds the most value. The valuable part comes after: flow, hierarchy, interactions and product decisions.&lt;/p&gt;

&lt;p&gt;A recent Claude Code feature goes straight at that bottleneck. You can ask, in plain language, for every screen of your app, and you get back a design canvas where each screen is a live, editable artboard. Not a screenshot. Not a static mockup.&lt;/p&gt;

&lt;p&gt;This post covers what it is, what happens under the hood, how to ask for it, and the tips that make the difference between a generic result and a useful first draft.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is
&lt;/h2&gt;

&lt;p&gt;The result is an infinite canvas with live artboards. Each screen becomes a frame on the canvas, at real device size, organized by flow, with titles and notes.&lt;/p&gt;

&lt;p&gt;It isn't limited to mobile apps. The same canvas works for web pages, landing pages, and even social media posts.&lt;/p&gt;

&lt;p&gt;The canvas is published as a private page on claude.ai. You see the screens appear as they're drawn, and you decide whether and when to share it with your team.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to ask
&lt;/h2&gt;

&lt;p&gt;There's no special command or syntax. You just ask. It works anywhere Claude Code runs: the terminal, the desktop app or the web.&lt;/p&gt;

&lt;p&gt;A good first request looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a design canvas with every screen of the app in this repo:
onboarding, login, home, calendar, detail and profile.
Mobile 390×844. Include empty, loading and error states.
Use our design system.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The most useful detail: &lt;strong&gt;run it inside your repository.&lt;/strong&gt; Claude Code reads the code to find the screens that actually exist (routes, pages, components), so the canvas reflects your real app instead of a generic template.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens after you hit Enter
&lt;/h2&gt;

&lt;p&gt;Roughly four steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;It understands the request.&lt;/strong&gt; It reads the repo, its routes and components, to learn which screens exist and how they connect.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It picks the look.&lt;/strong&gt; If your account or organization has a default design system, it uses it. If not, it defines a coherent visual identity and tells you which decisions it made.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It draws screen by screen.&lt;/strong&gt; Each artboard is an independent HTML component at real device size, which is why everything stays editable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It hands you the link.&lt;/strong&gt; A private canvas on claude.ai, where you watch the screens appear and decide what to do next.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The part that won me over: everything is editable
&lt;/h2&gt;

&lt;p&gt;This is what separates it from "AI generated a picture of an app".&lt;/p&gt;

&lt;p&gt;Because every screen is a live component, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tweak it directly.&lt;/strong&gt; Change copy, colors and spacing in a properties panel, and see the screen update right away.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comment on a screen.&lt;/strong&gt; Leave a comment like "make the card bigger and swap the icon", and Claude makes the change on that screen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep iterating in conversation.&lt;/strong&gt; Ask for a new variation, a new state or a new flow without starting over.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Take it further.&lt;/strong&gt; Link screens into a clickable prototype, or share the canvas with your team for feedback.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Five tips for a great canvas on the first try
&lt;/h2&gt;

&lt;p&gt;The quality of the canvas depends a lot on the quality of the request. These are the things that matter most.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Name the screens and flows
&lt;/h3&gt;

&lt;p&gt;"Design my app" gets you something generic. Name each screen and group them into flows: onboarding (welcome, sign up, permissions), auth (login, password reset), main (home, list, detail, profile, settings).&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Set the format
&lt;/h3&gt;

&lt;p&gt;Say what you're designing for: mobile at 390×844, web at 1440px, a landing page, a social post. Otherwise you'll get a reasonable guess, which may not be your guess.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Ask for the states
&lt;/h3&gt;

&lt;p&gt;Empty, loading, error and success. This is where most of the time savings are, because these are the screens nobody wants to draw by hand, and the ones most often forgotten until development.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Point to the brand
&lt;/h3&gt;

&lt;p&gt;Your design system, colors, fonts, or simply the repository. Without a reference, it will create a coherent identity, but it won't be yours.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Iterate in small steps
&lt;/h3&gt;

&lt;p&gt;"On the login screen, change the CTA to 'Continue with email'" works much better than asking it to redo everything. Small, specific requests keep what's already good and change only what you asked for.&lt;/p&gt;

&lt;h2&gt;
  
  
  A full prompt you can copy
&lt;/h2&gt;

&lt;p&gt;Putting the tips together, this is a prompt I'd use as a starting point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a design canvas with every screen of the app in this repo.

Flows:
- Onboarding: welcome, sign up, permissions
- Auth: login, password reset
- Main: home, list, detail, profile, settings

Mobile 390×844, one artboard per screen, grouped by flow with a title for each.
For each main screen, also include the empty, loading, error and success states.

Use our design system. If there isn't one, propose a simple identity
and tell me which decisions you made.

Use real copy from the app's domain, no lorem ipsum.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last line matters more than it looks. Real copy makes layout problems visible early: long names, button labels that don't fit, empty states that need an explanation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it doesn't do
&lt;/h2&gt;

&lt;p&gt;It's worth being clear about the limits, so expectations stay realistic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It doesn't replace designers.&lt;/strong&gt; It gives you a starting point. Decisions about hierarchy, interaction, accessibility and the product itself are still human work, and they're the ones that matter most.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vague requests give generic results.&lt;/strong&gt; If you don't name screens, formats and states, you get a plausible but bland app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It reflects what it can read.&lt;/strong&gt; If the repo is half-built or the screens are only in someone's head, describe them in the prompt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review it like any first draft.&lt;/strong&gt; Check contrast, touch target sizes and edge cases before treating anything as final.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Who it's for
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Designers&lt;/strong&gt; skip the rough draft and start at refinement: hierarchy, interactions and product calls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Engineers&lt;/strong&gt; see the screen before coding, and can discuss layout and states with something concrete instead of a description in a ticket.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product managers&lt;/strong&gt; validate a flow early, bringing real screens into the conversation before the sprint starts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The way I see it: designers keep making the calls. Claude delivers the starting point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;The time between "we have an idea" and "we have screens to discuss" used to be measured in days. With an editable canvas generated from your own repository, it can be minutes, and what you get is something you can keep working on, not a picture you have to redraw.&lt;/p&gt;

&lt;p&gt;If you try it, start small: one flow, one format, all the states. Then iterate.&lt;/p&gt;

&lt;p&gt;Have you tried it yet? I'm curious how designers feel about starting from a generated first draft instead of a blank canvas.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>design</category>
      <category>ux</category>
      <category>productivity</category>
    </item>
    <item>
      <title>ADRs Are the Guardrails Your AI Coding Agent Is Missing</title>
      <dc:creator>Diogo Soares</dc:creator>
      <pubDate>Fri, 16 Oct 2026 15:21:31 +0000</pubDate>
      <link>https://dev.to/soaresdiogo/adrs-are-the-guardrails-your-ai-coding-agent-is-missing-459c</link>
      <guid>https://dev.to/soaresdiogo/adrs-are-the-guardrails-your-ai-coding-agent-is-missing-459c</guid>
      <description>&lt;p&gt;If you work with AI coding agents every day, you have probably seen this: you ask for a small change, and the agent suggests swapping your authentication library, changing your data access pattern, or "simplifying" something that was built that way for a good reason.&lt;/p&gt;

&lt;p&gt;The agent isn't doing this on purpose. It just doesn't know why your decisions were made.&lt;/p&gt;

&lt;p&gt;I've been using Architecture Decision Records (ADRs) for years as a team practice. Since AI agents became part of my daily work, they stopped being "nice documentation" and became one of the most effective guardrails I have. This post explains why, shows a real example from one of my projects, and describes how I turn ADRs into guardrails that an agent actually follows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why agents keep reopening settled decisions
&lt;/h2&gt;

&lt;p&gt;An agent like Claude Code, Cursor or Copilot knows a lot about software in general and very little about your project in particular. Three things make this worse than it sounds:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;No memory between sessions.&lt;/strong&gt; Every session starts from zero. The agent only knows what is in its context: your prompt, the files it reads, and the instruction files you give it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code shows the "what", never the "why".&lt;/strong&gt; The agent can see that you use PostgreSQL. It cannot see that you evaluated MongoDB, rejected it because of reporting needs, and accepted the extra migration work on purpose.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Without constraints, it falls back to generic best practices.&lt;/strong&gt; If nothing says otherwise, the agent will optimize for what is usually a good idea, not for what is right in your context. Those are often not the same thing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That "why" used to live in the heads of the people who had been on the team the longest. A new developer would ask, and someone would explain. An agent doesn't ask. It acts on what it can read. If the reasoning isn't written down, from the agent's point of view it doesn't exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an ADR is
&lt;/h2&gt;

&lt;p&gt;An ADR is a short document that records one architectural decision. It is not a design doc and it is not a wiki page that tries to describe the whole system. It captures a single decision at a single point in time.&lt;/p&gt;

&lt;p&gt;A good ADR answers four questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Context:&lt;/strong&gt; what problem did we have, and what constraints were we under?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decision:&lt;/strong&gt; what did we choose?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alternatives:&lt;/strong&gt; what did we reject, and why?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consequences:&lt;/strong&gt; what did we gain, and what did we give up?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the template I use. It is intentionally small:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# NNNN. Title&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="gs"&gt;**Status:**&lt;/span&gt; Proposed | Accepted | Superseded by NNNN
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Date:**&lt;/span&gt; YYYY-MM-DD

&lt;span class="gu"&gt;## Context&lt;/span&gt;

What forces are at play (product goals, technical constraints, costs)?

&lt;span class="gu"&gt;## Decision&lt;/span&gt;

What we decided, stated in full sentences ("We will…").

&lt;span class="gu"&gt;## Consequences&lt;/span&gt;

What becomes easier or harder, the risks we accept, and the follow-ups this creates.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ADRs live in the repository, usually in &lt;code&gt;docs/adr/&lt;/code&gt;, numbered in order, with an index in &lt;code&gt;docs/adr/README.md&lt;/code&gt;. Two rules make them work over time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;An accepted ADR is never rewritten.&lt;/strong&gt; If the decision changes, you write a new ADR that supersedes the old one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Each ADR has a status.&lt;/strong&gt; Readers (human or not) can tell which decisions are still in force.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A real example: when a decision has to change
&lt;/h2&gt;

&lt;p&gt;I'm building a personal running app (React Native with Expo, a Node API, Strava integration). It has 32 ADRs so far. Here is a pair that shows why this matters with agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ADR 0004&lt;/strong&gt; says: the app does not record GPS. Strava is the single source of recorded activities. The reasoning is in the context section: the watch and Strava already record runs well, background GPS isn't available in Expo Go, and duplicating recordings would only add battery drain and complexity.&lt;/p&gt;

&lt;p&gt;Without that ADR, an agent asked to "show the distance of each interval" would very likely add GPS recording. It is the obvious solution, and it would quietly break a decision I made on purpose.&lt;/p&gt;

&lt;p&gt;Then a real need appeared. During track workouts with timed reps (for example, 10 × 30 seconds), I don't know how far I ran in each rep, and my coach asks for it. That is a different problem: I don't need a recorded activity, only the distance inside each fast window.&lt;/p&gt;

&lt;p&gt;So I didn't "just add GPS". I wrote &lt;strong&gt;ADR 0020&lt;/strong&gt;, which &lt;strong&gt;partly supersedes&lt;/strong&gt; ADR 0004, for timed reps only. It records:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the constraint: in Expo Go, location updates only arrive while the app is in the foreground;&lt;/li&gt;
&lt;li&gt;the decision: GPS is watched during sessions with timed reps, noisy fixes are filtered out, and only the metres per rep are kept, with no stored or uploaded positions;&lt;/li&gt;
&lt;li&gt;the consequences: a few metres of error per rep, extra battery use, and the screen must stay on. Measuring with the screen locked would need a development build and a new ADR.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important part is the last line of that ADR: &lt;em&gt;Strava stays the source of recorded activities (the rest of ADR 0004 holds).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now, when an agent works on this code, it can read exactly where the line is. GPS is allowed for timed reps, under specific rules. It is still not allowed for recording runs. And if I ever ask for something that crosses that line, the agent has what it needs to stop and tell me: "this conflicts with ADR 0004 and ADR 0020".&lt;/p&gt;

&lt;p&gt;That is the shift. The agent stops being something that might break your decisions and becomes something that can defend them.&lt;/p&gt;

&lt;h2&gt;
  
  
  From documentation to guardrails
&lt;/h2&gt;

&lt;p&gt;Writing ADRs is the first step, but an ADR sitting in a folder is only useful if the agent reads it. Over time I ended up with four layers. Each one covers a weakness of the previous one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 1: ADRs hold the "why"
&lt;/h3&gt;

&lt;p&gt;The ADRs are the source of truth for decisions and their reasoning. Everything else points to them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2: the instruction file turns decisions into rules
&lt;/h3&gt;

&lt;p&gt;Agents read an instruction file at the start of every session (&lt;code&gt;CLAUDE.md&lt;/code&gt;, &lt;code&gt;AGENTS.md&lt;/code&gt;, &lt;code&gt;.cursor/rules&lt;/code&gt;, &lt;code&gt;copilot-instructions.md&lt;/code&gt;, depending on the tool). This is where ADRs become short, explicit rules, each one citing the ADR that explains it.&lt;/p&gt;

&lt;p&gt;Here is part of the &lt;code&gt;CLAUDE.md&lt;/code&gt; from the running app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Read &lt;span class="sb"&gt;`README.md`&lt;/span&gt; and &lt;span class="sb"&gt;`docs/adr/`&lt;/span&gt; before changing architecture.

&lt;span class="gu"&gt;## Rules&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; Every project decision becomes an ADR in &lt;span class="sb"&gt;`docs/adr/`&lt;/span&gt; (template there;
   never rewrite an accepted ADR, supersede it). Update the index in
   &lt;span class="sb"&gt;`docs/adr/README.md`&lt;/span&gt;.
&lt;span class="p"&gt;2.&lt;/span&gt; &lt;span class="sb"&gt;`packages/domain`&lt;/span&gt; is framework-free: no React, Expo, Node or HTTP imports.
&lt;span class="p"&gt;3.&lt;/span&gt; Mobile runs in Expo Go. Anything that needs a dev build (Face ID,
   HealthKit, background GPS) requires an ADR first.
&lt;span class="p"&gt;5.&lt;/span&gt; Strava is the activity source; never record activities with GPS (ADR 0004).
   GPS only measures timed reps (ADR 0020).
&lt;span class="p"&gt;7.&lt;/span&gt; Tokens only in secure storage; never in AsyncStorage/SQLite/logs (ADR 0005).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things make this work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The rule is short; the reasoning is in the ADR.&lt;/strong&gt; The instruction file stays small enough that the agent reads all of it every time, and it can open the ADR when it needs the details.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Each rule cites its ADR.&lt;/strong&gt; When the agent pushes back, it can say which decision is at stake, and I can check whether that decision still makes sense.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Some rules are gates, not prohibitions.&lt;/strong&gt; "Requires an ADR first" doesn't forbid background GPS forever. It forces the conversation to happen before the code, which is exactly when I want to have it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Layer 3: the process makes the agent part of the ADR workflow
&lt;/h3&gt;

&lt;p&gt;Agents are good at writing ADRs. They are fast at summarizing context, listing alternatives and spelling out consequences. So I let them draft, and I decide.&lt;/p&gt;

&lt;p&gt;My workflow looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Before any structural change, the agent reads the relevant ADRs.&lt;/li&gt;
&lt;li&gt;If my request conflicts with an accepted ADR, the agent says so and names it, instead of silently working around it.&lt;/li&gt;
&lt;li&gt;If the decision really needs to change, the agent drafts a new ADR (status &lt;code&gt;Proposed&lt;/code&gt;) that supersedes the old one, and updates the index.&lt;/li&gt;
&lt;li&gt;I review it, change what's wrong, and only then mark it &lt;code&gt;Accepted&lt;/code&gt; and implement.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This keeps a human in charge of the decisions while the agent does most of the writing. It also means the history is never lost: six months later, both I and the agent can follow the chain from ADR 0004 to ADR 0020 and understand why the code looks the way it does.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 4: automated checks enforce what can't be left to reading
&lt;/h3&gt;

&lt;p&gt;Instruction files are strong guidance, not guarantees. Agents follow them most of the time, but not always, especially in long sessions or when the context gets crowded. So for decisions where a violation would be expensive, I don't rely only on the agent reading a rule. I make the build fail.&lt;/p&gt;

&lt;p&gt;Some examples of decisions that can be enforced automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Layer boundaries:&lt;/strong&gt; a lint rule (for example, &lt;code&gt;no-restricted-imports&lt;/code&gt; in ESLint, or a dependency-cruiser config) that blocks framework imports inside the domain package.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security decisions:&lt;/strong&gt; in the running app, the API's security decisions are in an ADR, and a smoke test against the production image runs the matching attack checks: user enumeration, 2FA bypass, mass assignment, a tampered JWT, deleting another user's data (IDOR), refresh-token replay. If an agent "simplifies" the authorization logic, the check fails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Domain rules:&lt;/strong&gt; unit tests that encode the rules an ADR describes, such as how GPS fixes are filtered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent hooks:&lt;/strong&gt; many tools now support hooks that run before or after the agent edits files or runs commands. They are a good place for fast checks, like blocking edits to accepted ADRs or running the linter after every change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A single "done" command:&lt;/strong&gt; one command (&lt;code&gt;npm run check&lt;/code&gt; in my case) that runs lint, type checks and tests, which the instruction file requires before a task is considered done.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple way to think about the layers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Its weakness&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ADR&lt;/td&gt;
&lt;td&gt;Explains why a decision was made&lt;/td&gt;
&lt;td&gt;Only works if someone reads it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instruction file&lt;/td&gt;
&lt;td&gt;Turns decisions into rules the agent reads every session&lt;/td&gt;
&lt;td&gt;Guidance, not enforcement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Process&lt;/td&gt;
&lt;td&gt;Forces decisions to be discussed before code is written&lt;/td&gt;
&lt;td&gt;Depends on discipline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automated checks&lt;/td&gt;
&lt;td&gt;Fails the build when a decision is violated&lt;/td&gt;
&lt;td&gt;Only covers what can be checked&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;None of these layers is enough on its own. Together, they cover each other's gaps. The ADR is what ties them together: every rule, gate and check can point back to a decision with a written reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  What not to do
&lt;/h2&gt;

&lt;p&gt;A few mistakes I've made or seen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Writing ADRs for everything.&lt;/strong&gt; Naming a variable is not an architectural decision. If reverting the decision would be cheap, it probably doesn't need an ADR.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Writing long ADRs.&lt;/strong&gt; If an ADR needs ten pages, it is a design doc. Agents and humans both skip long documents. One or two screens is usually enough.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Editing accepted ADRs.&lt;/strong&gt; It feels faster, but you lose the history, and the agent loses the ability to understand how and why things changed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leaving superseded ADRs without a status.&lt;/strong&gt; Two ADRs that contradict each other, both marked &lt;code&gt;Accepted&lt;/code&gt;, will confuse an agent more than having no ADRs at all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not linking ADRs from the instruction file.&lt;/strong&gt; If the agent doesn't know the folder exists, it might never open it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting started in an afternoon
&lt;/h2&gt;

&lt;p&gt;If your project has no ADRs yet, you don't need to document its entire history. Start small:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create &lt;code&gt;docs/adr/&lt;/code&gt; with a template and a README index.&lt;/li&gt;
&lt;li&gt;Write ADR 0001: "We record architecture decisions using ADRs".&lt;/li&gt;
&lt;li&gt;Write ADRs for the three to five decisions an agent (or a new developer) is most likely to undo: your data store, your authentication approach, your layering rules, and anything that looks "wrong" but is intentional.&lt;/li&gt;
&lt;li&gt;Add a short rules section to your agent's instruction file, with each rule pointing to its ADR, plus the instruction to read &lt;code&gt;docs/adr/&lt;/code&gt; before structural changes.&lt;/li&gt;
&lt;li&gt;Pick the one decision that would hurt most if broken and add an automated check for it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;From then on, every new decision gets an ADR, and you can ask the agent to draft it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Documenting decisions has always been good practice. The difference now is who reads them. With AI agents on the team, your ADRs are read every day, by a reader that has no memory, never asks "why", and will happily change anything that isn't explained.&lt;/p&gt;

&lt;p&gt;Write the "why" down, turn it into rules, and enforce what matters most. That's what makes an agent's work fit your project instead of a generic idea of what a project should look like.&lt;/p&gt;

&lt;p&gt;Do you use ADRs in your projects? How do you give that context to your agents? I'd like to hear what has worked for you.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>softwareengineering</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
