Claude Skill

dotnet-archunitnet

Use the open-source free `ArchUnitNET` library for architecture rules in .NET tests. Use when a repo needs richer architecture assertions than lightweight fluent rule libraries usually provide.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download postpartum-genushyacinthus29-dotnet-skills-skills_dotnet-archunitnet-bfa4ebd.zip · 5 KB
Part of postpartum-genushyacinthus29/dotnet-skills — 80 skills

Install

skills CLI npx skills add https://github.com/Postpartum-genushyacinthus29/dotnet-skills/tree/main/skills/dotnet-archunitnet
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install postpartum-genushyacinthus29-dotnet-skills@llmmart
Git git clone https://github.com/Postpartum-genushyacinthus29/dotnet-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole postpartum-genushyacinthus29/dotnet-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

ArchUnitNET for .NET

Trigger On

  • the repo uses or wants ArchUnitNET
  • architecture testing needs richer modeling than simple dependency checks

Value

  • produce a concrete project delta: code, docs, config, tests, CI, or review artifact
  • reduce ambiguity through explicit planning, verification, and final validation skills
  • leave reusable project context so future tasks are faster and safer

Do Not Use For

  • the lightest possible architecture rule checks

Inputs

  • the nearest AGENTS.md
  • target assemblies
  • architecture boundaries and naming conventions

Quick Start

  1. Read the nearest AGENTS.md and confirm scope and constraints.
  2. Run this skill's Workflow through the Ralph Loop until outcomes are acceptable.
  3. Return the Required Result Format with concrete artifacts and verification evidence.

Workflow

  1. Load the architecture once per test assembly where possible.
  2. Encode a small number of durable, high-value architecture rules first.
  3. Use the test-framework-specific integration package that matches the repo.

Bootstrap When Missing

If ArchUnitNET is not configured yet:

  1. Detect existing setup:
    • rg -n "TngTech\\.ArchUnitNET" -g '*.csproj' .
  2. Add packages to the architecture test project:
    • dotnet add TEST_PROJECT.csproj package TngTech.ArchUnitNET
    • add one framework bridge package: TngTech.ArchUnitNET.xUnit, TngTech.ArchUnitNET.xUnitV3, TngTech.ArchUnitNET.MSTestV2, or TngTech.ArchUnitNET.TUnit
  3. Add at least one durable boundary rule test.
  4. Wire architecture tests into the standard test command in AGENTS.md and CI.
  5. Run dotnet test TEST_PROJECT.csproj and return status: configured or status: improved.
  6. If NetArchTest already covers the same boundary policy and no gap exists, return status: not_applicable.

Deliver

  • architecture tests with richer domain and type modeling
  • architecture-rule commands wired into repo test flow and CI expectations

Validate

  • architecture load cost is reasonable for the suite
  • rules are stable and tied to real boundaries

Ralph Loop

Use the Ralph Loop for every task, including docs, architecture, testing, and tooling work.

  1. Plan first (mandatory):
    • analyze current state
    • define target outcome, constraints, and risks
    • write a detailed execution plan
    • list final validation skills to run at the end, with order and reason
  2. Execute one planned step and produce a concrete delta.
  3. Review the result and capture findings with actionable next fixes.
  4. Apply fixes in small batches and rerun the relevant checks or review steps.
  5. Update the plan after each iteration.
  6. Repeat until outcomes are acceptable or only explicit exceptions remain.
  7. If a dependency is missing, bootstrap it or return status: not_applicable with explicit reason and fallback path.

Required Result Format

  • status: complete | clean | improved | configured | not_applicable | blocked
  • plan: concise plan and current iteration step
  • actions_taken: concrete changes made
  • validation_skills: final skills run, or skipped with reasons
  • verification: commands, checks, or review evidence summary
  • remaining: top unresolved items or none

For setup-only requests with no execution, return status: configured and exact next commands.

Load References

  • references/archunitnet.md
  • references/patterns.md
  • references/examples.md

Example Requests

  • "Use ArchUnitNET for layered architecture tests."
  • "Set up ArchUnitNET with xUnit or MSTest."
