<?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: yunbow</title>
    <description>The latest articles on DEV Community by yunbow (@yunbow).</description>
    <link>https://dev.to/yunbow</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3909809%2F85412494-b63e-47d7-a160-a99184f2c7b4.png</url>
      <title>DEV Community: yunbow</title>
      <link>https://dev.to/yunbow</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yunbow"/>
    <language>en</language>
    <item>
      <title>Code Review Is Broken for AI-Generated Code — The Case for Pre-Implementation Governance</title>
      <dc:creator>yunbow</dc:creator>
      <pubDate>Wed, 06 May 2026 12:32:05 +0000</pubDate>
      <link>https://dev.to/yunbow/code-review-is-broken-for-ai-generated-code-the-case-for-pre-implementation-governance-43h5</link>
      <guid>https://dev.to/yunbow/code-review-is-broken-for-ai-generated-code-the-case-for-pre-implementation-governance-43h5</guid>
      <description>&lt;p&gt;Your team's code review process was designed for a world where a developer wrote every line.&lt;/p&gt;

&lt;p&gt;In that world, a PR with 200 lines meant 200 lines of human judgment. The reviewer's job was to check that judgment: catch bugs, enforce patterns, transfer knowledge. Review velocity matched author velocity. It worked.&lt;/p&gt;

&lt;p&gt;Now a developer generates 800 lines in an afternoon. The PR is 800 lines of AI output, lightly edited. &lt;strong&gt;The reviewer's job hasn't changed. The workload has.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Something breaks at scale. This is that something — and the fix isn't "review more carefully."&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Code Review Worked
&lt;/h2&gt;

&lt;p&gt;To understand what's breaking, start with why code review worked.&lt;/p&gt;

&lt;p&gt;The implicit model was straightforward: a developer who wrote the code understands the code. The reviewer's job isn't to re-derive it from scratch — it's to check what the author might have missed, enforce conventions they might have drifted from, and transfer knowledge bidirectionally.&lt;/p&gt;

&lt;p&gt;Author accountability made this work. When a reviewer left a comment — "we don't use &lt;code&gt;useEffect&lt;/code&gt; for data fetching here" — the author learned something. The next PR, they applied it. Over months, the team's conventions transferred from senior to junior through accumulated review feedback.&lt;/p&gt;

&lt;p&gt;Review velocity matched author velocity. One developer submitting 3 PRs a week produced review work that 1–2 reviewers could handle with appropriate depth. The ratio held.&lt;/p&gt;

&lt;p&gt;None of these assumptions hold when AI is in the loop.&lt;/p&gt;




&lt;h2&gt;
  
  
  How AI Changes the Math
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Volume
&lt;/h3&gt;

&lt;p&gt;A developer with an AI assistant generates significantly more code per day. Self-reported data and published productivity studies vary widely — 2× for complex tasks, up to 10× for focused generation work — but the directional finding is consistent: output volume per developer increases meaningfully.&lt;/p&gt;

&lt;p&gt;If a developer submitted 3 PRs a week before, they might submit 15 now. The review backlog grows faster than review capacity. Reviewers face a choice: spend more time reviewing (at the cost of their own development work), or skim.&lt;/p&gt;

&lt;p&gt;Most teams end up with a mix: some PRs get deep review, most get shallow review. The PRs that get shallow review are unpredictable. Convention violations slip through.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accountability Diffuses
&lt;/h3&gt;

&lt;p&gt;"The AI wrote it" is a new and genuinely complicated accountability situation.&lt;/p&gt;

&lt;p&gt;The developer is still responsible — they submitted the PR. But they may not have deeply understood every line. They didn't write it from scratch; they prompted and accepted. Their mental model of why the code does what it does is less thorough than if they'd typed it line by line.&lt;/p&gt;

&lt;p&gt;Reviewers feel this. The usual question — "what was the author thinking here?" — becomes harder to answer. "They asked AI to implement X" is not an answer that helps you evaluate whether the approach is sound.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pattern Inconsistency Increases
&lt;/h3&gt;

&lt;p&gt;Human developers drift from conventions gradually and inconsistently. Developer A might occasionally forget to validate input; Developer B might sometimes skip field selection on Prisma queries. These are distributed individual errors.&lt;/p&gt;

&lt;p&gt;AI drift is different. When AI generates code without your team's conventions in its context, it defaults to patterns from its training data. Those patterns may be systematically different from yours. Every API route generated in the same session might have the same missing auth pattern. Every Server Action might use the same incorrect error handling.&lt;/p&gt;

&lt;p&gt;This is worse than individual human drift because it's coherent and consistent — which makes it easier to miss. A codebase with uniform but incorrect patterns looks intentional.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Knowledge Transfer Function Breaks
&lt;/h3&gt;

&lt;p&gt;Junior developers lost a growth mechanism.&lt;/p&gt;

&lt;p&gt;When AI generated the code and the reviewer fixed a convention violation in review, who learned? The reviewer wrote the comment. The developer accepted the suggestion. The AI generated the next file without knowing the convention existed.&lt;/p&gt;

&lt;p&gt;The feedback loop that built senior developers over time — submit code, get specific feedback, internalize the pattern, apply it next time — is disrupted when AI is generating first drafts. The junior developer is learning to prompt and accept, not to derive patterns from first principles.&lt;/p&gt;

&lt;p&gt;This isn't an argument against using AI. It's a recognition that knowledge transfer now requires explicit investment, not passive osmosis.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Traditional Responses and Why They Fail
&lt;/h2&gt;

&lt;p&gt;Teams hit the review breakdown and try a few things:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Just slow down review."&lt;/strong&gt; This creates a bottleneck. Developers wait days for review. The velocity gain from AI evaporates. You've traded speed for thoroughness — but even "slow, careful" review isn't systematic. Two reviewers looking at the same AI output often flag different convention issues and miss different ones. Slowdown adds time; it doesn't add consistency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Be more strict about AI code."&lt;/strong&gt; Stricter in what sense? Without a written rubric, "be more strict" means each reviewer applies their own mental model more rigorously. What you get is reviewer opinion variance at higher intensity — more reviewer burnout, and still no guarantee the same issue is caught across PRs. Convention consistency requires an external reference, not more individual rigor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Require developers to review AI output before submitting."&lt;/strong&gt; A reasonable baseline, but it doesn't solve the systematic gap. A developer who hasn't internalized a convention can't catch its violation when they review their own output. The AI writes what it doesn't know. The developer approves what they don't know. The gap passes through both filters undetected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Pair program with AI and with a reviewer in real time."&lt;/strong&gt; Works for critical paths. Doesn't scale to the steady flow of feature work, where AI generation volume is highest and pairing capacity is lowest.&lt;/p&gt;

&lt;p&gt;All of these responses share a flaw: they're trying to fix a pre-implementation problem at the post-implementation stage. By the time the PR exists, 800 lines of convention-inconsistent code already exist. The fix is preventing them before the first line is generated.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pre-Implementation Governance: The Shift
&lt;/h2&gt;

&lt;p&gt;The core insight: most convention violations, security issues, and pattern drift are predictable and preventable — if your AI has your conventions in context.&lt;/p&gt;

&lt;p&gt;The current workflow for most teams:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer prompts AI
    ↓
AI generates 800 lines without team conventions
    ↓
Developer submits PR
    ↓
Reviewer finds convention violations, security issues, pattern drift
    ↓
Fix cycle (sometimes multiple rounds)
    ↓
Merge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The alternative:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Team conventions encoded in AI context (CLAUDE.md, .mdc files, Steering Rules)
    ↓
Developer prompts AI
    ↓
AI generates code following team conventions
    ↓
Developer submits PR
    ↓
Automated checks verify convention adherence (linting, type checking)
    ↓
Reviewer focuses on logical correctness and design decisions
    ↓
Merge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The shift: move convention enforcement from review (post-implementation) to context (pre-implementation) and automation (pre-merge).&lt;/p&gt;

&lt;p&gt;This has three components:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Explicit rule encoding.&lt;/strong&gt; &lt;code&gt;CLAUDE.md&lt;/code&gt; is an index file — 3 directive lines pointing to your guideline files. The actual conventions (auth patterns, error handling, naming conventions, security invariants) live in the referenced files, not inline. This separation means the rules are always in AI's context, written explicitly enough that AI can follow them without interpretation, without diluting attention with a wall of text.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Automated static verification.&lt;/strong&gt; Linting, type checking, and security scanning run as pre-commit hooks or CI gates. Rules that can be checked mechanically are checked mechanically — not by human reviewers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Review scope redefinition.&lt;/strong&gt; Reviewers stop checking convention compliance (the AI and linter handle that) and focus on what only humans can evaluate: logical correctness, architectural fit, edge case coverage, performance implications.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Changes for Reviewers
&lt;/h2&gt;

&lt;p&gt;This is the part that makes the shift concrete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop reviewing (delegate to AI context + automation):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Naming convention adherence — your AI guidelines handle this; your linter enforces it&lt;/li&gt;
&lt;li&gt;Missing error handling — your AI context requires &lt;code&gt;ActionResult&amp;lt;T&amp;gt;&lt;/code&gt;; your types enforce it&lt;/li&gt;
&lt;li&gt;Auth patterns — your AI security rules specify it; your linter checks for auth calls&lt;/li&gt;
&lt;li&gt;Import ordering, formatting — automated entirely&lt;/li&gt;
&lt;li&gt;Basic type errors — TypeScript strict mode catches these before review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Start reviewing (focus here):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the logic correctly implement the intended behavior?&lt;/li&gt;
&lt;li&gt;Does the architectural approach fit the existing system?&lt;/li&gt;
&lt;li&gt;Are the edge cases covered? (not just happy path)&lt;/li&gt;
&lt;li&gt;Are there performance implications at scale?&lt;/li&gt;
&lt;li&gt;Does this design decision create problems we'll regret in 6 months?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are judgment calls. They require understanding the system, the business context, and the tradeoffs. No linter and no AI rule set can substitute for this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The result:&lt;/strong&gt; reviews become shorter in clock time and higher in cognitive quality. Reviewers spend their time on the questions only they can answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Implementing the Shift
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Audit Your Last 20–30 PRs
&lt;/h3&gt;

&lt;p&gt;Go through the review comments. Categorize each:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Convention&lt;/strong&gt; — naming, patterns, formatting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt; — auth, validation, data exposure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logic&lt;/strong&gt; — wrong behavior, missing edge case&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design&lt;/strong&gt; — architectural mismatch, scalability concern&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Count the percentage in each category. In PRs I've reviewed on AI-assisted teams, convention and security comments consistently make up the majority — often more than half. That's your automation target.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Encode Conventions
&lt;/h3&gt;

