{"id":33828,"date":"2026-06-01T20:23:39","date_gmt":"2026-06-01T18:23:39","guid":{"rendered":"https:\/\/www.angulararchitects.io\/?p=33828"},"modified":"2026-06-01T20:35:19","modified_gmt":"2026-06-01T18:35:19","slug":"reliable-angular-architectures-with-ai-assisted-coding","status":"publish","type":"post","link":"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/","title":{"rendered":"Reliable Angular Architectures with AI-assisted Coding"},"content":{"rendered":"<p>Coding agents now write code faster than we can read it. That is great for speed \u2013 and acutely dangerous for the architecture. Because, by default, a language model optimizes for &quot;it works&quot;, not for &quot;it fits our target architecture&quot;. If no one steers against it, the quickly generated data access lands right inside the component, cross-references between domains creep in, and the painstakingly established structure softens commit by commit.<\/p>\n<p>The good news: precisely these guardrails can be described today in a way that the coding agent not only knows but also follows \u2013 and so that it receives deterministic, machine-generated feedback on violations, which it uses to correct itself.<\/p>\n<p><em>AI-assisted coding needs architecture as an executable contract: documented in Rules, activated through task-specific context, checked by Sheriff, and fed back via Hooks.<\/em><\/p>\n<p>In this article I show what that looks like in practice. It is about <strong>providing context for the architecture<\/strong>, <strong>integrating architecture checks like Sheriff into the AI's feedback loop<\/strong>, and setting all of this up so that it works <strong>across multiple platforms<\/strong> such as Cursor AI, Claude Code, Codex (GPT), or Google's Antigravity CLI. We integrate the <strong>official Angular Skills<\/strong> and the <strong>MCP server of the Angular CLI<\/strong>, account for the <strong>NgRx Signal Store<\/strong>, add <strong>custom Skills<\/strong>, and in the end also bring in <strong>ADRs<\/strong> and other documented decisions.<\/p>\n<p>\ud83d\udcc2 <a href=\"https:\/\/github.com\/angular-architects\/flights42\/tree\/ai-arc\">Source Code<\/a> (Branch: <code>ai-arc<\/code>)<\/p>\n<h2>Target Architecture: Domains and Layers in Angular<\/h2>\n<p>Before an AI can adhere to an architecture, we have to define that architecture. Our example structures the application into <strong>domains<\/strong>: domains reduce cognitive load, because when working on a feature you only need to care about a manageable slice, and they support team organization, because responsibilities can be cleanly delineated.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/matrix.png\" alt=\"Architecture matrix: domains such as Booking, Boarding, and Shared, each split into the layers Feature, UI, Data, and Util\" \/><\/p>\n<p>The matrix shows the principle. Each column is a domain, each row a layer. A <strong>Feature<\/strong> is a business use case, typically with smart components that orchestrate the use case. <strong>UI<\/strong> contains reusable, &quot;dumb&quot; components. <strong>Data<\/strong> takes care of data access and data models, <strong>Util<\/strong> of technical helper functions. Cutting across all of this, there is a <strong>Shared<\/strong> domain for code that several domains need.<\/p>\n<p>The permitted accesses are decisive: layers may only access one another from top to bottom (<code>feature \u2192 ui \u2192 data \u2192 util<\/code>), and <strong>domains do not access one another directly<\/strong>. Anyone who needs code from another domain either uses the Shared domain or an API that offers targeted access to selected parts of a domain.<\/p>\n<p>Building on this, we rely on <strong>Feature Slicing<\/strong>. The idea is locality: code that belongs only to one feature also lives in the feature folder \u2013 including feature-local dumb components, stores, and helper functions. This keeps cognitive load low, because related code sits together. The downside is just as real: if local code is suddenly needed elsewhere, it has to be refactored, that is, moved into a more global area. We will see later how exactly this moving can be nicely automated with AI-assisted coding.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/feature-slicing2.png\" alt=\"Feature Slicing: features keep their own UI, Data, and Util code local until it is needed by several features\" \/><\/p>\n<p>The image makes clear that Feature Slicing is not all that far from the pure matrix. It simply additionally allows feature-local UI, Data, and Util building blocks that only move into a deeper, shared layer once they are actually needed by several features.<\/p>\n<h2>Validating the Architecture Matrix with Sheriff<\/h2>\n<p>An architecture that exists only in a presentation does not survive a single sprint. That is why we enforce the matrix with <a href=\"https:\/\/github.com\/softarc-consulting\/sheriff\">Sheriff<\/a>. Sheriff assigns tags to folders \u2013 such as <code>domain:ticketing<\/code> and <code>type:data<\/code> \u2013 and defines rules about which tags may access which. If you don't comply, you get a linting error: right as you type in the IDE and on the console.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/sheriff.png\" alt=\"Console output of &quot;ng lint&quot;: Sheriff reports that the checkin domain may not access type:data of the ticketing domain\" \/><\/p>\n<p>The message is pleasingly concrete: the module <code>domains\/checkin\/feature-checkin<\/code> may not access <code>domains\/ticketing\/data<\/code>, because <code>domain:checkin<\/code> has no permission for <code>domain:ticketing, type:data<\/code>. It is exactly this precision that is the key to the next step \u2013 because such an error is not only feedback for developers, but also excellent, deterministic feedback for the language model. We will see in a moment how the coding agent picks up this message and corrects its code on its own.<\/p>\n<p>How to set up such an architecture with Sheriff and standalone components in detail is described in the article <a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/modern-architectures-with-angular-part-1-strategic-design-with-sheriff-and-standalone-components\/\">Modern Architectures with Angular \u2013 Strategic Design with Sheriff<\/a>.<\/p>\n<h2>Providing Context: Rules<\/h2>\n<p>A coding agent is only as good as the context it gets. Without explicit guidance the model guesses \u2013 and when in doubt it guesses the mainstream style from its training data, not our conventions. Context is therefore not a nice-to-have, but the prerequisite for generated code to fit our architecture at all.<\/p>\n<p>Angular itself provides the entry point. The framework generates an <code>AGENTS.md<\/code> with the most important cornerstones for modern Angular \u2013 signals, standalone components, <code>inject()<\/code>, native control flow, and much more. That is an excellent starting point that we don't have to reinvent.<\/p>\n<p>Cursor AI reads its guidelines from the <code>.cursor\/rules<\/code> folder. So that we don't duplicate rules, our Cursor-specific rule <code>cursor.mdc<\/code> points to <code>AGENTS.md<\/code> as the authoritative source:<\/p>\n<pre><code class=\"language-markdown\">---\nalwaysApply: true\n---\n\nAlways follow the guidelines defined in the `AGENTS.md` file in the project root.\nIt is the authoritative source for coding standards, conventions, and best practices.\nIn case of conflicts, the rules in `AGENTS.md` take precedence.<\/code><\/pre>\n<p>The <code>alwaysApply: true<\/code> in the frontmatter ensures that this rule applies to every request \u2013 and the actual content only points to <code>AGENTS.md<\/code>. This already brings clear roles for the individual artifacts into focus:<\/p>\n<ul>\n<li><code>AGENTS.md<\/code> contains the red lines and short references \u2013 not the full detailed rules.<\/li>\n<li><code>docs\/architecture-boundaries.md<\/code> is the source of truth for domains, layering, feature slicing, shared code, public APIs, and Sheriff rules.<\/li>\n<li><code>docs\/architecture-state-management.md<\/code> is the source of truth for store and state-management conventions.<\/li>\n<\/ul>\n<p>So the full detailed rules should not be duplicated in <code>AGENTS.md<\/code>. In short:<\/p>\n<p><em>Docs contain the binding architecture and coding rules. AGENTS.md names the most important red lines and points to the relevant rules. Task-specific context is only pulled in when the task at hand needs it.<\/em><\/p>\n<p>Behind this is a deliberate decision about context size: the more that permanently sits in the prompt, the higher the cost, the distraction, and the risk of context pollution. That is why only short always-on rules belong in <code>AGENTS.md<\/code> or in always-on rules. The detailed rules stay in <code>docs\/architecture-boundaries.md<\/code> and <code>docs\/architecture-state-management.md<\/code> and are read for matching tasks or activated via rules, prompts, or \u2013 later \u2013 Skills. We pick up this idea again in the section on Skills.<\/p>\n<p>In Cursor, rules can apply permanently, take effect via file patterns, be selected by the agent based on their description, or be referenced explicitly. With that, <code>.mdc<\/code> files already move toward task-specific context steering: short red lines stay visible at all times, detailed rules are only activated when the task needs them. Concretely, the <code>.mdc<\/code> files under <code>.cursor\/rules<\/code> point to <code>docs\/architecture-boundaries.md<\/code> and <code>docs\/architecture-state-management.md<\/code> and help the agent take them into account for matching tasks.<\/p>\n<p>With other tools like Claude Code we achieve the same effect via prompting: in local instruction files we tell the agent what to load when \u2013 for example <code>docs\/architecture-boundaries.md<\/code> for structural changes and <code>docs\/architecture-state-management.md<\/code> for store tasks. Instead of carrying every detailed rule along permanently, the matching rule is pulled in for the matching task. We'll look at the concrete implementation via <code>CLAUDE.md<\/code> and <code>src\/CLAUDE.md<\/code> further below.<\/p>\n<p>The full files can be looked up on GitHub if needed: <a href=\"https:\/\/github.com\/angular-architects\/flights42\/blob\/ai-arc\/.cursor\/rules\/architecture.mdc\"><code>architecture.mdc<\/code><\/a>, <a href=\"https:\/\/github.com\/angular-architects\/flights42\/blob\/ai-arc\/docs\/architecture-boundaries.md\"><code>docs\/architecture-boundaries.md<\/code><\/a>, and <a href=\"https:\/\/github.com\/angular-architects\/flights42\/blob\/ai-arc\/docs\/architecture-state-management.md\"><code>docs\/architecture-state-management.md<\/code><\/a>.<\/p>\n<h2>General Architecture Rules<\/h2>\n<p>With the architecture rules, the decisive thing is that we capture the tricky spots unambiguously. The most important rules in brief:<\/p>\n<ul>\n<li>The <strong>Sheriff configuration<\/strong> may only be changed on explicit request. In particular, it may not be weakened just to satisfy the linter.<\/li>\n<li><strong>Feature Slicing:<\/strong> feature-local code is to be preferred. If it is later needed elsewhere too, it is to be moved into a deeper layer.<\/li>\n<li><strong>New domains<\/strong> may only be added on explicit request. The model may, however, propose new domains.<\/li>\n<li><strong>Moving code into the Shared area<\/strong> is only allowed if the user agrees to it or explicitly requests it. The rule of thumb: shared is a deliberate architectural decision, not a fallback folder for import problems.<\/li>\n<li>The same applies to <strong>publishing code for other domains via APIs<\/strong>. In this case, additional Sheriff rules allow access to an <code>api\/index.ts<\/code> with selected exports in a neighboring domain.<\/li>\n<li>New code for new use cases should follow the structure of a few already existing, good <strong>reference use cases<\/strong> (such as <code>FlightSearch<\/code> and <code>FlightEdit<\/code>). In practice this has proven surprisingly effective.<\/li>\n<\/ul>\n<h2>Specific Rules for State Management<\/h2>\n<p>The rules for the Signal Store are explicit as well. Among other things, they specify:<\/p>\n<ul>\n<li>From the <a href=\"https:\/\/ngrx-toolkit.angulararchitects.io\/\">NgRx Toolkit<\/a>, use <code>withResource<\/code>, <code>withMutations<\/code>, and the dev tools support (<code>withDevtools<\/code>).<\/li>\n<li>The store delegates data access to a data-access service and does not access the backend itself.<\/li>\n<li>There are clearly delineated kinds of stores: for the <strong>entities of a search list<\/strong> (<code>&lt;Entity&gt;SearchStore<\/code>), for the <strong>entity of a detail view<\/strong> (<code>&lt;Entity&gt;DetailStore<\/code>), for <strong>lookup entities<\/strong> or suggestion values (<code>&lt;Feature&gt;LookupStore<\/code>), and for <strong>UI state<\/strong>.<\/li>\n<li>A store only gets access to another store if the user agrees.<\/li>\n<\/ul>\n<h2>Naming Conventions<\/h2>\n<p>Not every guideline can be sensibly expressed through layering and Sheriff. If you tried, the configuration would quickly become unwieldy. That is why we additionally rely on naming conventions that are easy to describe and easy for the model to check.<\/p>\n<p>A good example is access to the store. Only <strong>smart components<\/strong> may use a store, and in our project you recognize smart components by the suffixes <code>Page<\/code>, <code>Search<\/code>, <code>Detail<\/code>, and <code>Edit<\/code> \u2013 such as <code>FlightSearch<\/code> or <code>FlightEdit<\/code>.<\/p>\n<p>These conventions are likewise captured in the rules. Especially now that, in modern Angular, components no longer carry the not-very-meaningful default suffix <code>Component<\/code>, it pays off to use suffixes for such semantics \u2013 for human and machine alike.<\/p>\n<h2>Context on Demand: Angular Skills and MCP Servers<\/h2>\n<p>If we put the entire context into the prompt all the time, it would quickly become overloaded, expensive, and unwieldy. With rules we already use case-specific loading in part: in Cursor, for example, via file patterns, descriptions, or explicit references, and with Claude Code via corresponding prompting rules. <strong>Skills<\/strong> take this idea further by bundling task-specific knowledge and recurring workflows.<\/p>\n<p>Skills thus encapsulate task-specific knowledge and concrete workflows. Depending on the tool, they can be activated automatically or explicitly. This leads to a clear division of labor:<\/p>\n<p><em>Docs contain the binding architecture and coding rules. Skills describe how an agent should proceed for specific tasks. AGENTS.md names the most important red lines and points to the relevant rules.<\/em><\/p>\n<p>Skills therefore point to the docs but do not duplicate them: <code>docs\/architecture-boundaries.md<\/code> and <code>docs\/architecture-state-management.md<\/code> remain the binding detailed rules, while a Skill describes the matching workflow for them.<\/p>\n<p>The Angular community provides official Skills that are regularly adapted to the respective current framework version. We install them with the Skills CLI:<\/p>\n<pre><code class=\"language-bash\">npx skills add https:\/\/github.com\/angular\/skills<\/code><\/pre>\n<p>This places the Skills <code>angular-developer<\/code> and <code>angular-new-app<\/code> in the <code>.agents\/skills\/<\/code> folder \u2013 a convention that has established itself across tools. A <code>skills-lock.json<\/code> records which version is installed, so that updates can be applied in a traceable way.<\/p>\n<p>This very pattern can be applied to our own rules. For the state-management conventions from <code>docs\/architecture-state-management.md<\/code>, a task-specific <code>signal-store<\/code> Skill is a good additional fit. The <code>docs\/architecture-state-management.md<\/code> remains the binding source for store conventions; the Skill points to it and describes the concrete workflow for typical tasks: when a new store makes sense, which store type to choose, where the store should live, which existing stores serve as references, and which checks to run after the change. So the rule itself stays in the project documentation; the Skill describes how the agent should concretely proceed on store tasks.<\/p>\n<p>By the way, the same pattern can be applied to the architecture rules as well: instead of activating <code>docs\/architecture-boundaries.md<\/code> only via file-pattern rules and prompting, a dedicated architecture Skill could just as well take on this job and kick in on structural changes. The role separation remains decisive \u2013 the Skill describes the workflow and points to the docs as the binding source; it does not become the source of truth itself. The rule therefore still lives in <code>docs\/architecture-boundaries.md<\/code>, and the Skill merely points to it.<\/p>\n<p>In addition, the <strong>MCP server of the Angular CLI<\/strong> is useful. MCP (Model Context Protocol) is an open standard through which a coding agent can access external tools and knowledge sources. Among other things, the Angular MCP server provides the agent with well-curated examples and access to the current documentation \u2013 ideal for hitting best practices even when the model's training data is already somewhat dated.<\/p>\n<p>In Cursor AI we set up the server via the file <code>.cursor\/mcp.json<\/code>:<\/p>\n<pre><code class=\"language-json\">{\n  &quot;mcpServers&quot;: {\n    &quot;angular-cli&quot;: {\n      &quot;command&quot;: &quot;npx&quot;,\n      &quot;args&quot;: [&quot;-y&quot;, &quot;@angular\/cli&quot;, &quot;mcp&quot;]\n    }\n  }\n}<\/code><\/pre>\n<p>With that, the Angular MCP server is available to the agent as soon as it needs it.<\/p>\n<h2>Bringing Architecture Checks into the AI Feedback Loop via Hooks<\/h2>\n<p>Up to here we have taught the model a lot. But knowledge alone is not enough \u2013 we need a deterministic safety net that checks every round of the agent. That is exactly what <strong>Hooks<\/strong> are for.<\/p>\n<p>In Cursor AI we set up a <strong>stop hook<\/strong>. It kicks in when the agent thinks it is done, and beforehand runs a Node script that runs the linter, tests, and build. Sheriff is also integrated via the linter \u2013 so our architecture matrix is checked by machine on every round. The configuration sits in <code>.cursor\/hooks.json<\/code>:<\/p>\n<pre><code class=\"language-json\">{\n  &quot;version&quot;: 1,\n  &quot;hooks&quot;: {\n    &quot;stop&quot;: [\n      {\n        &quot;command&quot;: &quot;node scripts\/ci-checks.mjs&quot;,\n        &quot;timeout&quot;: 600,\n        &quot;loop_limit&quot;: 3\n      }\n    ]\n  }\n}<\/code><\/pre>\n<p>The invoked script <code>scripts\/ci-checks.mjs<\/code> is deliberately kept simple and runs the three relevant steps one after another:<\/p>\n<pre><code class=\"language-js\">import { execSync } from &#039;node:child_process&#039;;\n\nconst steps = [\n  &#039;npx ng lint flights&#039;,\n  &#039;npx ng test flights --configuration ci&#039;,\n  &#039;npx ng build flights&#039;,\n];\n\nfor (const step of steps) {\n  console.log(`\\n[ci-checks] ${step}`);\n  execSync(step, { stdio: &#039;inherit&#039; });\n}<\/code><\/pre>\n<p>If one of these steps fails \u2013 for example because Sheriff reports an architecture violation, a test is red, or the build breaks \u2013 the agent goes into a new round. It receives the error message as input and tries to fix it. The <code>loop_limit<\/code> of three limits how often this loop repeats, so that the agent doesn't circle endlessly.<\/p>\n<p>In larger repositories you can stagger the checks: first fast checks like lint and Sheriff, then targeted tests, and only for bigger changes or before the merge the full build. This keeps the safety net in place without making every round unnecessarily expensive.<\/p>\n<p>The fact that it is a <strong>Node script<\/strong> is a deliberate decision: this way the same check runs platform-independently on macOS, Linux, and Windows.<\/p>\n<p>A small but important difference in the behavior of the tools: Cursor reports visibly when the script is executed. Claude Code does not \u2013 there you only notice it when an error occurs.<\/p>\n<p><div style=\"\nmargin: 8px 0;\npadding: 22px;\nborder: 1px solid #e5e7eb;\nborder-radius: 14px;\nbackground: #f8fafc;\n\">NOTE<\/p>\n<h3 style=\"margin-top:0\">Modern Angular<\/h3>\n<p>You'll find more on Signal Forms and modern Angular architecture in my new eBook Modern Angular. It covers signals, architecture, testing, AI assistants, and practical solutions for modern business applications.<\/p>\n<p><a href=\"https:\/\/www.angulararchitects.io\/modern-book\"><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/01\/cover-klein.png\" width=\"400\" alt=\"Modern Angular - Signal-first, Architecture-first, Practice-first\" style=\"cursor:pointer !important\"><\/a><\/p>\n<p><a style=\"cursor:pointer !important\" href=\"https:\/\/www.angulararchitects.io\/modern-book\">More about the book \u2192<\/a>\n<\/div>\n<\/p>\n<h2>Serving Cursor AI and Claude Code from a Single Source of Truth<\/h2>\n<p>It is not uncommon for developers to be allowed to choose their own tools. And this is exactly where a practical problem lurks: different environments expect Rules, Skills, and MCP servers in different folders and under different file names. With Claude Code, for instance, Rules live in <code>CLAUDE.md<\/code>, Skills under <code>.claude\/skills\/<\/code>, and MCP servers are configured in <code>.mcp.json<\/code>.<\/p>\n<p>But we want to keep <strong>a single source of truth<\/strong> rather than maintaining every guideline multiple times. The solution depends on the respective artifact.<\/p>\n<p>For the <strong>Rules<\/strong> we solve it elegantly via references: the <code>CLAUDE.md<\/code> in the project root essentially consists only of a reference to <code>AGENTS.md<\/code>:<\/p>\n<pre><code class=\"language-markdown\">@AGENTS.md<\/code><\/pre>\n<p>In addition, a <code>src\/CLAUDE.md<\/code> points to the architecture documentation. So there is still only one authoritative source that all tools point to.<\/p>\n<pre><code class=\"language-markdown\">Before changing application or library code here, read `docs\/architecture-boundaries.md` and apply the architecture rules.\n\nIf the change touches state management, also read `docs\/architecture-state-management.md` when it exists.\n\nDo not bypass documented domain boundaries. Prefer small, focused changes.<\/code><\/pre>\n<p>This is the concrete implementation of the prompting approach mentioned earlier: instead of &quot;always read all architecture rules&quot;, we phrase the guidance case-specifically. In effect: use <code>docs\/architecture-boundaries.md<\/code> when you make structural changes \u2013 for example to domains, layers, imports, shared code, public APIs, or Sheriff rules. Use <code>docs\/architecture-state-management.md<\/code> when you create or change stores. This way not every detailed rule sits in the context permanently, but is pulled in for the matching task.<\/p>\n<p>The following image summarizes how Claude Code and Cursor AI obtain their context: both always load their entry rules (<code>CLAUDE.md<\/code> and <code>cursor.mdc<\/code>, respectively) and thus the <code>AGENTS.md<\/code>, while the detailed <code>docs\/<\/code> files are loaded only on demand.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/ai-context-loading.svg\" alt=\"Context loading compared: Claude Code and Cursor AI always load their entry rules (CLAUDE.md and cursor.mdc) and the AGENTS.md, while the detailed docs\/ files are loaded only on demand\" \/><\/p>\n<p>For <strong>Skills and MCP configuration<\/strong> this reference trick does not work \u2013 here the files actually have to live in both places. Symlinks would be the obvious choice, but they behave differently between Windows and Linux\/macOS and, in our experience, cause friction. That is why we instead copy the files with a small <a href=\"https:\/\/github.com\/angular-architects\/flights42\/blob\/ai-arc\/scripts\/sync-agent-config.mjs\">Node script<\/a>. It mirrors <code>.agents\/skills\/<\/code> to <code>.claude\/skills\/<\/code> and <code>.cursor\/mcp.json<\/code> to <code>.mcp.json<\/code>.<\/p>\n<p>So that no one accidentally edits the generated copies, the script additionally creates two <code>DO_NOT_EDIT<\/code> files \u2013 one in the mirrored Skills folder and one for the MCP configuration. They point out unmistakably that changes here will be overwritten on the next sync and must instead be made in the respective source.<\/p>\n<p>So that the script runs reliably, we hook it into the usual lifecycles: it is executed via npm's <code>prepare<\/code> script (that is, after <code>npm install<\/code>) and additionally triggered via a pre-commit hook as soon as one of the sources has changed. This way the copies stay up to date automatically, without anyone having to think about it.<\/p>\n<h2>Extending to GPT, Codex CLI, Google Antigravity, and Beyond<\/h2>\n<p>Many current coding agents and agent tools now orient themselves around similar conventions: an <code>AGENTS.md<\/code> describes project-wide instructions, Skills often live in a dedicated Skills directory, and MCP servers are registered via tool-specific configuration files. The details, however, differ from tool to tool \u2013 for example with hooks, local instruction files, or the MCP configuration. For instance, Codex expects the MCP configuration in a TOML file (such as <code>.codex\/config.toml<\/code>), while Antigravity uses a JSON format (such as <code>mcp_config.json<\/code>).<\/p>\n<p>That is why we treat <code>AGENTS.md<\/code>, <code>.agents\/skills\/<\/code>, and our MCP base configuration as central sources and let a small sync script generate the required target formats from them. When another tool is added, usually only this script has to be extended. Since the script is deliberately kept simple, this very adjustment is an excellent fit for AI-assisted coding: the agent can look up the documentation of the new tool, derive the required target format, and extend the sync script accordingly.<\/p>\n<p>This is exactly where language models play to their strength: they are remarkably good at adapting our existing setup to the current conventions of additional coding agents. You can simply ask the agent to consult the documentation of the new tool, derive the matching target format, and extend the sync script accordingly \u2013 so connecting another tool itself becomes a task for AI-assisted coding.<\/p>\n<h2>AI-assisted Coding in Action: Generating a New Feature<\/h2>\n<p>Enough theory \u2013 let's see the setup in action. In the coding agent we request that we also want to manage <strong>Airports<\/strong> going forward. For simplicity, these are kept directly in memory, in a data-access service named <code>AirportClient<\/code>. In addition, we want to be able to select the airports from dropdown fields when maintaining flights.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/arc01.png\" alt=\"Architecture after the first step: the features airports and booking each have their own store but share the AirportClient in the data layer\" style=\"max-width: 700px\" \/><\/p>\n<p>The result is impressive. The two features <code>airports<\/code> and <code>booking<\/code> each get their own store \u2013 and that is exactly right, because the features have different state. A filter in one feature should not affect the other. (If that were desired after all, we would have to reflect it in <code>architecture-boundaries.md<\/code>.) Both stores, however, use the same <code>AirportClient<\/code> in the data layer.<\/p>\n<p>If the agent were to violate a linting rule such as a Sheriff-based architecture constraint \u2013 or if tests or the build failed \u2013 the IDE would automatically go into a new round thanks to the stop hook, until the checks are green.<\/p>\n<p>It gets exciting when we vary the requirements. If we explicitly state that we want the same store in both features, the coding agent moves the store into the data layer on its own \u2013 exactly as we described it in <code>architecture-boundaries.md<\/code>. In doing so, it incidentally solves one of the central challenges of Feature Slicing: the refactoring, that is, moving local code into more global areas once it actually becomes necessary.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/arc02.png\" alt=\"Architecture after the refactoring: store and client were moved together into the data layer, so that both features use the same store\" style=\"max-width: 700px\" \/><\/p>\n<p>As long as we stay within the same domain, the agent may refactor the code according to the documented rules \u2013 such as the move of the store into the data layer shown earlier. It gets even more interesting when we also want to reuse the <code>AirportClient<\/code> in the <code>checkin<\/code> domain. Now domain boundaries are affected, and exactly then the agent has to ask. The agent confronts us with a question \u2013 and that is intentional. In <code>architecture-boundaries.md<\/code> we specified that in exactly this case consultation is required, because cross-domain access is a deliberate architectural decision. Possible options are then, for example: move the code to <code>shared<\/code>, publish it via a public API of the <code>ticketing<\/code> domain, or cut the requirement differently.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/question-refactoring.png\" alt=\"The agent asks a follow-up question: should the AirportClient be provided via the public API of the ticketing domain or moved into the shared area?\" style=\"max-width: 700px\" \/><\/p>\n<p>If we decide to move the <code>AirportClient<\/code> into the shared area, the result looks like above: both domains now access the shared code in <code>shared<\/code>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/arc03.png\" alt=\"Architecture after moving the AirportClient into the shared area\" style=\"max-width: 700px\" \/><\/p>\n<p>If we instead choose the API path, the <code>AirportClient<\/code> stays in the <code>ticketing<\/code> domain and is published via an <code>api\/index.ts<\/code>. To this end, the agent adjusts the Sheriff configuration so that <code>domain:checkin<\/code> gets access to <code>domain:ticketing\/api<\/code> \u2013 but only to the selected, released elements there:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/api01.png\" alt=\"Architecture when using an API: the checkin domain accesses the AirportClient via the published API of the ticketing domain\" style=\"max-width: 700px\" \/><\/p>\n<h2>Refining Rules and Skills Iteratively<\/h2>\n<p>An honest assessment is part of the picture: creating good Rules and Skills is not a one-time act, but an <strong>iterative process<\/strong>. If the agent does something you don't want, these files need to be sharpened and made more concrete. By the way, language models and coding agents help excellently with this too \u2013 you can simply ask them to turn an undesired behavior into a more precise rule.<\/p>\n<p>In our experience, it also depends strongly on the model used how strictly and explicitly you have to phrase things. Some models follow even brief hints, others need unambiguous, almost pedantic guidance. It pays off to calibrate the rule set to the model actually in use.<\/p>\n<h2>Saved Prompts and Plan Mode<\/h2>\n<p>From practice, two more recommendations that can make the difference between frustration and flow. First, I've had good experiences with <strong>saved prompts<\/strong> that I pull into the chat when needed. This helps enormously with iterative refinement and especially with analogous follow-up tasks.<\/p>\n<p>Second, I like to first have the agent explicitly <strong>plan<\/strong> \u2013 via the plan mode that many IDEs now offer \u2013 and only then release the plan for implementation. This way misunderstandings can be cleared up before a single line of code is written.<\/p>\n<h2>Custom Skills: Running an Architecture Review<\/h2>\n<p>Refined prompts can also be developed into custom Skills. We are not limited to generating code here \u2013 we can also use them for recurring tasks such as an <strong>architecture review<\/strong>. Our own Skill for this lives under <a href=\"https:\/\/github.com\/angular-architects\/flights42\/blob\/ai-arc\/.agents\/skills\/architecture-review\/SKILL.md\"><code>.agents\/skills\/architecture-review\/SKILL.md<\/code><\/a> and is deliberately compact:<\/p>\n<pre><code class=\"language-markdown\">---\nname: architecture-review\ndescription: Review Angular code against the repository architecture rules in docs\/architecture-boundaries.md, including Sheriff boundaries, layering, feature slicing, shared code, and state management conventions.\n---\n\n# Review Angular Architecture\n\nUse this skill when reviewing Angular code for architectural quality.\n\nBefore reviewing, read:\n\n- `docs\/architecture-boundaries.md`\n- `AGENTS.md` if present\n- `docs\/architecture-state-management.md` if state management is involved\n- the relevant Sheriff configuration\n- the changed files and their imports\n\nTreat `docs\/architecture-boundaries.md` as the source of truth.\n...<\/code><\/pre>\n<p>The Skill makes <code>docs\/architecture-boundaries.md<\/code> the authoritative source, prescribes a clear review process, and describes the desired output format \u2013 from the summary, through findings by severity, to the concrete fix. This turns a vague &quot;have a look&quot; into a reproducible review.<\/p>\n<p>The review is started with a simple prompt:<\/p>\n<pre><code>Perform an architecture review for the new airport-related features (skill architecture-review).<\/code><\/pre>\n<p>You don't strictly have to name the Skill. But anyone who wants to make absolutely sure that the coding agent uses exactly this Skill can name it explicitly.<\/p>\n<h2>More Context: ADRs and MCP Servers for Confluence and Co.<\/h2>\n<p>Architectural decisions almost always have a backstory: why relaxed layering? Why Feature Slicing? Teams capture these rationales in <strong>Architecture Decision Records (ADRs)<\/strong>. In the branch <code>ai-arc-adr<\/code> we bring in such ADRs \u2013 for example around relaxed layering, domains, Feature Slicing, and state management.<\/p>\n<p>Here it matters not to stuff the agent's context unnecessarily full. If we delivered all ADRs permanently, it would come at the cost of clarity and token budget. That is why we <strong>derive concise rules from the ADRs<\/strong> \u2013 this too works well with language models \u2013 and <strong>link<\/strong> from these rules back to the detailed ADRs, so that the coding agent can look things up when needed. In <code>docs\/architecture-boundaries.md<\/code> this looks roughly like:<\/p>\n<pre><code class=\"language-markdown\">## Shared Code\n\n_(derived from [ADR-0004](adr\/0004-feature-slicing-and-shared-code.md))_\n\n- Promote code to a shared area only when at least two independent features require it.\n- Avoid premature shared abstractions.\n\n## State Management\n\n_(derived from [ADR-0003](adr\/0003-ngrx-signal-store-for-state.md))_\n\n- Follow `docs\/architecture-state-management.md` where applicable.<\/code><\/pre>\n<p>So the rule sits compactly in the context, while the rationale remains a click away. This keeps the prompt lean and still makes decisions traceable.<\/p>\n<p>Beyond ADRs in the repository, it pays to take a look at the tool landscape: platforms like Confluence now offer MCP servers as well. With them, the agent can, when needed, directly access decisions and guidelines documented there \u2013 without us having to copy them into the repository.<\/p>\n<h2>Conclusion<\/h2>\n<p>Reliable architectures do not emerge on their own with AI-assisted coding \u2013 they are the result of deliberately provided context. It pays to separate the roles clearly:<\/p>\n<p><em>Rules say which project rules must be visible. Skills describe how to work on a specific task. MCP provides access to external tools and knowledge sources.<\/em><\/p>\n<p>And we have to adapt to the different file conventions of various agents. To nonetheless keep a single source of truth, we use references and small scripts that copy files.<\/p>\n<p>The core story can be summarized in a simple flow:<\/p>\n<pre><code class=\"language-text\">define the architecture\n\u2192 provide context deliberately\n\u2192 check deterministically\n\u2192 feed errors back to the agent\n\u2192 the agent corrects itself\n\u2192 serve multiple tools from a single source of truth<\/code><\/pre>\n<p>At least as important is the feedback loop: a <strong>Hook<\/strong> that runs deterministic tools like Sheriff, tests, and build gives the agent a reliable, machine-generated corrective \u2013 and turns an architecture violation into an automatic correction round instead of technical debt.<\/p>\n<p>In our example, a vertical architecture with domains and Feature Slicing has proven its worth. Even the classic challenge of Feature Slicing \u2013 later moving local code into more global areas \u2013 could be solved elegantly, because the agent takes on this refactoring itself based on clear rules and consults on tricky decisions.<\/p>\n<p>And finally: it remains an iterative process. Rules and Skills grow with the experiences you gather with the respective model. Anyone willing to continuously sharpen these guardrails gets the best of both worlds \u2013 the speed of AI and the reliability of a well-thought-out architecture.<\/p>\n<h2>Learn More: Angular Architecture Workshop: AI &amp; Signals (Remote, Interactive, Advanced)<\/h2>\n<p>Become an expert in enterprise-wide and long-lived Angular applications with our Angular Architecture Workshop!<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/sujet-en.jpg\" alt=\"Angular Architecture Workshop\" style=\"width:600px; max-width:100%; display: block; margin-left: auto; margin-right:auto\" \/><\/p>\n<p><a href=\"https:\/\/www.angulararchitects.io\/en\/training\/advanced-angular-architecture-workshop\/\">German Version<\/a> | <a href=\"https:\/\/www.angulararchitects.io\/en\/training\/advanced-angular-architecture-workshop\/\">English Version<\/a><\/p>\n<h2>FAQ<\/h2>\n<p><strong>Why isn't it enough to explain the architecture to the coding agent once?<\/strong><br \/>\nBy default, a language model optimizes for working code, not for adherence to your target architecture. Without explicit, permanently available guidance (Rules) and a deterministic feedback loop (Hook with Sheriff, tests, build), the structure softens over time.<\/p>\n<p><strong>How does the architecture feedback get back to the model?<\/strong><br \/>\nVia a stop hook, the IDE runs a Node script that starts the linter (including Sheriff), tests, and build. If something fails, the agent automatically goes into a new round and corrects its code based on the concrete error message.<\/p>\n<p><strong>How do you support multiple tools like Cursor AI and Claude Code at the same time?<\/strong><br \/>\nRules are bundled via references (e.g., <code>CLAUDE.md<\/code> points to <code>AGENTS.md<\/code>), so that there is a single source of truth. Skills and MCP configuration are copied to their respective expected locations via a Node script \u2013 deliberately rather than via symlink, since symlinks behave differently across operating systems.<\/p>\n<p><strong>What is the difference between Rules, Skills, and MCP servers?<\/strong><br \/>\nRules say which project rules must be visible \u2013 short red lines permanently, detailed rules for the matching task. Skills bundle task-specific knowledge and concrete workflows and describe how an agent proceeds on specific tasks; depending on the tool, they are activated automatically or explicitly. MCP servers give the agent access to external tools and knowledge sources, such as the Angular documentation or documented decisions in Confluence.<\/p>\n<p><strong>How do ADRs fit into the picture without overloading the context?<\/strong><br \/>\nConcise rules are derived from the ADRs and live in the context; only a link points to the detailed ADRs. This keeps the prompt lean, and the agent can look up the rationale when needed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Coding agents now write code faster than we can read it. That is great for speed \u2013 and acutely dangerous for the architecture. Because, by default, a language model optimizes for &quot;it works&quot;, not for &quot;it fits our target architecture&quot;. If no one steers against it, the quickly generated data access lands right inside the [&hellip;]<\/p>\n","protected":false},"author":25,"featured_media":33818,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"footnotes":""},"categories":[18],"tags":[],"class_list":["post-33828","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Reliable Angular Architectures with AI-assisted Coding - ANGULARarchitects<\/title>\n<meta name=\"description\" content=\"AI-assisted coding writes code faster than we can review it \u2013 yet without guardrails, every architecture erodes. This article shows how to enforce a reliable Angular architecture with Rules, Skills, MCP servers, Hooks, and Sheriff, one that coding agents reliably respect \u2013 across Cursor AI, Claude Code, and beyond.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Reliable Angular Architectures with AI-assisted Coding - ANGULARarchitects\" \/>\n<meta property=\"og:description\" content=\"AI-assisted coding writes code faster than we can review it \u2013 yet without guardrails, every architecture erodes. This article shows how to enforce a reliable Angular architecture with Rules, Skills, MCP servers, Hooks, and Sheriff, one that coding agents reliably respect \u2013 across Cursor AI, Claude Code, and beyond.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/\" \/>\n<meta property=\"og:site_name\" content=\"ANGULARarchitects\" \/>\n<meta property=\"article:published_time\" content=\"2026-06-01T18:23:39+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-06-01T18:35:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/sujet-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Manfred Steyer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/sujet-1.png\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Manfred Steyer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"25 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/\"},\"author\":{\"name\":\"Manfred Steyer\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a\"},\"headline\":\"Reliable Angular Architectures with AI-assisted Coding\",\"datePublished\":\"2026-06-01T18:23:39+00:00\",\"dateModified\":\"2026-06-01T18:35:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/\"},\"wordCount\":4422,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/hero-1.png\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/\",\"name\":\"Reliable Angular Architectures with AI-assisted Coding - ANGULARarchitects\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/hero-1.png\",\"datePublished\":\"2026-06-01T18:23:39+00:00\",\"dateModified\":\"2026-06-01T18:35:19+00:00\",\"description\":\"AI-assisted coding writes code faster than we can review it \u2013 yet without guardrails, every architecture erodes. This article shows how to enforce a reliable Angular architecture with Rules, Skills, MCP servers, Hooks, and Sheriff, one that coding agents reliably respect \u2013 across Cursor AI, Claude Code, and beyond.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#primaryimage\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/hero-1.png\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/hero-1.png\",\"width\":1734,\"height\":907},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.angulararchitects.io\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Reliable Angular Architectures with AI-assisted Coding\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"name\":\"ANGULARarchitects\",\"description\":\"AngularArchitects.io\",\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\",\"name\":\"ANGULARarchitects\",\"alternateName\":\"SOFTWAREarchitects\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"width\":644,\"height\":216,\"caption\":\"ANGULARarchitects\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/github.com\/angular-architects\",\"https:\/\/www.linkedin.com\/company\/angular-architects\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a\",\"name\":\"Manfred Steyer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g\",\"caption\":\"Manfred Steyer\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Reliable Angular Architectures with AI-assisted Coding - ANGULARarchitects","description":"AI-assisted coding writes code faster than we can review it \u2013 yet without guardrails, every architecture erodes. This article shows how to enforce a reliable Angular architecture with Rules, Skills, MCP servers, Hooks, and Sheriff, one that coding agents reliably respect \u2013 across Cursor AI, Claude Code, and beyond.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/","og_locale":"en_US","og_type":"article","og_title":"Reliable Angular Architectures with AI-assisted Coding - ANGULARarchitects","og_description":"AI-assisted coding writes code faster than we can review it \u2013 yet without guardrails, every architecture erodes. This article shows how to enforce a reliable Angular architecture with Rules, Skills, MCP servers, Hooks, and Sheriff, one that coding agents reliably respect \u2013 across Cursor AI, Claude Code, and beyond.","og_url":"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/","og_site_name":"ANGULARarchitects","article_published_time":"2026-06-01T18:23:39+00:00","article_modified_time":"2026-06-01T18:35:19+00:00","og_image":[{"width":1200,"height":628,"url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/sujet-1.png","type":"image\/png"}],"author":"Manfred Steyer","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/sujet-1.png","twitter_misc":{"Written by":"Manfred Steyer","Est. reading time":"25 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#article","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/"},"author":{"name":"Manfred Steyer","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a"},"headline":"Reliable Angular Architectures with AI-assisted Coding","datePublished":"2026-06-01T18:23:39+00:00","dateModified":"2026-06-01T18:35:19+00:00","mainEntityOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/"},"wordCount":4422,"commentCount":0,"publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/hero-1.png","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/","url":"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/","name":"Reliable Angular Architectures with AI-assisted Coding - ANGULARarchitects","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#primaryimage"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/hero-1.png","datePublished":"2026-06-01T18:23:39+00:00","dateModified":"2026-06-01T18:35:19+00:00","description":"AI-assisted coding writes code faster than we can review it \u2013 yet without guardrails, every architecture erodes. This article shows how to enforce a reliable Angular architecture with Rules, Skills, MCP servers, Hooks, and Sheriff, one that coding agents reliably respect \u2013 across Cursor AI, Claude Code, and beyond.","breadcrumb":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#primaryimage","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/hero-1.png","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2026\/06\/hero-1.png","width":1734,"height":907},{"@type":"BreadcrumbList","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/reliable-angular-architectures-with-ai-assisted-coding\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.angulararchitects.io\/en\/"},{"@type":"ListItem","position":2,"name":"Reliable Angular Architectures with AI-assisted Coding"}]},{"@type":"WebSite","@id":"https:\/\/www.angulararchitects.io\/en\/#website","url":"https:\/\/www.angulararchitects.io\/en\/","name":"ANGULARarchitects","description":"AngularArchitects.io","publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.angulararchitects.io\/en\/#organization","name":"ANGULARarchitects","alternateName":"SOFTWAREarchitects","url":"https:\/\/www.angulararchitects.io\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","width":644,"height":216,"caption":"ANGULARarchitects"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/github.com\/angular-architects","https:\/\/www.linkedin.com\/company\/angular-architects\/"]},{"@type":"Person","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a","name":"Manfred Steyer","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g","caption":"Manfred Steyer"}}]}},"_links":{"self":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/33828","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/users\/25"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/comments?post=33828"}],"version-history":[{"count":3,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/33828\/revisions"}],"predecessor-version":[{"id":33831,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/33828\/revisions\/33831"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media\/33818"}],"wp:attachment":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media?parent=33828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/categories?post=33828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/tags?post=33828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}