Files (dotnet-skills)
  • references
    • archunitnet.md 1 KB
      # ArchUnitNET
      
      ## Open/Free Status
      
      - open source
      - free to use
      
      ## Install
      
      Core package:
      
      ```bash
      dotnet add package TngTech.ArchUnitNET
      ```
      
      Framework integration packages vary by test framework, for example:
      
      ```bash
      dotnet add package TngTech.ArchUnitNET.xUnit
      dotnet add package TngTech.ArchUnitNET.xUnitV3
      dotnet add package TngTech.ArchUnitNET.MSTestV2
      dotnet add package TngTech.ArchUnitNET.TUnit
      ```
      
      ## Verify First
      
      Before adding packages, check whether the repo already references ArchUnitNET and which framework integration it uses:
      
      ```bash
      rg -n "TngTech\\.ArchUnitNET" -g '*.csproj' .
      ```
      
      ## Common Usage
      
      Load the target assemblies once, then assert rules in tests.
      
      Good fit for:
      
      - layered architecture
      - namespace rules
      - dependency restrictions
      - domain boundary checks
      
      ## CI Fit
      
      - runs as part of the normal test suite
      - richer than lightweight architecture-rule libraries, but also heavier
      
      ## When Not To Use
      
      - when simple `NetArchTest` rules already cover the needed constraints
      
      ## Sources
      
      - [ArchUnitNET](https://github.com/TNG/ArchUnitNET)
      
    • examples.md 10.1 KB
      # ArchUnitNET Common Architecture Rules
      
      ## Project Setup
      
      ### Base Test Class
      
      ```csharp
      using ArchUnitNET.Domain;
      using ArchUnitNET.Loader;
      using ArchUnitNET.Fluent;
      using static ArchUnitNET.Fluent.ArchRuleDefinition;
      
      public abstract class ArchitectureTestBase
      {
          protected static readonly Architecture Architecture =
              new ArchLoader()
                  .LoadAssemblies(
                      typeof(Domain.Marker).Assembly,
                      typeof(Application.Marker).Assembly,
                      typeof(Infrastructure.Marker).Assembly,
                      typeof(Web.Marker).Assembly)
                  .Build();
      }
      ```
      
      ## Clean Architecture Rules
      
      ### Domain Layer Independence
      
      The domain layer should have no dependencies on outer layers:
      
      ```csharp
      [Fact]
      public void Domain_Should_Not_Reference_Application()
      {
          Types()
              .That().ResideInNamespace("MyApp.Domain")
              .Should().NotDependOnAny(
                  Types().That().ResideInNamespace("MyApp.Application"))
              .Check(Architecture);
      }
      
      [Fact]
      public void Domain_Should_Not_Reference_Infrastructure()
      {
          Types()
              .That().ResideInNamespace("MyApp.Domain")
              .Should().NotDependOnAny(
                  Types().That().ResideInNamespace("MyApp.Infrastructure"))
              .Check(Architecture);
      }
      
      [Fact]
      public void Domain_Should_Not_Reference_Presentation()
      {
          Types()
              .That().ResideInNamespace("MyApp.Domain")
              .Should().NotDependOnAny(
                  Types().That().ResideInNamespace("MyApp.Web"))
              .Check(Architecture);
      }
      ```
      
      ### Application Layer Rules
      
      ```csharp
      [Fact]
      public void Application_Should_Not_Reference_Infrastructure()
      {
          Types()
              .That().ResideInNamespace("MyApp.Application")
              .Should().NotDependOnAny(
                  Types().That().ResideInNamespace("MyApp.Infrastructure"))
              .Check(Architecture);
      }
      
      [Fact]
      public void Application_Should_Not_Reference_Presentation()
      {
          Types()
              .That().ResideInNamespace("MyApp.Application")
              .Should().NotDependOnAny(
                  Types().That().ResideInNamespace("MyApp.Web"))
              .Check(Architecture);
      }
      ```
      
      ### Infrastructure Layer Rules
      
      ```csharp
      [Fact]
      public void Infrastructure_Should_Not_Reference_Presentation()
      {
          Types()
              .That().ResideInNamespace("MyApp.Infrastructure")
              .Should().NotDependOnAny(
                  Types().That().ResideInNamespace("MyApp.Web"))
              .Check(Architecture);
      }
      ```
      
      ## Naming Convention Rules
      
      ### Controllers
      
      ```csharp
      [Fact]
      public void Controllers_Should_Have_Controller_Suffix()
      {
          Types()
              .That().ResideInNamespace("Controllers", includeSubNamespaces: true)
              .And().AreClasses()
              .And().AreNotAbstract()
              .Should().HaveNameEndingWith("Controller")
              .Check(Architecture);
      }
      
      [Fact]
      public void Controllers_Should_Inherit_ControllerBase()
      {
          Types()
              .That().HaveNameEndingWith("Controller")
              .And().ResideInNamespace("Controllers")
              .Should().BeAssignableTo(typeof(ControllerBase))
              .Check(Architecture);
      }
      ```
      
      ### Services
      
      ```csharp
      [Fact]
      public void Services_Should_Have_Service_Suffix()
      {
          Types()
              .That().ResideInNamespace("Services")
              .And().AreClasses()
              .And().AreNotAbstract()
              .Should().HaveNameEndingWith("Service")
              .Check(Architecture);
      }
      
      [Fact]
      public void Service_Interfaces_Should_Start_With_I()
      {
          Types()
              .That().ResideInNamespace("Services")
              .And().AreInterfaces()
              .Should().HaveNameStartingWith("I")
              .Check(Architecture);
      }
      ```
      
      ### Repositories
      
      ```csharp
      [Fact]
      public void Repositories_Should_Have_Repository_Suffix()
      {
          Types()
              .That().ImplementInterface(typeof(IRepository<>))
              .And().AreClasses()
              .Should().HaveNameEndingWith("Repository")
              .Check(Architecture);
      }
      ```
      
      ### Handlers (CQRS/MediatR)
      
      ```csharp
      [Fact]
      public void Handlers_Should_Have_Handler_Suffix()
      {
          Types()
              .That().ImplementInterface(typeof(IRequestHandler<,>))
              .Should().HaveNameEndingWith("Handler")
              .Check(Architecture);
      }
      
      [Fact]
      public void Commands_Should_Have_Command_Suffix()
      {
          Types()
              .That().ImplementInterface(typeof(IRequest<>))
              .And().ResideInNamespaceContaining("Commands")
              .Should().HaveNameEndingWith("Command")
              .Check(Architecture);
      }
      
      [Fact]
      public void Queries_Should_Have_Query_Suffix()
      {
          Types()
              .That().ImplementInterface(typeof(IRequest<>))
              .And().ResideInNamespaceContaining("Queries")
              .Should().HaveNameEndingWith("Query")
              .Check(Architecture);
      }
      ```
      
      ## Domain-Driven Design Rules
      
      ### Entities
      
      ```csharp
      [Fact]
      public void Entities_Should_Reside_In_Domain()
      {
          Types()
              .That().AreAssignableTo(typeof(Entity))
              .Should().ResideInNamespaceContaining("Domain")
              .Check(Architecture);
      }
      
      [Fact]
      public void Entities_Should_Not_Have_Public_Setters()
      {
          // Use custom predicate or property-level checks
          Types()
              .That().AreAssignableTo(typeof(Entity))
              .Should().BeSealed()
              .OrShould().BeAbstract()
              .Check(Architecture);
      }
      ```
      
      ### Value Objects
      
      ```csharp
      [Fact]
      public void ValueObjects_Should_Be_Sealed()
      {
          Types()
              .That().AreAssignableTo(typeof(ValueObject))
              .And().AreNotAbstract()
              .Should().BeSealed()
              .Check(Architecture);
      }
      ```
      
      ### Aggregate Roots
      
      ```csharp
      [Fact]
      public void Only_AggregateRoots_Should_Be_Referenced_By_Repositories()
      {
          Types()
              .That().HaveNameEndingWith("Repository")
              .Should().DependOnAny(
                  Types().That().ImplementInterface(typeof(IAggregateRoot)))
              .Check(Architecture);
      }
      ```
      
      ## API Design Rules
      
      ### DTOs
      
      ```csharp
      [Fact]
      public void DTOs_Should_Not_Reference_Domain_Entities()
      {
          Types()
              .That().HaveNameEndingWith("Dto")
              .Or().HaveNameEndingWith("Request")
              .Or().HaveNameEndingWith("Response")
              .Should().NotDependOnAny(
                  Types().That().ResideInNamespace("Domain.Entities"))
              .Check(Architecture);
      }
      ```
      
      ### No Circular Dependencies
      
      ```csharp
      [Fact]
      public void Application_Should_Be_Free_Of_Cycles()
      {
          Types()
              .That().ResideInNamespace("MyApp.Application")
              .Should().BeFreeOfCycles()
              .Check(Architecture);
      }
      ```
      
      ## Infrastructure Rules
      
      ### Database Contexts
      
      ```csharp
      [Fact]
      public void DbContexts_Should_Reside_In_Infrastructure()
      {
          Types()
              .That().AreAssignableTo(typeof(DbContext))
              .Should().ResideInNamespaceContaining("Infrastructure")
              .Check(Architecture);
      }
      ```
      
      ### External Service Clients
      
      ```csharp
      [Fact]
      public void HttpClients_Should_Reside_In_Infrastructure()
      {
          Types()
              .That().HaveNameEndingWith("Client")
              .And().DependOnAny(Types().That().HaveName("HttpClient"))
              .Should().ResideInNamespaceContaining("Infrastructure")
              .Check(Architecture);
      }
      ```
      
      ## Dependency Injection Rules
      
      ### Interface Implementations
      
      ```csharp
      [Fact]
      public void Every_Service_Should_Have_Interface()
      {
          Types()
              .That().HaveNameEndingWith("Service")
              .And().AreClasses()
              .And().AreNotAbstract()
              .Should().ImplementInterface(
                  Types().That().AreInterfaces()
                      .And().HaveNameStartingWith("I"))
              .Check(Architecture);
      }
      ```
      
      ## Testing Rules
      
      ### Test Classes Naming
      
      ```csharp
      [Fact]
      public void Test_Classes_Should_Have_Tests_Suffix()
      {
          Types()
              .That().ResideInAssembly(typeof(SomeTest).Assembly)
              .And().AreClasses()
              .And().HaveAnyMethodWithAttribute(typeof(FactAttribute))
              .Should().HaveNameEndingWith("Tests")
              .Check(TestArchitecture);
      }
      ```
      
      ## Complete Test Class Example
      
      ```csharp
      using ArchUnitNET.Domain;
      using ArchUnitNET.Loader;
      using ArchUnitNET.Fluent;
      using ArchUnitNET.xUnit;
      using Xunit;
      using static ArchUnitNET.Fluent.ArchRuleDefinition;
      
      namespace MyApp.Tests.Architecture;
      
      public class CleanArchitectureTests
      {
          private static readonly Architecture Architecture =
              new ArchLoader()
                  .LoadAssemblies(
                      typeof(Domain.DomainAssemblyMarker).Assembly,
                      typeof(Application.ApplicationAssemblyMarker).Assembly,
                      typeof(Infrastructure.InfrastructureAssemblyMarker).Assembly,
                      typeof(Web.WebAssemblyMarker).Assembly)
                  .Build();
      
          // Layer definitions
          private static readonly IObjectProvider<IType> DomainLayer =
              Types().That().ResideInNamespace("MyApp.Domain").As("Domain Layer");
      
          private static readonly IObjectProvider<IType> ApplicationLayer =
              Types().That().ResideInNamespace("MyApp.Application").As("Application Layer");
      
          private static readonly IObjectProvider<IType> InfrastructureLayer =
              Types().That().ResideInNamespace("MyApp.Infrastructure").As("Infrastructure Layer");
      
          private static readonly IObjectProvider<IType> PresentationLayer =
              Types().That().ResideInNamespace("MyApp.Web").As("Presentation Layer");
      
          [Fact]
          public void Domain_Should_Have_No_Dependencies_On_Other_Layers()
          {
              Types()
                  .That().Are(DomainLayer)
                  .Should().NotDependOnAny(ApplicationLayer)
                  .AndShould().NotDependOnAny(InfrastructureLayer)
                  .AndShould().NotDependOnAny(PresentationLayer)
                  .Check(Architecture);
          }
      
          [Fact]
          public void Application_Should_Only_Depend_On_Domain()
          {
              Types()
                  .That().Are(ApplicationLayer)
                  .Should().NotDependOnAny(InfrastructureLayer)
                  .AndShould().NotDependOnAny(PresentationLayer)
                  .Check(Architecture);
          }
      
          [Fact]
          public void Controllers_Should_Follow_Naming_Convention()
          {
              Types()
                  .That().Are(PresentationLayer)
                  .And().AreAssignableTo(typeof(Microsoft.AspNetCore.Mvc.ControllerBase))
                  .Should().HaveNameEndingWith("Controller")
                  .Check(Architecture);
          }
      
          [Fact]
          public void Services_Should_Be_Internal()
          {
              Types()
                  .That().HaveNameEndingWith("Service")
                  .And().AreClasses()
                  .And().DoNotHaveNameStartingWith("I")
                  .Should().BeInternal()
                  .Check(Architecture);
          }
      }
      ```
      
    • patterns.md 5 KB
      # ArchUnitNET Rule Patterns
      
      ## Architecture Loading
      
      Load the architecture once per test class to avoid repeated assembly scanning:
      
      ```csharp
      private static readonly Architecture Architecture =
          new ArchLoader()
              .LoadAssemblies(typeof(SomeClassInTargetAssembly).Assembly)
              .Build();
      ```
      
      For multiple assemblies:
      
      ```csharp
      private static readonly Architecture Architecture =
          new ArchLoader()
              .LoadAssemblies(
                  typeof(Domain.Entity).Assembly,
                  typeof(Application.Service).Assembly,
                  typeof(Infrastructure.Repository).Assembly)
              .Build();
      ```
      
      ## Rule Syntax Patterns
      
      ### Basic Pattern
      
      ```csharp
      IArchRule rule = Types()
          .That()
          .Are(predicate)
          .Should()
          .Be(condition);
      
      rule.Check(Architecture);
      ```
      
      ### With Test Framework Integration
      
      Using xUnit:
      
      ```csharp
      [Fact]
      public void Controllers_Should_Not_Depend_On_Repositories()
      {
          Types()
              .That().ResideInNamespace("Controllers")
              .Should().NotDependOnAny(Types().That().ResideInNamespace("Repositories"))
              .Check(Architecture);
      }
      ```
      
      Using MSTest:
      
      ```csharp
      [TestMethod]
      public void Controllers_Should_Not_Depend_On_Repositories()
      {
          Types()
              .That().ResideInNamespace("Controllers")
              .Should().NotDependOnAny(Types().That().ResideInNamespace("Repositories"))
              .Check(Architecture);
      }
      ```
      
      ## Selection Patterns
      
      ### By Namespace
      
      ```csharp
      Types().That().ResideInNamespace("MyApp.Domain")
      Types().That().ResideInNamespaceContaining("Services")
      Types().That().ResideInNamespaceMatching(@"MyApp\..*\.Handlers")
      ```
      
      ### By Naming Convention
      
      ```csharp
      Types().That().HaveNameEndingWith("Controller")
      Types().That().HaveNameStartingWith("I")
      Types().That().HaveNameMatching(@".*Handler$")
      ```
      
      ### By Type Characteristics
      
      ```csharp
      Types().That().AreClasses()
      Types().That().AreInterfaces()
      Types().That().AreAbstract()
      Types().That().AreSealed()
      Types().That().ArePublic()
      Types().That().ImplementInterface(typeof(IService))
      ```
      
      ### By Inheritance
      
      ```csharp
      Types().That().AreAssignableTo(typeof(BaseClass))
      Types().That().ImplementInterface(typeof(IHandler<>))
      ```
      
      ### By Attributes
      
      ```csharp
      Types().That().HaveAnyAttributes(typeof(SerializableAttribute))
      Types().That().DoNotHaveAnyAttributes(typeof(ObsoleteAttribute))
      ```
      
      ## Condition Patterns
      
      ### Dependency Rules
      
      ```csharp
      .Should().NotDependOnAny(Types().That().ResideInNamespace("Infrastructure"))
      .Should().OnlyDependOn(Types().That().ResideInNamespace("Domain"))
      .Should().DependOnAny(Types().That().ResideInNamespace("Contracts"))
      ```
      
      ### Namespace Residence
      
      ```csharp
      .Should().ResideInNamespace("MyApp.Application")
      .Should().ResideInNamespaceContaining("Handlers")
      ```
      
      ### Naming Requirements
      
      ```csharp
      .Should().HaveNameEndingWith("Service")
      .Should().HaveNameStartingWith("I")
      ```
      
      ### Visibility Requirements
      
      ```csharp
      .Should().BePublic()
      .Should().BeInternal()
      .Should().BeSealed()
      ```
      
      ### Inheritance Requirements
      
      ```csharp
      .Should().ImplementInterface(typeof(IDisposable))
      .Should().BeAssignableTo(typeof(BaseEntity))
      ```
      
      ## Layer Definition Pattern
      
      Define layers as reusable predicates:
      
      ```csharp
      private static readonly IObjectProvider<IType> DomainLayer =
          Types().That().ResideInNamespace("MyApp.Domain").As("Domain Layer");
      
      private static readonly IObjectProvider<IType> ApplicationLayer =
          Types().That().ResideInNamespace("MyApp.Application").As("Application Layer");
      
      private static readonly IObjectProvider<IType> InfrastructureLayer =
          Types().That().ResideInNamespace("MyApp.Infrastructure").As("Infrastructure Layer");
      
      private static readonly IObjectProvider<IType> PresentationLayer =
          Types().That().ResideInNamespace("MyApp.Web").As("Presentation Layer");
      ```
      
      Use layers in rules:
      
      ```csharp
      [Fact]
      public void Domain_Should_Not_Depend_On_Application()
      {
          Types().That().Are(DomainLayer)
              .Should().NotDependOnAny(ApplicationLayer)
              .Check(Architecture);
      }
      ```
      
      ## Combining Rules
      
      Combine multiple conditions:
      
      ```csharp
      Types()
          .That().ResideInNamespace("MyApp.Domain")
          .And().AreClasses()
          .And().AreNotAbstract()
          .Should().BeSealed()
          .OrShould().ImplementInterface(typeof(IEntity))
          .Check(Architecture);
      ```
      
      ## Custom Predicates
      
      Create reusable custom predicates:
      
      ```csharp
      public static class CustomPredicates
      {
          public static IPredicate<IType> AreAggregateRoots()
          {
              return new SimplePredicate<IType>(
                  type => type.ImplementsInterface(typeof(IAggregateRoot)),
                  "are aggregate roots");
          }
      }
      ```
      
      Use in rules:
      
      ```csharp
      Types().That().Are(CustomPredicates.AreAggregateRoots())
          .Should().ResideInNamespace("MyApp.Domain.Aggregates")
          .Check(Architecture);
      ```
      
      ## Slice Pattern for Vertical Slices
      
      Check that vertical slices do not depend on each other:
      
      ```csharp
      SliceRuleDefinition.ForFunctions()
          .Should().NotDependOnEachOther()
          .Check(Architecture);
      ```
      
      ## Cycle Detection Pattern
      
      Check for circular dependencies:
      
      ```csharp
      Types().That().ResideInNamespace("MyApp")
          .Should().BeFreeOfCycles()
          .Check(Architecture);
      ```
      
  • SKILL.md 3.9 KB
    ---
    name: dotnet-archunitnet
    version: "1.0.0"
    category: "Architecture"
    description: "Use the open-source free `ArchUnitNET` library for architecture rules in .NET tests. Use when a repo needs richer architecture assertions than lightweight fluent rule libraries usually provide."
    compatibility: "Requires a .NET test project; supports dedicated integrations for xUnit, xUnit v3, MSTest, TUnit, and others where available."
    ---
    
    # ArchUnitNET for .NET
    
    ## Trigger On
    
    - the repo uses or wants `ArchUnitNET`
    - architecture testing needs richer modeling than simple dependency checks
    
    ## Value
    
    - produce a concrete project delta: code, docs, config, tests, CI, or review artifact
    - reduce ambiguity through explicit planning, verification, and final validation skills
    - leave reusable project context so future tasks are faster and safer
    
    ## Do Not Use For
    
    - the lightest possible architecture rule checks
    
    ## Inputs
    
    - the nearest `AGENTS.md`
    - target assemblies
    - architecture boundaries and naming conventions
    
    ## Quick Start
    
    1. Read the nearest `AGENTS.md` and confirm scope and constraints.
    2. Run this skill's `Workflow` through the `Ralph Loop` until outcomes are acceptable.
    3. Return the `Required Result Format` with concrete artifacts and verification evidence.
    
    ## Workflow
    
    1. Load the architecture once per test assembly where possible.
    2. Encode a small number of durable, high-value architecture rules first.
    3. Use the test-framework-specific integration package that matches the repo.
    
    ## Bootstrap When Missing
    
    If `ArchUnitNET` is not configured yet:
    
    1. Detect existing setup:
       - `rg -n "TngTech\\.ArchUnitNET" -g '*.csproj' .`
    2. Add packages to the architecture test project:
       - `dotnet add TEST_PROJECT.csproj package TngTech.ArchUnitNET`
       - add one framework bridge package: `TngTech.ArchUnitNET.xUnit`, `TngTech.ArchUnitNET.xUnitV3`, `TngTech.ArchUnitNET.MSTestV2`, or `TngTech.ArchUnitNET.TUnit`
    3. Add at least one durable boundary rule test.
    4. Wire architecture tests into the standard `test` command in `AGENTS.md` and CI.
    5. Run `dotnet test TEST_PROJECT.csproj` and return `status: configured` or `status: improved`.
    6. If `NetArchTest` already covers the same boundary policy and no gap exists, return `status: not_applicable`.
    
    
    ## Deliver
    
    - architecture tests with richer domain and type modeling
    - architecture-rule commands wired into repo test flow and CI expectations
    
    ## Validate
    
    - architecture load cost is reasonable for the suite
    - rules are stable and tied to real boundaries
    
    ## Ralph Loop
    
    Use the Ralph Loop for every task, including docs, architecture, testing, and tooling work.
    
    1. Plan first (mandatory):
       - analyze current state
       - define target outcome, constraints, and risks
       - write a detailed execution plan
       - list final validation skills to run at the end, with order and reason
    2. Execute one planned step and produce a concrete delta.
    3. Review the result and capture findings with actionable next fixes.
    4. Apply fixes in small batches and rerun the relevant checks or review steps.
    5. Update the plan after each iteration.
    6. Repeat until outcomes are acceptable or only explicit exceptions remain.
    7. If a dependency is missing, bootstrap it or return `status: not_applicable` with explicit reason and fallback path.
    
    ### Required Result Format
    
    - `status`: `complete` | `clean` | `improved` | `configured` | `not_applicable` | `blocked`
    - `plan`: concise plan and current iteration step
    - `actions_taken`: concrete changes made
    - `validation_skills`: final skills run, or skipped with reasons
    - `verification`: commands, checks, or review evidence summary
    - `remaining`: top unresolved items or `none`
    
    For setup-only requests with no execution, return `status: configured` and exact next commands.
    
    ## Load References
    
    - `references/archunitnet.md`
    - `references/patterns.md`
    - `references/examples.md`
    
    ## Example Requests
    
    - "Use ArchUnitNET for layered architecture tests."
    - "Set up ArchUnitNET with xUnit or MSTest."
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related