&lt;p&gt;Every convention-category comment from step 1 should become either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A rule in your &lt;code&gt;CLAUDE.md&lt;/code&gt; / AI guidelines&lt;/li&gt;
&lt;li&gt;An ESLint rule (if checkable statically)&lt;/li&gt;
&lt;li&gt;A TypeScript type constraint (if enforceable via types)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Repeated security-category comments become security rules in AI context + security ESLint plugins.&lt;/p&gt;

&lt;p&gt;This is one-time work. Once a rule is encoded, you never leave that review comment again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Redefine Review Scope
&lt;/h3&gt;

&lt;p&gt;Write a short "what we review" document for your team. One page. It explicitly states:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What's handled by AI context (convention compliance)&lt;/li&gt;
&lt;li&gt;What's handled by automated checks (linting, types, security scanning)&lt;/li&gt;
&lt;li&gt;What reviewers are responsible for (logic, design, edge cases)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't telling reviewers to be less rigorous. It's telling them where to direct their rigor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Measure
&lt;/h3&gt;

&lt;p&gt;Track:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PR cycle time&lt;/strong&gt; — should decrease as convention-fixing rounds drop out&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reviewer time per PR&lt;/strong&gt; — should decrease once automation handles convention checking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Convention violations post-merge&lt;/strong&gt; — should approach zero with rules in AI context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If violations post-merge aren't dropping, the encoded rules are incomplete or imprecise. Iterate on the rules, not the review process.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Doesn't Change
&lt;/h2&gt;

&lt;p&gt;Code review still matters. Logic errors, design mismatches, and business rule violations require human judgment. AI-generated code needs review for correctness just as human-generated code does — arguably more, because the author's understanding of the code is shallower.&lt;/p&gt;

&lt;p&gt;What changes is what review is for.&lt;/p&gt;

&lt;p&gt;Pre-implementation governance doesn't eliminate review. It elevates it. When reviewers aren't spending their attention on convention checklists, they can spend it on the architectural questions that actually determine whether a feature ages well.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Knowledge Transfer Problem
&lt;/h2&gt;

&lt;p&gt;One thing pre-implementation governance doesn't solve: junior developer growth.&lt;/p&gt;

&lt;p&gt;If conventions are enforced by AI and automation before a junior developer ever touches the code, they may never encounter the correction that would have built their intuition. The feedback loop that built senior developers is still disrupted.&lt;/p&gt;

&lt;p&gt;This is a real cost. The mitigation is intentional: pair programming sessions focused on design decisions (not convention compliance), explicit architectural discussions, and making the encoded rules legible — so junior developers read the guidelines and understand &lt;em&gt;why&lt;/em&gt; the conventions exist, not just &lt;em&gt;that&lt;/em&gt; they exist.&lt;/p&gt;

&lt;p&gt;The rules your team codified for AI should be readable as an engineering culture document. They're not just instructions for the AI.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Broader Pattern
&lt;/h2&gt;

&lt;p&gt;Quality assurance in software has been moving in one direction for decades: earlier.&lt;/p&gt;

&lt;p&gt;Testing shifted from manual QA after shipping to automated tests before shipping. Security shifted from penetration testing in production to SAST in CI. Code quality shifted from "hope the reviewers catch it" to linting in the editor.&lt;/p&gt;

&lt;p&gt;In each case: catch problems earlier, make them cheaper to fix, free up human attention for judgment calls.&lt;/p&gt;

&lt;p&gt;Pre-implementation governance is the same shift applied to AI-generated code. Conventions that used to be caught in review get enforced before generation. Human review bandwidth goes to the problems that require it.&lt;/p&gt;

&lt;p&gt;The teams that will scale AI-assisted development well are the ones investing in rule infrastructure now — not the ones reviewing faster.&lt;/p&gt;




&lt;p&gt;What's your team's current review-to-generation ratio? If you're generating 10× more code but haven't changed your review process, the math is working against you.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is the final article in the AI Dev OS series. The full framework — including rule templates for Next.js and TypeScript — is at &lt;a href="https://github.com/yunbow/ai-dev-os" rel="noopener noreferrer"&gt;github.com/yunbow/ai-dev-os&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>codereview</category>
      <category>softwareengineering</category>
      <category>teamwork</category>
      <category>aidevos</category>
    </item>
    <item>
      <title>Codifying Tacit Knowledge: The Missing Layer Between Your Team's Conventions and Your AI Assistant</title>
      <dc:creator>yunbow</dc:creator>
      <pubDate>Wed, 06 May 2026 00:14:34 +0000</pubDate>
      <link>https://dev.to/yunbow/codifying-tacit-knowledge-the-missing-layer-between-your-teams-conventions-and-your-ai-assistant-302b</link>
      <guid>https://dev.to/yunbow/codifying-tacit-knowledge-the-missing-layer-between-your-teams-conventions-and-your-ai-assistant-302b</guid>
      <description>&lt;p&gt;Every engineering team has two codebases.&lt;/p&gt;

&lt;p&gt;The first is the one in your repository — versioned, reviewed, deployed. The second lives in your engineers' heads: which patterns are preferred, which shortcuts are acceptable, what "clean code" means in &lt;em&gt;this&lt;/em&gt; project specifically.&lt;/p&gt;

&lt;p&gt;New hires absorb it over months. It shapes every PR comment. It's the reason two experienced engineers on your team produce recognizably similar code even when working independently.&lt;/p&gt;

&lt;p&gt;This second codebase — tacit knowledge — is invisible to your AI assistant.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Tacit Knowledge Actually Is
&lt;/h2&gt;

&lt;p&gt;There's a concept from philosophy of knowledge that describes exactly this problem. Michael Polanyi called it tacit knowledge: "we know more than we can tell." In software teams, it shows up as patterns that everyone enforces but no one has written down.&lt;/p&gt;

&lt;p&gt;Pull from a real Next.js project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;"We don't use &lt;code&gt;useEffect&lt;/code&gt; for data fetching." Never written down. Every senior dev enforces it in code review. New hires learn it by getting the comment. The reason (Server Components exist now, and &lt;code&gt;useEffect&lt;/code&gt; fetching causes race conditions we've hit before) lives only in institutional memory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Server Actions always return &lt;code&gt;ActionResult&amp;lt;T&amp;gt;&lt;/code&gt;." Emerged from a painful debugging incident six months ago. There's no ticket, no ADR, no documentation. It's in the team's blood.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Zod schemas live in &lt;code&gt;lib/schemas/&lt;/code&gt;, not colocated with components." A decision made when two engineers independently created conflicting schemas for the same entity. One PR comment from a tech lead fixed it for the humans. The AI has no idea.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren't minor style preferences. They're load-bearing conventions. When they're violated at scale, the codebase becomes harder to navigate, harder to maintain, and harder to reason about.&lt;/p&gt;

&lt;p&gt;The traditional transfer mechanism — code review, pair programming, osmosis — worked well enough when humans wrote all the code. AI changed the equation.&lt;/p&gt;




&lt;h2&gt;
  
  
  How AI Breaks the Knowledge Transfer Mechanism
&lt;/h2&gt;

&lt;p&gt;Junior developers historically learned team conventions through accumulated PR feedback. They'd submit code, get a comment ("we don't do it that way here, here's the pattern we use"), adjust, and internalize. Over months, the tacit knowledge transferred.&lt;/p&gt;

&lt;p&gt;This mechanism has two requirements: the author receives feedback, and the author can learn from it. AI violates both.&lt;/p&gt;

&lt;p&gt;AI generates code without having gone through the feedback loop. It has no history with your specific codebase, no memory of last week's PR comment. It defaults to whatever patterns were most common in its training data — which may be completely different from your team's conventions.&lt;/p&gt;

&lt;p&gt;When you leave a code review comment on AI-generated code, you're not teaching the AI. Next conversation, same violation. The correction doesn't compound.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The silence problem:&lt;/strong&gt; AI doesn't know what it doesn't know about your team. It generates &lt;code&gt;return Response.json(user)&lt;/code&gt; without knowing that returning a raw Prisma object is specifically something your team decided against. It's not ignoring your convention — it's unaware the convention exists.&lt;/p&gt;

&lt;p&gt;The volume problem compounds this. A developer submitting 20 PRs a week (with AI assistance) outpaces the feedback loop that worked for 3 PRs a week. Review quality degrades. Violations propagate.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Four-Layer Model for Externalizing Team Knowledge
&lt;/h2&gt;

&lt;p&gt;The solution is to move tacit knowledge from your engineers' heads into a structure your AI can persistently access.&lt;/p&gt;

&lt;p&gt;The key is separating by lifespan. Rules at different stability levels shouldn't be mixed together — updating a tool-specific setting shouldn't require touching your design philosophy, and vice versa.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;L1: Design Philosophy          (2–5 year lifespan)
    Why we make the decisions we do.
    "We optimize for correctness and observability over developer convenience."
    "Explicit over implicit: named types, no any, no magic."

L2: Technology Decisions       (1–3 years)
    What we've chosen and why.
    "Next.js App Router — no Pages Router patterns."
    "Prisma for database access. We evaluated Drizzle and chose Prisma for
     type safety and migration tooling."
    "Tailwind CSS — we decided against CSS-in-JS for bundle size reasons."

L3: Concrete Coding Rules      (6–12 months)
    How we implement things.
    Naming conventions, error handling patterns, security invariants,
    test structure, import ordering.

L4: Tool-Specific Config       (2–4 months)
    Where the rules live in your AI tool.
    CLAUDE.md (index file: 3 directives + file references),
    .mdc files for Cursor, Steering Rules for Kiro.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why separate by lifespan: updating your Claude Code plugin configuration (L4) shouldn't risk accidentally overwriting your design philosophy (L1). Adopting a new library (L2) shouldn't require rewriting your security rules (L3).&lt;/p&gt;

&lt;p&gt;Each layer has a different update frequency, different owner, and different blast radius if changed incorrectly. Keep them separate.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Codification Process
&lt;/h2&gt;

&lt;p&gt;This isn't a one-afternoon project. But it's not a six-month initiative either. Here's the process that produces results quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Knowledge Extraction
&lt;/h3&gt;

&lt;p&gt;Don't start from scratch. Your team's tacit knowledge is already encoded — in PR comments.&lt;/p&gt;

&lt;p&gt;Review the last 20 PRs in your repository. For each non-trivial comment (not typos or formatting), ask: "what convention is this enforcing?" Write it down.&lt;/p&gt;

&lt;p&gt;Then ask your senior engineers: "What would make you reject a PR immediately, without discussion?" The answers reveal your hardest conventions — the ones everyone knows but no one has documented.&lt;/p&gt;

&lt;p&gt;Finally, list every "everyone knows that" convention you can think of. If you've ever thought "obviously we don't do X here," that's a candidate.&lt;/p&gt;

&lt;p&gt;After this exercise, you'll typically have 30–60 items. Most of them have never been written down.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Classify by Layer
&lt;/h3&gt;

&lt;p&gt;For each item:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does this change when you switch AI tools? → L4&lt;/li&gt;
&lt;li&gt;Does this change when you upgrade a framework or library? → L3&lt;/li&gt;
&lt;li&gt;Does this reflect a technology choice that's lasted more than a year? → L2&lt;/li&gt;
&lt;li&gt;Does this reflect why your team makes the decisions it makes? → L1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't overthink placement. A rule that's in the wrong layer is still better than a rule that doesn't exist. You can move it later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Write for an AI Reader
&lt;/h3&gt;

&lt;p&gt;This is where most teams go wrong. They write rules that make sense to humans and assume AI can infer the intent.&lt;/p&gt;

&lt;p&gt;AI needs explicit, unambiguous rules. Compare:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Written for a human:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Use proper error handling in Server Actions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Any experienced engineer on your team knows what this means. AI doesn't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Written for an AI:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All Server Actions must return &lt;code&gt;ActionResult&amp;lt;T&amp;gt;&lt;/code&gt;. Never throw an exception from a Server Action. Return &lt;code&gt;{ success: false, error: string }&lt;/code&gt; for any failure case. The error field should be a user-readable message, not a technical error string.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The second version leaves no room for interpretation. It tells the AI exactly what to do and what not to do.&lt;/p&gt;

&lt;p&gt;The test: could a developer who's never seen your codebase follow this rule exactly right the first time? If yes, it's written for an AI reader.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Test and Iterate
&lt;/h3&gt;

&lt;p&gt;Run the same generation task with and without your codified rules. Score the output on your team's quality criteria.&lt;/p&gt;

&lt;p&gt;If the AI is still violating a rule despite it being codified, there are three likely causes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The rule is in the wrong context.&lt;/strong&gt; A security rule needs to be in context when generating API routes, not buried in a general guidelines file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The rule is too abstract.&lt;/strong&gt; Rewrite it with a concrete example. "Never return raw Prisma objects" + show a before/after pair.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The rule conflicts with another rule.&lt;/strong&gt; When two rules contradict, the AI picks arbitrarily. Find the conflict and resolve it.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Iterate until the before/after output shows consistent adherence. In my experience across several Next.js projects, 2–3 rounds per rule set is typical: the first round surfaces the biggest gaps, the second tightens ambiguous wording, and the third (if needed) resolves edge cases.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Side Effect: Forced Explicit Alignment
&lt;/h2&gt;

&lt;p&gt;Codifying tacit knowledge for AI has an unexpected benefit: it forces your team to make implicit agreements explicit.&lt;/p&gt;

&lt;p&gt;When you sit down to write "our Server Action pattern," you discover that two senior engineers have different mental models of what that pattern is. The disagreement was never surfaced because each enforced their own version in PRs and neither caught the other's violations.&lt;/p&gt;

&lt;p&gt;The codification process surfaces these gaps. You have a 30-minute conversation, align on one pattern, write it down. The disagreement is resolved. The rule is clear.&lt;/p&gt;

&lt;p&gt;Teams that go through this process tend to report:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster onboarding for new engineers (they read the guideline files, not just the code)&lt;/li&gt;
&lt;li&gt;Clearer PR reviews (reviewers reference rules, not intuition)&lt;/li&gt;
&lt;li&gt;Less ambiguity in design discussions ("does this fit our L2 technology decisions?")&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rules you write for AI become your living engineering handbook. The investment pays forward into human processes, not just AI tooling.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Compounding Payoff
&lt;/h2&gt;

&lt;p&gt;The payoff is slow at first and accelerates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Month 1:&lt;/strong&gt; Codification takes time. AI output quality improves noticeably on the rules you've defined, but you're still filling gaps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Month 3:&lt;/strong&gt; Core conventions are codified. AI output is reliably on-pattern for the common cases. Rule violations shift from "common but not obvious" to "rare and immediately visible."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Month 6:&lt;/strong&gt; New engineers join the team. Their onboarding time is shorter — they read the guideline files and get an accurate picture of the codebase's conventions. The AI and the engineers are working from the same source of truth.&lt;/p&gt;

&lt;p&gt;The rules you wrote for your AI assistant become the documentation that humans use too. The two problems — AI convention adherence and human knowledge transfer — turn out to have the same solution.&lt;/p&gt;




&lt;h2&gt;
  
  
  Starting Small
&lt;/h2&gt;

&lt;p&gt;You don't have to codify everything at once.&lt;/p&gt;

&lt;p&gt;Pick your highest-value conventions first: the ones that cause the most cleanup work when violated. For most Next.js projects, that's:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Auth patterns in API routes&lt;/li&gt;
&lt;li&gt;Server Action return types&lt;/li&gt;
&lt;li&gt;Zod schema placement and usage&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Write those three rules down. Write them for an AI reader. Test them. Those three rules, consistently applied, will eliminate more rework than an 80-rule document that's never precise enough.&lt;/p&gt;




&lt;p&gt;What's one convention in your codebase that lives only in your senior devs' heads? Drop it in the comments — these are exactly the kinds of rules that the default AI Dev OS templates are missing.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The AI Dev OS framework, including rule templates for Next.js and TypeScript, is at &lt;a href="https://github.com/yunbow/ai-dev-os" rel="noopener noreferrer"&gt;github.com/yunbow/ai-dev-os&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Next in this series: AI-Generated Code Has 2.74× More Security Vulnerabilities — Here's the Data and What to Do (link will be added on publish)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>teamwork</category>
      <category>softwareengineering</category>
      <category>aitools</category>
      <category>aidevos</category>
    </item>
    <item>
      <title>Why AI Doesn't Code What You Designed: The Structural Gap Between Specs and Implementation</title>
      <dc:creator>yunbow</dc:creator>
      <pubDate>Tue, 05 May 2026 06:29:37 +0000</pubDate>
      <link>https://dev.to/yunbow/why-ai-doesnt-code-what-you-designed-the-structural-gap-between-specs-and-implementation-5fb8</link>
      <guid>https://dev.to/yunbow/why-ai-doesnt-code-what-you-designed-the-structural-gap-between-specs-and-implementation-5fb8</guid>
      <description>&lt;p&gt;You write a detailed design doc. You paste it into your AI assistant. You wait.&lt;/p&gt;

&lt;p&gt;The output compiles. Tests pass. And yet — it's not quite what you designed. The auth middleware is in the wrong layer. The error handling pattern differs from the rest of the codebase. The field names don't match the schema.&lt;/p&gt;

&lt;p&gt;You fix it. Next task, same thing.&lt;/p&gt;

&lt;p&gt;This happens constantly, and it's not a model capability problem. &lt;strong&gt;It's a structural problem in how we communicate design intent to AI.&lt;/strong&gt; And "write better prompts" is not the solution — it's a band-aid.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why "Better Prompts" Doesn't Scale
&lt;/h2&gt;

&lt;p&gt;The instinct when AI misses the mark: add more detail to the prompt. Describe the pattern more explicitly. Give an example.&lt;/p&gt;

&lt;p&gt;This works — sometimes, for that one task.&lt;/p&gt;

&lt;p&gt;The problem: design intent isn't a single instruction. It's institutional knowledge accumulated over months. It's the reason two experienced engineers on your team write recognizably similar code without coordinating on every PR. It's the unspoken answer to "what does good look like here?"&lt;/p&gt;

&lt;p&gt;You can't fit that into a prompt. And even if you could, you'd need to paste it every single time.&lt;/p&gt;

&lt;p&gt;Think about onboarding a new engineer. You don't brief them on your entire codebase in the first conversation. You give them documentation, you pair with them, you let them absorb context over weeks. The conventions transfer gradually because there's a persistent learning mechanism.&lt;/p&gt;

&lt;p&gt;With AI, there's no persistent learning mechanism by default. Every conversation starts from scratch. Your prompt is one-time context. Your design intent is institutional knowledge that needs to live somewhere the AI can always access.&lt;/p&gt;




&lt;h2&gt;
  
  
  Three Structural Gaps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Gap 1: Implicit Conventions Stay Implicit
&lt;/h3&gt;

&lt;p&gt;Every team has them. Rules that are enforced in code review but never written down because "everyone knows that."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"We use &lt;code&gt;ActionResult&amp;lt;T&amp;gt;&lt;/code&gt; for Server Actions"&lt;/li&gt;
&lt;li&gt;"Zod schemas live in &lt;code&gt;lib/schemas/&lt;/code&gt;, not colocated with components"&lt;/li&gt;
&lt;li&gt;"Don't use &lt;code&gt;useEffect&lt;/code&gt; for data fetching — we have Server Components for that"&lt;/li&gt;
&lt;li&gt;"Always call &lt;code&gt;auth()&lt;/code&gt; before any database access in an API route"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These live in your engineers' heads. When a new hire submits a PR that violates them, a reviewer catches it and leaves a comment. The new hire learns. The knowledge transfers.&lt;/p&gt;

&lt;p&gt;AI doesn't get those review comments. It generates code, the review happens, but the AI's context doesn't update. Next task, same violation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The cost:&lt;/strong&gt; every AI output needs a manual convention-correction pass. The faster AI can generate code, the more convention-correction work piles up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gap 2: Specs Describe WHAT, Not HOW or WHY
&lt;/h3&gt;

&lt;p&gt;Your design doc says "implement user authentication with session management." Good.&lt;/p&gt;

&lt;p&gt;What it doesn't say:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auth middleware belongs in the route handler, not a global Next.js middleware&lt;/li&gt;
&lt;li&gt;Sessions are stored in the database, not JWT (because you had a security incident)&lt;/li&gt;
&lt;li&gt;Use NextAuth's &lt;code&gt;auth()&lt;/code&gt; helper, not direct session inspection&lt;/li&gt;
&lt;li&gt;All session-dependent routes return 401, not redirect to login&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These "how" and "why" constraints are the engineering culture. They're the decisions your team made, the tradeoffs you've accepted, the patterns you've settled on. A spec that describes the what gives AI enough rope to generate something plausible that violates all of the above.&lt;/p&gt;

&lt;p&gt;An AI-effective spec would include the constraints that shape implementation, not just the behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gap 3: No Feedback Loop for Rule Violations
&lt;/h3&gt;

&lt;p&gt;Human code review creates a feedback loop. Author submits code → reviewer catches violations → author adjusts → over time, author internalizes the rules.&lt;/p&gt;

&lt;p&gt;AI-generated code breaks this loop in two ways.&lt;/p&gt;

&lt;p&gt;First, the feedback doesn't persist. You can tell Claude "in this project, Server Actions always return &lt;code&gt;ActionResult&amp;lt;T&amp;gt;&lt;/code&gt;" in one conversation. Next conversation, you tell it again.&lt;/p&gt;

&lt;p&gt;Second, the volume overwhelms the feedback loop. One engineer might submit 3 PRs a week. With AI assistance, they might submit 20. Reviewers who were previously keeping up now face a backlog. Review quality degrades under volume. Violations start slipping through.&lt;/p&gt;

&lt;p&gt;At scale, violations accumulate faster than review can catch them. Plausible-but-wrong patterns spread across the codebase. Six months later, you have a refactoring problem that looks like technical debt but is actually accumulated convention drift.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Compounding Effect
&lt;/h2&gt;

&lt;p&gt;A single convention violation in one file: minor, easy to fix.&lt;/p&gt;

&lt;p&gt;10 AI-generated files with the same violation: a pattern.&lt;/p&gt;

&lt;p&gt;50 AI-generated files with diverse convention violations: an architectural consistency problem. Different error handling here, different auth patterns there, schemas mixed into component files, raw Prisma objects returned from APIs.&lt;/p&gt;

&lt;p&gt;This is the state many teams are in now — not because AI is bad, but because they're using AI without the infrastructure to give it their institutional knowledge.&lt;/p&gt;

&lt;p&gt;From retrospectives I've reviewed and conversations with teams adopting AI tools: teams without explicit guidelines consistently report spending significantly more time — often 2–4× — on "cleanup" and "consistency work" than teams with structured rule systems. A common pattern: the team celebrates 3× faster feature generation, then quietly absorbs the same hours back in review cycles, convention-fixing passes, and cross-file inconsistency cleanup. The productivity gains from AI generation are real; they're being partially eaten by convention-drift cleanup.&lt;/p&gt;




&lt;h2&gt;
  
  
  What "Design Intent" Actually Means
&lt;/h2&gt;

&lt;p&gt;When I say "design intent," I mean more than the features described in a spec. I mean:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Naming conventions and why they exist.&lt;/strong&gt; Not just "use camelCase" but "function names that fetch data start with &lt;code&gt;get&lt;/code&gt;, mutations start with &lt;code&gt;update&lt;/code&gt; or &lt;code&gt;create&lt;/code&gt;, and no function is named &lt;code&gt;handle&lt;/code&gt; because it tells you nothing."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which patterns are preferred and which are deprecated.&lt;/strong&gt; "We use Server Components for data fetching. &lt;code&gt;useEffect&lt;/code&gt; for data fetching was how we did it two years ago and there's still some in the codebase — don't follow it."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security invariants.&lt;/strong&gt; "Every external-facing API route must validate the session. This is not a preference, it's a requirement. There are no exceptions."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The tradeoffs you've accepted.&lt;/strong&gt; "We verbose-type everything even when TypeScript could infer it. We know this is more code. We've decided explicit types are worth it for this team."&lt;/p&gt;

&lt;p&gt;These don't belong in a design doc — they're too foundational, too stable. They belong in a persistent context that every AI interaction can access.&lt;/p&gt;




&lt;h2&gt;
  
  
  Rethinking What a Spec Is For
&lt;/h2&gt;

&lt;p&gt;A traditional specification document is written for humans. It describes desired behavior, UI flows, data models, and edge cases. The reader is assumed to already know your team's conventions.&lt;/p&gt;

&lt;p&gt;An AI-effective specification is different. It still describes behavior. But it also includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;constraints&lt;/strong&gt; that shape implementation ("use NextAuth, not custom JWT")&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;non-options&lt;/strong&gt; ("do not introduce a new state management library")&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;patterns&lt;/strong&gt; that must be followed ("Server Actions must follow the &lt;code&gt;ActionResult&amp;lt;T&amp;gt;&lt;/code&gt; pattern")&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;why&lt;/strong&gt; behind significant decisions ("we use Prisma's typed client because we've been burned by SQL injection in the past")&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consider the difference between these two spec sections:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Implement an API endpoint that allows authenticated users to update their profile information.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;AI-effective:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Implement an API route at &lt;code&gt;app/api/profile/route.ts&lt;/code&gt; that allows authenticated users to update their profile.&lt;/p&gt;

&lt;p&gt;Implementation constraints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;auth()&lt;/code&gt; from &lt;code&gt;@/lib/auth&lt;/code&gt; to verify the session&lt;/li&gt;
&lt;li&gt;Accept only &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;image&lt;/code&gt; fields — no other fields should be updatable via this endpoint&lt;/li&gt;
&lt;li&gt;Validate input with a Zod schema before any database operation&lt;/li&gt;
&lt;li&gt;Return &lt;code&gt;{ data: user }&lt;/code&gt; on success with only safe fields selected (no &lt;code&gt;passwordHash&lt;/code&gt;, &lt;code&gt;emailVerified&lt;/code&gt;, or internal IDs)&lt;/li&gt;
&lt;li&gt;Return &lt;code&gt;{ error: "..." }&lt;/code&gt; with appropriate HTTP status on failure&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;The second version leaves less room for AI to infer its own patterns. It specifies the how alongside the what.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Solution Direction: Externalizing Tacit Knowledge
&lt;/h2&gt;

&lt;p&gt;The fix isn't writing better prompts. It's building an infrastructure that makes your team's tacit knowledge persistent and accessible.&lt;/p&gt;

&lt;p&gt;The practical shape of this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. A persistent context file (&lt;code&gt;CLAUDE.md&lt;/code&gt; or equivalent)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Keep it to 3 directive lines — a project header, "follow these guidelines," and "upper sections take priority." The rest is a list of file references pointing to your actual rule files. This loads on every interaction, but because it's just an index, it doesn't dilute Claude's attention on your task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Guideline files for L3 specifics&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Naming conventions, security invariants, error handling patterns — these live in dedicated files (&lt;code&gt;docs/ai-dev-os/03_guidelines/common/security.md&lt;/code&gt;, etc.) and are loaded contextually when relevant. A rule submodule like &lt;code&gt;ai-dev-os-rules-typescript&lt;/code&gt; provides these for TypeScript/Next.js projects out of the box.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. AI-effective specs for larger tasks&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
For non-trivial features, include implementation constraints in the spec alongside behavioral requirements — which auth helper to use, which patterns to follow, which approaches to avoid. Write the spec like you're briefing a developer who knows nothing about your codebase's conventions.&lt;/p&gt;

&lt;p&gt;This is a systems-design problem, not a prompting problem. You design the system once. The AI operates within it on every task.&lt;/p&gt;

&lt;p&gt;The next article in this series walks through building this infrastructure for a Next.js project — step by step, with before/after code.&lt;/p&gt;




&lt;p&gt;The structural gap between specs and implementation isn't inherent to AI. It's a gap we created by giving AI our "what" without our "how."&lt;/p&gt;

&lt;p&gt;Closing it requires treating your team's conventions as infrastructure, not tribal knowledge.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's the most persistent spec-drift you've hit with AI coding tools? Drop it in the comments — I'm cataloging these to improve guideline templates.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Next in this series: &lt;a href="https://dev.to/yunbow/codifying-tacit-knowledge-the-missing-layer-between-your-teams-conventions-and-your-ai-assistant-302b"&gt;Codifying Tacit Knowledge: The Missing Layer Between Your Team's Conventions and Your AI Assistant&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Under 30-Minute Setup: AI Coding Guidelines for Your Next.js Project (Before/After Code)</title>
      <dc:creator>yunbow</dc:creator>
      <pubDate>Tue, 05 May 2026 01:49:14 +0000</pubDate>
      <link>https://dev.to/yunbow/under-30-minute-setup-ai-coding-guidelines-for-your-nextjs-project-beforeafter-code-fnp</link>
      <guid>https://dev.to/yunbow/under-30-minute-setup-ai-coding-guidelines-for-your-nextjs-project-beforeafter-code-fnp</guid>
      <description>&lt;p&gt;Your Next.js project has an AI assistant. The question isn't whether to use AI — it's whether the code it generates follows your project's conventions.&lt;/p&gt;

&lt;p&gt;This is a hands-on walkthrough. In under 30 minutes (10 via CLI, 20 manually), you'll install &lt;a href="https://github.com/yunbow/ai-dev-os" rel="noopener noreferrer"&gt;AI Dev OS&lt;/a&gt; into an existing Next.js project using Claude Code. By the end, your AI will consistently apply your naming conventions, security patterns, and architectural rules — without you reminding it every prompt.&lt;/p&gt;

&lt;p&gt;All examples show before/after code so you can see exactly what changes.&lt;/p&gt;




&lt;h2&gt;
  
  
  What You're Installing (5 min)
&lt;/h2&gt;

&lt;p&gt;AI Dev OS uses a 4-layer model. For a Next.js project, here's what goes where:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CLAUDE.md                     ← L1 + L2: Always loaded, project philosophy
.claude/guidelines/
  nextjs.md                   ← L3: App Router, Server Actions, Middleware
  typescript.md               ← L3: Type conventions, naming rules
  security.md                 ← L3: Auth patterns, input validation
.claude/commands/             ← L4: Reusable Skills for common tasks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rules you care about most day-to-day live in &lt;code&gt;guidelines/&lt;/code&gt;. They're loaded when relevant — not every single prompt — so they don't dilute Claude's attention on your actual task.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Node.js &amp;gt;= 18
Next.js &amp;gt;= 14 (App Router)
Claude Code CLI installed
TypeScript (strict mode strongly recommended)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Already have a running Next.js project? Good — work from there. Starting fresh also works.&lt;/p&gt;




&lt;h2&gt;
  
  
  Option A: CLI Setup (10 min)
&lt;/h2&gt;

&lt;p&gt;The fastest path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx ai-dev-os init &lt;span class="nt"&gt;--rules&lt;/span&gt; typescript &lt;span class="nt"&gt;--plugin&lt;/span&gt; claude-code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CLAUDE.md&lt;/code&gt; — guidelines index (3 directive lines + file references)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docs/ai-dev-os/&lt;/code&gt; — rule submodule with L1–L3 guidelines for TypeScript/Next.js&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.claude/plugins/ai-dev-os/&lt;/code&gt; — Skills, Agents, and Hooks (L4)&lt;/li&gt;
&lt;li&gt;Pre-commit hooks for automated rule verification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After it runs, open &lt;code&gt;CLAUDE.md&lt;/code&gt; and add your project-specific guideline files to the &lt;code&gt;## Project-Specific Guidelines&lt;/code&gt; section (3 files is the recommended starting point).&lt;/p&gt;

&lt;p&gt;Verify the setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx ai-dev-os doctor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output should show all guideline files detected and no configuration conflicts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Option B: Manual Setup (20 min)
&lt;/h2&gt;

&lt;p&gt;Manual setup takes longer but gives you a clear mental model of what each file does. Recommended if you want to adapt the rules heavily.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Add the rule submodule and copy the CLAUDE.md template
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Add L1–L3 rules for TypeScript/Next.js&lt;/span&gt;
git submodule add https://github.com/yunbow/ai-dev-os-rules-typescript.git docs/ai-dev-os
git submodule update &lt;span class="nt"&gt;--init&lt;/span&gt;

&lt;span class="c"&gt;# Add Claude Code plugin (Skills, Agents, Hooks)&lt;/span&gt;
git submodule add https://github.com/yunbow/ai-dev-os-plugin-claude-code.git .claude/plugins/ai-dev-os

&lt;span class="c"&gt;# Copy the CLAUDE.md template&lt;/span&gt;
&lt;span class="nb"&gt;cp &lt;/span&gt;docs/ai-dev-os/templates/nextjs/CLAUDE.md.template ./CLAUDE.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt; is an index file — 3 directive lines followed by references to guideline files in the submodule. Open it and fill in your project name, then add project-specific guideline files in the &lt;code&gt;## Project-Specific Guidelines&lt;/code&gt; section:&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;## Project-Specific Guidelines&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; docs/guidelines/your-business-rule.md
&lt;span class="p"&gt;-&lt;/span&gt; docs/guidelines/your-external-api.md
&lt;span class="p"&gt;-&lt;/span&gt; docs/guidelines/your-compliance.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3 files is the recommended starting point. Create these files in &lt;code&gt;docs/guidelines/&lt;/code&gt; and document the rules specific to your project (auth provider choices, external service integrations, business constraints).&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Understand what the submodule provides
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;docs/ai-dev-os/&lt;/code&gt; submodule already contains comprehensive L3 guidelines. Key files for a Next.js project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docs/ai-dev-os/03_guidelines/
  frameworks/nextjs/
    overview.md         ← App Router conventions, tech stack overview
    api.md              ← API route patterns (auth check, field selection)
    server-actions.md   ← ActionResult&amp;lt;T&amp;gt; pattern, Zod validation
    auth.md             ← NextAuth integration
    database.md         ← Prisma usage, no raw SQL
  common/
    security.md         ← Auth invariants, data exposure prevention
    validation.md       ← Zod schema placement and usage
    error-handling.md   ← Error patterns
    naming.md           ← Naming conventions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These files contain the concrete rules with examples — including the patterns shown in the Before/After section below. You don't write these; they come with the submodule.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Create the ActionResult type
&lt;/h3&gt;

&lt;p&gt;If you don't have it already:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// types/action.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ActionResult&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This conditional type handles the common &lt;code&gt;void&lt;/code&gt; case — Server Actions that return no data can use &lt;code&gt;return { success: true }&lt;/code&gt; without a &lt;code&gt;data&lt;/code&gt; field, while actions that return data get a fully typed &lt;code&gt;{ success: true; data: T }&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Verification: Test Before/After
&lt;/h2&gt;

&lt;p&gt;The best way to confirm your setup is working: ask Claude the same task twice — before applying guidelines, after.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test prompt:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create an API route at app/api/profile/route.ts that returns 
the current user's profile data from the database.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt; (no guidelines, typical output):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/prisma&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-user-id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Problems: takes user ID from a header (trivially spoofable), returns the entire user object including password hash and tokens, no error handling if user not found. Also note the import uses &lt;code&gt;prisma&lt;/code&gt; from &lt;code&gt;@/lib/prisma&lt;/code&gt; — in the conventions we're setting up, the db client is exposed as &lt;code&gt;db&lt;/code&gt; from &lt;code&gt;@/lib/db&lt;/code&gt; for consistency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt; (with guidelines loaded):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/auth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/db&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Unauthorized&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Not found&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Auth from session (not headers). Explicit field selection. Error cases handled. Consistent response shape.&lt;/p&gt;




&lt;h2&gt;
  
  
  Before / After: Server Action
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Test prompt:&lt;/strong&gt;&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 Server Action to update the current user's display name.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/prisma&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateDisplayName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user_id_here&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Problems: hardcoded placeholder ID, no validation, no auth, no return value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ActionResult&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/types/action&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/auth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/db&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UpdateNameSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name is required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name too long&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateDisplayName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormData&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ActionResult&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Unauthorized&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;UpdateNameSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safeParse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Loading Guidelines in Practice
&lt;/h2&gt;

&lt;p&gt;The Skills bundled with &lt;code&gt;ai-dev-os-plugin-claude-code&lt;/code&gt; handle contextual loading automatically. For example, the &lt;code&gt;/api&lt;/code&gt; skill loads the relevant framework and security guidelines before generating code.&lt;/p&gt;

&lt;p&gt;You can also reference guidelines directly in your prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@docs/ai-dev-os/03_guidelines/frameworks/nextjs/server-actions.md
Create a Server Action to update the current user's display name.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or add a project-specific skill in &lt;code&gt;.claude/commands/api.md&lt;/code&gt; that loads your project-specific rules alongside the framework guidelines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Load the API and security guidelines, then complete the task:

@docs/ai-dev-os/03_guidelines/frameworks/nextjs/api.md
@docs/ai-dev-os/03_guidelines/common/security.md
@docs/guidelines/your-business-rule.md

Task: $ARGUMENTS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now in Claude Code: &lt;code&gt;/api Create a route for updating user preferences&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Add your project-specific rules.&lt;/strong&gt; The submodule provides the framework-level rules. Create &lt;code&gt;docs/guidelines/&lt;/code&gt; files for your project's business logic, external API integrations, and compliance requirements — these go in the &lt;code&gt;## Project-Specific Guidelines&lt;/code&gt; section of &lt;code&gt;CLAUDE.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Commit the submodule reference to git.&lt;/strong&gt; Team members who clone the repo run &lt;code&gt;git submodule update --init --recursive&lt;/code&gt; and get the full guideline set automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep the submodule updated.&lt;/strong&gt; Run &lt;code&gt;git submodule update --remote docs/ai-dev-os&lt;/code&gt; to pull the latest rules, or pin to a specific version with &lt;code&gt;git checkout v1.x.x&lt;/code&gt; inside the submodule.&lt;/p&gt;




&lt;p&gt;The full ruleset (with Python/FastAPI support) is at &lt;a href="https://github.com/yunbow/ai-dev-os" rel="noopener noreferrer"&gt;github.com/yunbow/ai-dev-os&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What Next.js patterns does your team enforce that keep slipping through AI-generated code? I'm collecting edge cases to improve the default ruleset.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>typescript</category>
      <category>aitools</category>
      <category>aidevos</category>
    </item>
    <item>
      <title>200 Lines in CLAUDE.md Dropped My Code Quality to 79% — Splitting into 3 Files Got It to 96.9%</title>
      <dc:creator>yunbow</dc:creator>
      <pubDate>Mon, 04 May 2026 00:29:54 +0000</pubDate>
      <link>https://dev.to/yunbow/200-lines-in-claudemd-dropped-my-code-quality-to-79-splitting-into-3-files-got-it-to-969-1glm</link>
      <guid>https://dev.to/yunbow/200-lines-in-claudemd-dropped-my-code-quality-to-79-splitting-into-3-files-got-it-to-969-1glm</guid>
      <description>&lt;p&gt;More rules should mean better output. That's the intuition.&lt;/p&gt;

&lt;p&gt;I spent weeks building a comprehensive &lt;code&gt;CLAUDE.md&lt;/code&gt; — 200 lines covering naming conventions, security rules, error handling, architectural patterns, import ordering, type safety requirements, and more. I was proud of it. I'd thought through every scenario.&lt;/p&gt;

&lt;p&gt;Then I scored the output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;79.0 / 100.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My carefully crafted documentation was actively making AI performance worse. Here's the experiment, what I found, and how restructuring it to 4 files (the original &lt;code&gt;CLAUDE.md&lt;/code&gt; trimmed to ~35 lines, plus 3 topic-specific guideline files) pushed the score to &lt;strong&gt;96.9&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Experiment
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Project:&lt;/strong&gt; Next.js 14 + TypeScript + Prisma + NextAuth&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I measured:&lt;/strong&gt; Code quality across 5 dimensions, scored by a structured rubric applied to 20 generated files (mix of API routes, Server Actions, components, utility functions). I applied the rubric manually — each file scored 0–100 per dimension, then averaged across all files. All generation tasks used the same prompts to isolate the config variable:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;What was scored&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Naming&lt;/td&gt;
&lt;td&gt;Variable names, function names, file naming — match project conventions?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;td&gt;Auth checks present, input validation, no sensitive data exposure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error handling&lt;/td&gt;
&lt;td&gt;Consistent pattern, proper types, no silent failures&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Type safety&lt;/td&gt;
&lt;td&gt;No &lt;code&gt;any&lt;/code&gt;, proper inference, Zod schemas where needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test coverage&lt;/td&gt;
&lt;td&gt;Unit tests generated alongside implementation files&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Baseline:&lt;/strong&gt; 200-line monolithic &lt;code&gt;CLAUDE.md&lt;/code&gt; containing all rules&lt;/p&gt;




&lt;h2&gt;
  
  
  Why More Rules Made Things Worse
&lt;/h2&gt;

&lt;p&gt;I expected a positive correlation: more rules → better adherence. I got the opposite. Here's why.&lt;/p&gt;

&lt;h3&gt;
  
  
  Position sensitivity
&lt;/h3&gt;

&lt;p&gt;Claude reads the entire &lt;code&gt;CLAUDE.md&lt;/code&gt; on every interaction. A 200-line file isn't huge in absolute terms, but attention is not uniformly distributed across a long document. Rules near the end — in my case, security invariants starting at line 160 — received demonstrably less weight than rules at the top.&lt;/p&gt;

&lt;p&gt;In my tests, moving the security section from line 160 to line 20 pushed security scores from 68% to 81% — without changing a single rule. The content was identical. Position was the only variable.&lt;/p&gt;

&lt;p&gt;Why: the user's prompt arrives at the end of the context window. Rules at the bottom of &lt;code&gt;CLAUDE.md&lt;/code&gt; are immediately adjacent to the prompt and compete with everything above them for the model's attention during generation. The further up a rule is, the less it competes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule conflicts
&lt;/h3&gt;

&lt;p&gt;When L1 philosophy rules and L3 specific rules live in the same file, conflicts appear. My L1 section said "prefer explicitness." My L3 section said "keep implementations concise." When generating a Server Action, the AI had to arbitrate between these — and sometimes picked the wrong tradeoff for the context.&lt;/p&gt;

&lt;h3&gt;
  
  
  The result by dimension
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;200-line CLAUDE.md&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Naming&lt;/td&gt;
&lt;td&gt;81%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;td&gt;68%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error handling&lt;/td&gt;
&lt;td&gt;77%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Type safety&lt;/td&gt;
&lt;td&gt;82%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test coverage&lt;/td&gt;
&lt;td&gt;86%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Overall&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;79.0%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Security being the lowest made sense in retrospect. Security rules are naturally verbose and were buried at the bottom.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Fix: Two-Tier Context
&lt;/h2&gt;

&lt;p&gt;The insight: &lt;code&gt;CLAUDE.md&lt;/code&gt; should contain only what the AI needs to know for &lt;strong&gt;every single interaction&lt;/strong&gt;. Everything else should be loaded on demand.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CLAUDE.md                         ← Always loaded (3 directive lines + file refs)
docs/ai-dev-os/03_guidelines/
  frameworks/nextjs/              ← Next.js App Router, Server Actions, etc.
  common/security.md              ← Auth patterns, input validation
  common/validation.md            ← Zod usage
  ...                             ← Referenced from CLAUDE.md
docs/guidelines/                  ← Your project-specific rules (3 files recommended)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The rule of thumb:&lt;/strong&gt; &lt;code&gt;CLAUDE.md&lt;/code&gt; is an index file, not a rules file. Keep it to 3 lines of directives and a list of file references. The actual rules live in the referenced files.&lt;/p&gt;

&lt;h3&gt;
  
  
  What CLAUDE.md looks like
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Project: [Your App Name] - Claude Code Guidelines&lt;/span&gt;

Please write code following the guidelines below for this project.
In case of conflicts, upper sections take priority.

&lt;span class="gu"&gt;## Development Guidelines&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; docs/ai-dev-os/03_guidelines/frameworks/nextjs/overview.md - Overview &amp;amp; tech stack
&lt;span class="p"&gt;-&lt;/span&gt; docs/ai-dev-os/03_guidelines/frameworks/nextjs/server-actions.md - Server Actions (ActionResult pattern)
&lt;span class="p"&gt;-&lt;/span&gt; docs/ai-dev-os/03_guidelines/common/security.md - Security
&lt;span class="p"&gt;-&lt;/span&gt; docs/ai-dev-os/03_guidelines/common/validation.md - Validation
&lt;span class="p"&gt;-&lt;/span&gt; docs/ai-dev-os/03_guidelines/common/error-handling.md - Error handling
...

&lt;span class="gu"&gt;## Project-Specific Guidelines&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; docs/guidelines/your-business-rule.md
&lt;span class="p"&gt;-&lt;/span&gt; docs/guidelines/your-external-api.md
&lt;span class="p"&gt;-&lt;/span&gt; docs/guidelines/your-compliance.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it — 3 directive lines, then file references. The philosophy, coding conventions, and security invariants are all in the referenced files in &lt;code&gt;docs/ai-dev-os/&lt;/code&gt;, which come from the rule submodule.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the topic files contain
&lt;/h3&gt;

&lt;p&gt;The submodule (&lt;code&gt;ai-dev-os-rules-typescript&lt;/code&gt;) provides:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docs/ai-dev-os/03_guidelines/common/security.md&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every auth pattern with examples&lt;/li&gt;
&lt;li&gt;Field selection rules for Prisma queries&lt;/li&gt;
&lt;li&gt;Input validation requirements&lt;/li&gt;
&lt;li&gt;Rate limiting requirements for auth endpoints&lt;/li&gt;
&lt;li&gt;Logging requirements for security events&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;docs/ai-dev-os/03_guidelines/frameworks/nextjs/server-actions.md&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server Action patterns with full examples (&lt;code&gt;ActionResult&amp;lt;T&amp;gt;&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Middleware structure&lt;/li&gt;
&lt;li&gt;Data fetching patterns (no &lt;code&gt;useEffect&lt;/code&gt; for data)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;docs/ai-dev-os/03_guidelines/common/naming.md&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Import ordering&lt;/li&gt;
&lt;li&gt;Type naming conventions&lt;/li&gt;
&lt;li&gt;Error type definitions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your project-specific rules go into &lt;code&gt;docs/guidelines/&lt;/code&gt; — 3 files is the recommended starting point.&lt;/p&gt;

&lt;h3&gt;
  
  
  Loading on demand
&lt;/h3&gt;

&lt;p&gt;In Claude Code, the Skills bundled with the plugin (&lt;code&gt;ai-dev-os-plugin-claude-code&lt;/code&gt;) handle contextual loading automatically. For manual invocation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Load the Next.js guidelines, then complete the task:

@docs/ai-dev-os/03_guidelines/frameworks/nextjs/overview.md
@docs/ai-dev-os/03_guidelines/common/security.md

Task: $ARGUMENTS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage: &lt;code&gt;/nextjs Create an API route for updating user preferences&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For Cursor: the Cursor plugin (&lt;code&gt;.cursor/rules/&lt;/code&gt;) provides scoped &lt;code&gt;.mdc&lt;/code&gt; files with &lt;code&gt;globs&lt;/code&gt; patterns — no manual setup needed after running the CLI.&lt;/p&gt;

&lt;p&gt;For Kiro: the Kiro plugin copies steering rules to &lt;code&gt;.kiro/steering/&lt;/code&gt; with appropriate &lt;code&gt;include&lt;/code&gt; conditions — no manual configuration needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  After the Split
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;200-line CLAUDE.md&lt;/th&gt;
&lt;th&gt;File-reference split&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Naming&lt;/td&gt;
&lt;td&gt;81%&lt;/td&gt;
&lt;td&gt;98%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;td&gt;68%&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error handling&lt;/td&gt;
&lt;td&gt;77%&lt;/td&gt;
&lt;td&gt;97%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Type safety&lt;/td&gt;
&lt;td&gt;82%&lt;/td&gt;
&lt;td&gt;99%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test coverage&lt;/td&gt;
&lt;td&gt;86%&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Overall&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;79.0%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;96.9%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Security improved the most: from 68% to 95%. Moving security rules to a dedicated file and explicitly loading them for auth/API work meant they were in context when they mattered and not diluting attention when they didn't.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Refactor Your Own CLAUDE.md
&lt;/h2&gt;

&lt;p&gt;If yours has grown to 100+ lines, here's the audit process I used:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Categorize every rule&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go through your &lt;code&gt;CLAUDE.md&lt;/code&gt; line by line and tag each rule:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;[always]&lt;/code&gt; — needs to apply to every single generated line&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[task:X]&lt;/code&gt; — only relevant when working on task type X&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[rarely]&lt;/code&gt; — edge case that doesn't need to be in persistent context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Move all rules to topic files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Rules in &lt;code&gt;[task:X]&lt;/code&gt; and &lt;code&gt;[rarely]&lt;/code&gt; move to dedicated files (&lt;code&gt;security.md&lt;/code&gt;, &lt;code&gt;testing.md&lt;/code&gt;, etc.) in &lt;code&gt;docs/guidelines/&lt;/code&gt; or a rule submodule. Replace the inline content in &lt;code&gt;CLAUDE.md&lt;/code&gt; with file references.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Reduce CLAUDE.md to 3 directive lines + references&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt; should contain:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A project header&lt;/li&gt;
&lt;li&gt;"Please write code following the guidelines below."&lt;/li&gt;
&lt;li&gt;"In case of conflicts, upper sections take priority."&lt;/li&gt;
&lt;li&gt;A list of file references (not inline rules)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If &lt;code&gt;CLAUDE.md&lt;/code&gt; still has inline rules rather than file references, you haven't finished the refactor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Set up loading mechanisms&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude Code: The &lt;code&gt;ai-dev-os-plugin-claude-code&lt;/code&gt; plugin includes Skills and Agents that load the relevant guideline files contextually&lt;/li&gt;
&lt;li&gt;Cursor: The &lt;code&gt;ai-dev-os-plugin-cursor&lt;/code&gt; provides scoped &lt;code&gt;.mdc&lt;/code&gt; files with &lt;code&gt;globs&lt;/code&gt; patterns&lt;/li&gt;
&lt;li&gt;Kiro: The &lt;code&gt;ai-dev-os-plugin-kiro&lt;/code&gt; installs steering rules into &lt;code&gt;.kiro/steering/&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Score before and after&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the same 5–10 generation tasks with your old config and your new config. If you don't have a formal rubric, just note which rules are adhered to. You'll see the pattern.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Counter-Intuitive Takeaway
&lt;/h2&gt;

&lt;p&gt;The impulse to "add more to your CLAUDE.md" when you notice rule violations is natural — and usually wrong.&lt;/p&gt;

&lt;p&gt;If the AI isn't following a rule, the first question isn't "should I add more detail?" It's "is this rule in the right place?" If it's a convention only relevant to one type of task, moving it to a topic file and loading it contextually will do more than elaborating on it in the always-on context.&lt;/p&gt;

&lt;p&gt;Less in &lt;code&gt;CLAUDE.md&lt;/code&gt;. More in the right place at the right time.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Next in the series: &lt;a href="https://dev.to/yunbow/under-30-minute-setup-ai-coding-guidelines-for-your-nextjs-project-beforeafter-code-fnp"&gt;30-Minute Setup: AI Coding Guidelines for Your Next.js Project&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aitools</category>
      <category>codequality</category>
      <category>devtools</category>
      <category>aidevos</category>
    </item>
    <item>
      <title>Why High-Context Culture Makes AI Coding Harder — A Japanese Developer's Perspective</title>
      <dc:creator>yunbow</dc:creator>
      <pubDate>Sun, 03 May 2026 12:10:41 +0000</pubDate>
      <link>https://dev.to/yunbow/why-high-context-culture-makes-ai-coding-harder-a-japanese-developers-perspective-123a</link>
      <guid>https://dev.to/yunbow/why-high-context-culture-makes-ai-coding-harder-a-japanese-developers-perspective-123a</guid>
      <description>&lt;p&gt;I'm a software engineer in Japan. I've been using AI coding assistants — Claude Code, Cursor, Copilot — for about one years now.&lt;/p&gt;

&lt;p&gt;At some point I started keeping informal notes on how many prompt revisions it took to get production-quality output. After a few months, a pattern was hard to ignore.&lt;/p&gt;

&lt;p&gt;For tasks I described in Japanese: &lt;strong&gt;4–6 revisions on average.&lt;/strong&gt;&lt;br&gt;
Watching colleagues who worked primarily in English: &lt;strong&gt;1–3.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Same AI. Same model. Roughly similar task complexity. Different language — and apparently, different results.&lt;/p&gt;

&lt;p&gt;I started asking why.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Most Invisible Problem in a High-Context Language
&lt;/h2&gt;

&lt;p&gt;Japanese ranks among the world's most high-context languages. What that means practically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Subject omission is grammatically normal. "Did it" is a complete sentence. Who did what to whom lives in context.&lt;/li&gt;
&lt;li&gt;Vague expressions are socially preferred over explicit ones. "Somehow it feels off" is a complete critique in a code review.&lt;/li&gt;
&lt;li&gt;Politeness layers add indirection at every level. Direct requests sound rude. Softened requests carry meaning only if you know what's being softened.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this is a flaw. It's a communication system that works — between humans who share context.&lt;/p&gt;

&lt;p&gt;AI assistants do not share your context.&lt;/p&gt;

&lt;p&gt;When I write "please handle this appropriately," I know what "appropriately" means in my codebase. My AI assistant does not. It makes its best guess, which is informed by the global distribution of code it was trained on — not by the six months of implicit decisions my team has accumulated.&lt;/p&gt;

&lt;p&gt;The result is plausible-looking code that misses the point in ways that take hours to diagnose.&lt;/p&gt;


&lt;h2&gt;
  
  
  The 6 Tacit Knowledge Zones
&lt;/h2&gt;

&lt;p&gt;After talking to engineers across Japanese dev teams, I found the same blind spots appearing in almost every organization:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Documentation that doesn't document&lt;/strong&gt;&lt;br&gt;
Formats vary by author. Files go months without updates. The real spec lives in Slack DMs and someone's memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Team rules that exist only in senior developers' heads&lt;/strong&gt;&lt;br&gt;
Coding conventions exist in practice — enforced silently in code review, never written down because "everyone knows."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Security as an afterthought&lt;/strong&gt;&lt;br&gt;
Security is something you consider before release, not during development. The AI doesn't know this is your team's operating assumption. It will skip security considerations unless explicitly prompted — which you won't do if you don't think about it mid-task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Task management via word of mouth&lt;/strong&gt;&lt;br&gt;
The real priority queue is the one your team lead carries in their head and communicates in standup. The ticket system is a formality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Testing without test cases&lt;/strong&gt;&lt;br&gt;
You test the happy path manually before shipping. Edge cases are discovered in production. The AI will generate code that matches this standard — because you didn't specify otherwise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Operations knowledge locked in one person&lt;/strong&gt;&lt;br&gt;
When something breaks at 2am, one person knows what to do. That person's knowledge doesn't exist anywhere else.&lt;/p&gt;

&lt;p&gt;Notice what these have in common: &lt;strong&gt;they're not the absence of knowledge. They're knowledge that lives in exactly one place — a person's head — and will disappear when that person leaves.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Why AI Makes This Worse, Not Better
&lt;/h2&gt;

&lt;p&gt;The instinctive argument: "AI will fix this — it generates more documentation, writes more consistent code."&lt;/p&gt;

&lt;p&gt;The reality is the opposite.&lt;/p&gt;

&lt;p&gt;AI is excellent at transforming explicit knowledge into more explicit knowledge. Give it a well-defined spec and it produces well-defined code. Give it a type definition and it generates a correctly-typed implementation.&lt;/p&gt;

&lt;p&gt;What AI cannot do is extract tacit knowledge from the environment. It cannot interview your senior engineer. It cannot observe your code review culture. It cannot infer that your team decided six months ago that &lt;code&gt;useEffect&lt;/code&gt; for data fetching was banned after a painful production incident — because that decision exists only in the memory of the three people who were there.&lt;/p&gt;

&lt;p&gt;When you give an AI assistant a vague prompt, it fills the gaps. It uses the global distribution of code patterns it learned during training. That distribution doesn't include your team's specific decisions.&lt;/p&gt;

&lt;p&gt;The higher your tacit knowledge density — and high-context organizations tend to have higher tacit knowledge density — the larger the gap between what you intend and what the AI produces.&lt;/p&gt;


&lt;h2&gt;
  
  
  A Scenario That's More Common Than It Should Be
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;The following is a fictional but composite scenario based on failure patterns I've seen and read about. The system and people are made up. The mechanisms are real.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A team builds a medical appointment system. Development moves fast — AI-assisted, one month to MVP.&lt;/p&gt;

&lt;p&gt;What gets missed in the first week: domain knowledge. The engineers don't know that insurance category codes have a specific format. They don't know that doctor license numbers have validation rules. The AI doesn't ask. No one thinks to tell it.&lt;/p&gt;

&lt;p&gt;By month one: the same appointment conflict logic has been implemented in three different places, each slightly differently, because three developers each asked the AI to "handle booking conflicts" without knowing the others had done it. The AI gave each of them a reasonable implementation.&lt;/p&gt;

&lt;p&gt;Security holes accumulate invisibly. Patient records are accessible without proper authorization checks because the prompt said "fetch appointments for this user" and didn't say "verify the requesting user has access to this patient's records." The AI did exactly what was asked.&lt;/p&gt;

&lt;p&gt;The system ships. In the first week, a researcher discovers they can access any patient's records by modifying the URL parameter. The system goes offline.&lt;/p&gt;

&lt;p&gt;When the team tries to fix it, they discover that the implicit business logic — the stuff that existed only in the product manager's head — was never written down. No one knows what the correct behavior is for edge cases anymore.&lt;/p&gt;

&lt;p&gt;The CTO spends the next three months rebuilding from scratch, this time writing the spec before writing the code.&lt;/p&gt;

&lt;p&gt;The lesson isn't "don't use AI." The lesson is: &lt;strong&gt;the bottleneck in AI-assisted development isn't writing code. It's making implicit knowledge explicit before the AI touches anything.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  What Actually Shifts the Outcome
&lt;/h2&gt;

&lt;p&gt;I've been working on an open-source framework called &lt;a href="https://github.com/yunbow/ai-dev-os" rel="noopener noreferrer"&gt;AI Dev OS&lt;/a&gt; that's essentially a structured answer to this problem. But the framework is less important than the underlying principle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Prompt in the language that minimizes ambiguity for the task&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is uncomfortable to write as a Japanese developer, but: for technical specification, English or highly explicit Japanese outperforms natural conversational Japanese. Not because English is better, but because technical communication benefits from low-context precision.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❌  「いい感じに処理してください」
✅  「ユーザーがPOSTした画像ファイルを、
    サーバーサイドでWebP形式に変換して
    S3バケット {env.BUCKET_NAME} に保存してください。
    ファイルサイズ上限は5MB。超過はValidationErrorを返すこと。」
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Write down the thing that "everyone knows" before you prompt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The most valuable five minutes before any significant AI-assisted task: write one paragraph of the rules that your senior developer would enforce in code review. Not a full spec — just the implicit decisions that would otherwise live in their head and filter silently through review.&lt;/p&gt;

&lt;p&gt;Put it in a &lt;code&gt;CLAUDE.md&lt;/code&gt; file or &lt;code&gt;.cursorrules&lt;/code&gt;. Make it persistent. Now the AI has access to your context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Spec before code, always&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ask the AI to write the specification first: input/output types, error cases, security assumptions, business rules. Review it. Then ask for the implementation.&lt;/p&gt;

&lt;p&gt;The friction this adds is real. The bugs it prevents are also real — and much more expensive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Treat tacit knowledge as an organizational risk, not a personal style&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When the person who holds the knowledge leaves, it's gone. An AI tool that depends on that person's mental model in every prompt is inheriting that fragility.&lt;/p&gt;

&lt;p&gt;The act of writing down team conventions isn't documentation overhead. It's risk reduction.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Question Worth Asking Your Team
&lt;/h2&gt;

&lt;p&gt;What's the most important unwritten rule in your codebase right now?&lt;/p&gt;

&lt;p&gt;Not the stuff in your linting config or your CONTRIBUTING.md. The real rule — the one a senior engineer would catch in review but that exists nowhere in text.&lt;/p&gt;

&lt;p&gt;If you can name it, you can write it down. If you can write it down, your AI assistant can follow it.&lt;/p&gt;

&lt;p&gt;That one rule, made explicit, is worth more than any prompt engineering technique I've found.&lt;/p&gt;

&lt;p&gt;For what it's worth: the thing I wrote down that made the biggest difference was two sentences. "Server Actions always return &lt;code&gt;ActionResult&amp;lt;T&amp;gt;&lt;/code&gt;. Never throw from a Server Action." Six months of drift, fixed by two sentences in a markdown file.&lt;/p&gt;

&lt;p&gt;Start there.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I built &lt;a href="https://github.com/yunbow/ai-dev-os" rel="noopener noreferrer"&gt;AI Dev OS&lt;/a&gt; to systematize this process for Next.js + TypeScript projects. It's open source — the framework, the templates, the reasoning. If this resonated, that's where the implementation lives.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What's the unwritten rule in your codebase? I'm genuinely curious — drop it in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>culture</category>
      <category>aitools</category>
      <category>aidevos</category>
    </item>
    <item>
      <title>AI Dev OS</title>
      <dc:creator>yunbow</dc:creator>
      <pubDate>Sun, 03 May 2026 08:07:56 +0000</pubDate>
      <link>https://dev.to/yunbow/ai-dev-os-m4i</link>
      <guid>https://dev.to/yunbow/ai-dev-os-m4i</guid>
      <description>&lt;p&gt;Articles&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/yunbow/i-built-an-oss-to-stop-ai-from-writing-inconsistent-code-every-time-claude-code-cursor-kiro-1oe1"&gt;I Built an OSS to Stop AI from Writing Inconsistent Code Every Time (Claude Code / Cursor / Kiro)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/yunbow/why-high-context-culture-makes-ai-coding-harder-a-japanese-developers-perspective-123a"&gt;Why High-Context Culture Makes AI Coding Harder — A Japanese Developer's Perspective&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/yunbow/under-30-minute-setup-ai-coding-guidelines-for-your-nextjs-project-beforeafter-code-fnp"&gt;200 Lines in CLAUDE.md Dropped My Code Quality to 79% — Splitting into 3 Files Got It to 96.9%&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/yunbow/under-30-minute-setup-ai-coding-guidelines-for-your-nextjs-project-beforeafter-code-fnp"&gt;Under 30-Minute Setup: AI Coding Guidelines for Your Next.js Project (Before/After Code)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/yunbow/why-ai-doesnt-code-what-you-designed-the-structural-gap-between-specs-and-implementation-5fb8"&gt;Why AI Doesn't Code What You Designed: The Structural Gap Between Specs and Implementation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/yunbow/why-ai-doesnt-code-what-you-designed-the-structural-gap-between-specs-and-implementation-5fb8"&gt;Why AI Doesn't Code What You Designed: The Structural Gap Between Specs and Implementation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/yunbow/codifying-tacit-knowledge-the-missing-layer-between-your-teams-conventions-and-your-ai-assistant-302b"&gt;Codifying Tacit Knowledge: The Missing Layer Between Your Team's Conventions and Your AI Assistant&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/yunbow/code-review-is-broken-for-ai-generated-code-the-case-for-pre-implementation-governance-43h5"&gt;Code Review Is Broken for AI-Generated Code — The Case for Pre-Implementation Governance&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>I Built an OSS to Stop AI from Writing Inconsistent Code Every Time (Claude Code / Cursor / Kiro)</title>
      <dc:creator>yunbow</dc:creator>
      <pubDate>Sun, 03 May 2026 04:07:06 +0000</pubDate>
      <link>https://dev.to/yunbow/i-built-an-oss-to-stop-ai-from-writing-inconsistent-code-every-time-claude-code-cursor-kiro-1oe1</link>
      <guid>https://dev.to/yunbow/i-built-an-oss-to-stop-ai-from-writing-inconsistent-code-every-time-claude-code-cursor-kiro-1oe1</guid>
      <description>&lt;p&gt;"Write a function to fetch the list of users." — same prompt, same codebase.&lt;/p&gt;

&lt;p&gt;Yesterday: &lt;code&gt;getUsers()&lt;/code&gt;. Today: &lt;code&gt;fetchUserList()&lt;/code&gt;. Tomorrow: &lt;code&gt;loadAllUsers()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Six months of AI-assisted coding and I kept hitting this wall. My initial reaction was "maybe I need to write better prompts." I wrote better prompts. The functions got slightly better. New inconsistencies appeared elsewhere.&lt;/p&gt;

&lt;p&gt;The problem wasn't the AI's capability. It was that &lt;strong&gt;I had never given it my team's unwritten rules.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That realization led me to build &lt;strong&gt;AI Dev OS&lt;/strong&gt; — an open-source framework that converts implicit developer knowledge into explicit, enforceable rules for AI coding assistants. It supports Claude Code, Cursor, and Kiro (Amazon's AI-native IDE).&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/yunbow/ai-dev-os" rel="noopener noreferrer"&gt;github.com/yunbow/ai-dev-os&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Root Problem: "Almost Correct" Is the Most Expensive Output
&lt;/h2&gt;

&lt;p&gt;When an AI produces obviously wrong code, you catch it immediately and discard it. Not a big deal.&lt;/p&gt;

&lt;p&gt;When an AI produces &lt;em&gt;almost correct&lt;/em&gt; code — code that compiles, passes basic tests, looks reasonable — you merge it. Six months later, your codebase has three error handling patterns, four naming styles, and no one is sure which is canonical.&lt;/p&gt;

&lt;p&gt;That's the real cost. Not obvious errors. Plausible drift.&lt;/p&gt;

&lt;p&gt;Here's why this happens structurally: your AI assistant has no access to your team's conventions by default. It doesn't know that you use &lt;code&gt;ActionResult&amp;lt;T&amp;gt;&lt;/code&gt; for Server Actions, that Zod schemas live in &lt;code&gt;lib/schemas/&lt;/code&gt; and not colocated with components, that you've banned &lt;code&gt;useEffect&lt;/code&gt; for data fetching. These conventions exist in your engineers' heads and in unwritten PR review culture — nowhere an AI can read.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Switching to a more capable model doesn't fix this.&lt;/strong&gt; A more capable model without your conventions just produces more fluent drift.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Solution: A 4-Layer Rule Framework
&lt;/h2&gt;

&lt;p&gt;The core insight of AI Dev OS: rules have different lifespans, and mixing them into one file is what causes fragility.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────┐
│  L1: Design Philosophy          (2–5 year lifespan)     │
│      "We optimize for correctness and observability     │
│       over developer convenience"                       │
│                                                         │
│  L2: Technology Decisions       (1–3 years)             │
│      "Next.js App Router, Prisma, Zod, NextAuth"        │
│      "We use Tailwind — no CSS-in-JS"                   │
│                                                         │
│  L3: Concrete Coding Rules      (6–12 months)           │
│      Naming conventions, error handling patterns,       │
│      security invariants, test structure                │
│                                                         │
│  L4: Tool-Specific Config       (2–4 months)            │
│      CLAUDE.md, .cursor/.mdc files, Kiro Steering Rules │
└─────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why does this matter? When you update your AI tool's configuration (L4), you shouldn't risk destabilizing your design philosophy (L1). When you adopt a new library (L2), you shouldn't have to rewrite your security rules (L3). Separating by lifespan makes updates surgical.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 7-Repository Structure
&lt;/h2&gt;

&lt;p&gt;AI Dev OS is distributed across 7 repositories, each with a clear responsibility:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ai-dev-os                     ← Core specification and theory     [available]
ai-dev-os-rules-typescript    ← L1–L3 rules for TypeScript / Next.js  [available]
ai-dev-os-rules-python        ← L1–L3 rules for Python / FastAPI  [available]
ai-dev-os-plugin-claude-code  ← L4: Skills, Agents, Hooks for Claude Code  [available]
ai-dev-os-plugin-cursor       ← L4: .mdc rules for Cursor         [available]
ai-dev-os-plugin-kiro         ← L4: Steering Rules for Kiro       [available]
ai-dev-os-cli                 ← init / update / doctor commands   [available]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;You don't need all of them.&lt;/strong&gt; If you're using Claude Code with TypeScript, you need &lt;code&gt;ai-dev-os-rules-typescript&lt;/code&gt; and &lt;code&gt;ai-dev-os-plugin-claude-code&lt;/code&gt;. Pick what fits your stack.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Get Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Option A: CLI (10 minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx ai-dev-os init &lt;span class="nt"&gt;--rules&lt;/span&gt; typescript &lt;span class="nt"&gt;--plugin&lt;/span&gt; claude-code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CLAUDE.md&lt;/code&gt; — guidelines index referencing your rule files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docs/ai-dev-os/&lt;/code&gt; — rule submodule (L1–L3)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.claude/plugins/ai-dev-os/&lt;/code&gt; — Skills, Agents, Hooks (L4)&lt;/li&gt;
&lt;li&gt;Pre-commit hooks for automated rule verification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verify the setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx ai-dev-os doctor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Option B: Manual (20 minutes, more control)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Add the rule submodule and copy the &lt;code&gt;CLAUDE.md&lt;/code&gt; template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git submodule add https://github.com/yunbow/ai-dev-os-rules-typescript.git docs/ai-dev-os
&lt;span class="nb"&gt;cp &lt;/span&gt;docs/ai-dev-os/templates/nextjs/CLAUDE.md.template ./CLAUDE.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt; is an index file — 3 lines of directives plus references to the guideline files in the submodule. Add your project-specific rules (3 files recommended) in the &lt;code&gt;## Project-Specific Guidelines&lt;/code&gt; section:&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;## Project-Specific Guidelines&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; docs/guidelines/your-business-rule.md
&lt;span class="p"&gt;-&lt;/span&gt; docs/guidelines/your-external-api.md
&lt;span class="p"&gt;-&lt;/span&gt; docs/guidelines/your-compliance.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Add the Claude Code plugin for Skills, Agents, and Hooks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git submodule add https://github.com/yunbow/ai-dev-os-plugin-claude-code.git .claude/plugins/ai-dev-os
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Code loads &lt;code&gt;CLAUDE.md&lt;/code&gt; automatically on every interaction. The guideline files referenced within it are read on demand.&lt;/p&gt;




&lt;h2&gt;
  
  
  Before / After: What This Actually Changes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  API Route
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt; (no guidelines):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/api/users/route.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findMany&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Problems: no auth check, exposes all user fields including sensitive ones, no error handling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt; (with AI Dev OS):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/api/users/route.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/auth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/db&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Unauthorized&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findMany&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Auth check. Field selection. Consistent response shape. The AI generated this without being asked because the rules made it the default.&lt;/p&gt;

&lt;h3&gt;
  
  
  Server Action
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Problems: no validation, no error handling, &lt;code&gt;name&lt;/code&gt; is typed as &lt;code&gt;FormDataEntryValue | null&lt;/code&gt;, hardcoded ID.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ActionResult&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/types/action&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/auth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/db&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UpdateUserSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormData&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ActionResult&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Unauthorized&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;UpdateUserSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safeParse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every Server Action in the codebase now follows this pattern — not because individual developers remember to, but because the AI enforces it by default.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Effect Over Time
&lt;/h2&gt;

&lt;p&gt;The value compounds. After 2 weeks with AI Dev OS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every new API route has auth checks and field selection&lt;/li&gt;
&lt;li&gt;Every Server Action validates input and returns &lt;code&gt;ActionResult&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;PR reviews stop being about convention enforcement and start being about logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After 2 months, a new engineer joining the project reads the guideline files and understands the codebase's patterns — because those patterns are now consistently applied everywhere, including the AI-generated portions.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Isn't
&lt;/h2&gt;

&lt;p&gt;AI Dev OS won't catch logical bugs. It won't validate your business rules. It won't replace code review.&lt;/p&gt;

&lt;p&gt;What it does: ensure the AI produces code that matches your codebase's established patterns. The output is still yours to review — but you're reviewing logic, not convention drift.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check out the core spec&lt;/span&gt;
git clone https://github.com/yunbow/ai-dev-os

&lt;span class="c"&gt;# Or start with the TypeScript rules&lt;/span&gt;
git clone https://github.com/yunbow/ai-dev-os-rules-typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you've been hitting the inconsistency wall and want to talk through how to adapt the rules for your stack — drop a comment. What conventions does your team enforce that your AI assistant keeps ignoring?&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>aitools</category>
      <category>opensource</category>
      <category>aidevos</category>
    </item>
  </channel>
</rss>
