adr-aware

Ensures Architecture Decision Records (ADRs) are automatically considered when AI agents create or modify code. This skill provides proactive ADR awareness versus reactive checking (which is handled b

SKILL.md

GitHub

adr-aware

Last Reviewed: 2026-05-16 Reviewed By: ai-procedure-quality-r1 (Phase 2b Wave 2b-A) Exemplar rationale: This skill prescribes a context-loading discipline, not a build/deploy procedure — no artifact to rebuild and compare. Quarterly manual review of the mapping table is the right cadence.

Purpose

Ensures Architecture Decision Records (ADRs) are automatically considered when AI agents create or modify code. This skill provides proactive ADR awareness versus reactive checking (which is handled by adr-check).

Philosophy:

  • adr-aware (this skill) = BEFORE - Load relevant ADRs when starting work
  • adr-check = AFTER - Validate completed work against every ADR that applies (mapping + a pass over the whole index)

Always-Apply Rules

Rule 1: Resource-Type to ADR Mapping

When creating or modifying these resource types, automatically load the specified ADRs:

Resource Type Detection Pattern Required ADRs
API Endpoint *Endpoints.cs, *Handler.cs, Program.cs routes ADR-001, ADR-008, ADR-010
AI Endpoint/Service Api/Ai/*, *DocumentIntelligence*, *Analysis*, *Ai* ADR-013, ADR-015, ADR-016, ADR-018, ADR-019, ADR-020
Authorization *Authorization*.cs, *Filter.cs, *Policy*.cs ADR-003, ADR-008, ADR-028
Auth Library / Client Bootstrap @spaarke/auth/**, *authInit*.ts, useAuth consumers, initAuth() callers, authenticatedFetch callers ADR-028
Caching *Cache*.cs, IDistributedCache, IMemoryCache ADR-009
Dataverse write path (plugin proposal; record create/update path; Create*Wizard services; rule a record must satisfy on save) *Plugin.cs (prohibited), *Wizard/*Service.ts, RecordCreationService, *Resolver.cs writers ADR-002
Graph/SPE Integration *Spe*.cs, *Graph*.cs, *Drive*.cs, GraphClientFactory.cs ADR-007, ADR-028
PCF Control *.tsx in pcf/, ControlManifest.Input.xml ADR-006, ADR-011, ADR-012, ADR-021, ADR-028 (for any PCF calling BFF)
Webresource *.js in webresources/ ADR-006
DI Registration Program.cs DI section, Add* extension methods ADR-010
Background Worker *Worker.cs, *Service.cs implementing BackgroundService; IJobHandler; IScheduledJob; a Functions project ADR-052 (where it runs), ADR-004 (queue), ADR-036 (schedule)
Job Status/Persistence *JobStatus*, JobOutcome, JobContract ADR-004, ADR-017, ADR-020
Feature Flags / Kill Switches *Feature*, FeatureFlag, IOptions* gates ADR-018
API Errors / ProblemDetails ProblemDetails, Results.Problem, IResult error helpers ADR-019
Versioning v1/, ApiVersion, contracts/DTO versioning ADR-020
Storage/Documents *Store*.cs, *Document*.cs, *File*.cs ADR-005, ADR-007

Rule 2: Automatic Context Loading (Two-Tier Strategy)

When a task or prompt involves creating/modifying files matching the patterns above:

BEFORE writing any code:
  1. IDENTIFY resource types from task/file patterns
  2. LOOKUP applicable ADRs from mapping table (Rule 1)

  3. LOAD Tier 1 context (concise, AI-optimized):
     a. LOAD .claude/constraints/{domain}.md for MUST/MUST NOT rules
        - API work → .claude/constraints/api.md
        - PCF work → .claude/constraints/pcf.md
        - Dataverse write path / record invariants / any plugin proposal → .claude/constraints/plugins.md
        - Auth work → .claude/constraints/auth.md
        - Caching work → .claude/constraints/data.md
        - AI work → .claude/constraints/ai.md
        - Testing → .claude/constraints/testing.md

     b. LOAD .claude/adr/ADR-XXX.md for each applicable ADR
        - These are 100-150 line concise versions
        - Focus on constraints, not full rationale

     c. LOAD .claude/patterns/{domain}/*.md for implementation pointers (When to use, canonical files to read, constraints, key rules)
        - API patterns → .claude/patterns/api/
        - Auth patterns → .claude/patterns/auth/
        - PCF patterns → .claude/patterns/pcf/
        - Dataverse patterns → .claude/patterns/dataverse/

  4. IF more context needed (rare):
     → READ docs/adr/ADR-XXX-*.md for full rationale and history

  5. APPLY constraints during implementation

Resource Type to Context Files Mapping

Resource Type Constraints File Pattern Directory ADRs
API Endpoint .claude/constraints/api.md .claude/patterns/api/ ADR-001, 008, 010
PCF Control .claude/constraints/pcf.md .claude/patterns/pcf/ ADR-006, 011, 012, 021
Dataverse write path (record create/update, invariants; plugins prohibited) .claude/constraints/plugins.md .claude/patterns/dataverse/ ADR-002
Auth/OAuth .claude/constraints/auth.md .claude/patterns/auth/ (incl. spaarke-sso-binding.md) ADR-003, 008, 028 (canonical)
Caching .claude/constraints/data.md .claude/patterns/caching/ ADR-009
AI Features .claude/constraints/ai.md .claude/patterns/ai/ ADR-013, 014, 015, 016
Background Jobs .claude/constraints/jobs.md — ADR-052, 004, 036, 017
Testing .claude/constraints/testing.md .claude/patterns/testing/ ADR-022

Rule 3: ADR Constraint Comments

When writing code affected by ADRs, include a brief ADR reference comment:

// ✅ DO: Reference ADRs in significant architectural code
public static class NavMapEndpoints
{
    /// <summary>
    /// ADR Compliance:
    /// - ADR-001: Minimal API (no controllers)
    /// - ADR-008: Endpoint-level authorization
    /// - ADR-009: Redis-first caching (L1 exception for metadata)
    /// </summary>
    public static void MapNavMapEndpoints(this WebApplication app) { }
}

// ❌ DON'T: Clutter every method - only significant decisions
public string FormatDate(DateTime dt) => dt.ToString("yyyy-MM-dd"); // No ADR ref needed

Rule 4: ADR Violation Prevention

If about to write code that violates an ADR:

IF detected violation pattern:
  1. STOP before writing
  2. NOTIFY user with:
     🔔 **ADR Conflict Detected**
     
     **ADR**: {ADR-XXX} - {Title}
     **Constraint**: {Specific rule being violated}
     **Intended Code**: {What you were about to write}
     **Compliant Alternative**: {What to write instead}
     
     Proceed with compliant alternative? (y/n)
  3. AWAIT confirmation before continuing

ADR Quick Reference

Reference this table for common constraints. The source of truth is:

  • Concise ADRs: .claude/adr/ (AI-optimized, 100-150 lines each)
  • Full ADRs: docs/adr/INDEX.md (complete with history and rationale)
ADR Title Key Constraint Violation Pattern
ADR-001 Minimal API (BFF runtime) BFF endpoints in Minimal API; no Functions / Durable Task inside the BFF. Where background work runs → ADR-052 (inside the BFF: queue → ADR-004, schedule → ADR-036) [Function]/[FunctionName]/[HttpTrigger] inside Sprk.Bff.Api; Functions or DurableTask packages in the BFF csproj
ADR-002 No Plugins + Server-Side Write Path No plugins at all; each record invariant has one BFF owner; client previews only; security fails closed Any IPlugin; applyFieldMappings/stamping only in a wizard then Xrm.WebApi create; NULL security flag treated as not-secure
ADR-003 Authorization Seams Two seams only: UAC + Storage Multiple IAuthorizationXxx interfaces
ADR-004 Async Job Contract Uniform job processing Ad-hoc Task.Run for async work
ADR-005 Flat Storage No folder hierarchies in SPE CreateFolder, nested paths
ADR-006 PCF over Webresources No new JS webresources New .js in webresources/
ADR-007 SpeFileStore Facade No Graph types above facade Microsoft.Graph in API controllers
ADR-008 Endpoint Filters No global auth middleware app.UseAuthorization() for resources
ADR-009 Redis-First No hybrid L1+L2 without proof IMemoryCache cross-request
ADR-010 DI Minimalism Feature modules; ~15 Program.cs lines is a target Interface for single implementation
ADR-011 Dataset PCF PCF for data grids Native subgrid with custom actions
ADR-012 Shared Components Reuse @spaarke/ui-components Duplicate component implementations
ADR-013 AI Architecture No hidden/orphaned AI elements Undocumented AI endpoints/jobs
ADR-014 AI Caching Define cache reuse policy Ad-hoc caching per endpoint
ADR-015 AI Data Governance Minimize/secure AI data flows Logging prompts/PII, unclear retention
ADR-016 AI Backpressure Rate limits + bounded concurrency Unbounded fanout / no throttling
ADR-017 Job Status Persist job status contract Fire-and-forget without status
ADR-018 Feature Flags Kill switches for risky features No gating for AI/expensive features
ADR-019 API Errors ProblemDetails standards Ad-hoc error payloads/status codes
ADR-020 Versioning Version APIs/jobs/contracts Breaking changes without version bump
ADR-021 Fluent UI v9 Design Use Fluent v9; dark mode; tokens Hard-coded colors, Fluent v8 imports
ADR-022 PCF Platform Libraries PCF uses React 16/17 (platform); Code Pages use React 19 (bundled) createRoot in PCF; useId() in PCF
ADR-026 Code Page Build Standard Vite + vite-plugin-singlefile + React 19 Webpack/CRA for new Code Pages; no viteSingleFile
ADR-027 Subscription Isolation One Azure subscription per CUSTOMER (amended 2026-09-28) + declarative per-scope resource groups; unmanaged solutions in every environment (amended 2026-06-02) Two customers in one subscription; a shared App Service Plan across customers (impossible cross-subscription); ad-hoc/manually-created resource groups; enforcing managed solutions — that mandate is suspended, not active
ADR-028 Spaarke Auth Architecture (v2) useAuth() + authenticatedFetch; MI (UAMI) for app-only outbound; MI-FIC client assertion or KV certificate for confidential clients / OBO (A4); HMAC webhooks; tenant-specific authority Raw fetch(... Authorization: Bearer ...), tokenBridge, window.__SPAARKE_BFF_TOKEN__, 6-strategy cascade, ClientSecretCredential for app-only when MI available, .WithClientSecret(...) on BFF-identity clients (A4; transitional sites covered by E-3), per-request CCA construction, /common or /organizations authority

Integration with Other Skills

design-to-spec

  • Phase 2 (Context) should invoke ADR lookup using the mapping table
  • Generated CLAUDE.md should list applicable ADRs

task-create

  • Task <constraints> should include ADR references
  • Task <files> should include ADRs to read

code-review

  • Should reference this skill for ADR-specific checks
  • Violations should cite specific ADR numbers

adr-check

  • This skill prevents violations; adr-check validates afterward
  • Both should use the same ADR quick reference

Examples

Example 1: Creating a new API endpoint

Task: "Create a new endpoint to get document metadata"

adr-aware activates:

Detected: API Endpoint creation
Loading ADRs: ADR-001, ADR-008, ADR-010

Key constraints:
- ADR-001: Use Minimal API pattern (MapGet/MapPost), not controllers
- ADR-008: Add endpoint filter for authorization, not global middleware
- ADR-010: Inject concrete SpeFileStore, not interface

Generated code includes:

// ADR-001: Minimal API pattern
app.MapGet("/api/documents/{id}/metadata", GetDocumentMetadataAsync)
   .AddEndpointFilter<DocumentAuthorizationFilter>()  // ADR-008
   .WithName("GetDocumentMetadata");

Example 2: Creating a PCF control

Task: "Create a document viewer PCF control"

adr-aware activates:

Detected: PCF Control creation
Loading ADRs: ADR-006, ADR-011, ADR-012, ADR-021

Key constraints:
- ADR-006: Use PCF, not webresource (already doing this ✅)
- ADR-011: Use Dataset PCF for list views
- ADR-012: Import from @spaarke/ui-components for shared components
- ADR-021: Use Fluent v9, semantic tokens, dark mode support

Generated code includes:

// ADR-012: Use shared component library
import { DocumentCard, StatusBadge } from "@spaarke/ui-components";
// ADR-021: Fluent v9 components and tokens
import { Button, tokens, makeStyles } from "@fluentui/react-components";
import { DocumentAdd20Regular } from "@fluentui/react-icons";

const useStyles = makeStyles({
  container: {
    backgroundColor: tokens.colorNeutralBackground1, // ADR-021: semantic tokens
    color: tokens.colorNeutralForeground1,
  },
});

Example 3: Prevented violation

Task: "Add caching to the document service"

adr-aware detects:

About to use IMemoryCache for cross-request caching...

🔔 **ADR Conflict Detected**

**ADR**: ADR-009 - Redis-first caching
**Constraint**: No hybrid L1+L2 cache; use IDistributedCache for cross-request
**Intended Code**: `_memoryCache.Set(key, value, TimeSpan.FromMinutes(5))`
**Compliant Alternative**: `await _distributedCache.SetStringAsync(key, json, options)`

Proceed with compliant alternative? (y/n)

Validation

Run /adr-check after completing tasks to verify no violations were introduced.


Failure Modes & Recovery

Failure Cause Prevention / Recovery
Agent creates code that violates an ADR despite adr-aware being always-apply Mapping table didn't trigger (resource type not recognized) OR agent loaded the ADR but ignored its constraint Add the missed resource type to the mapping table (Rule 1) so future loads cover it. Run /adr-check to retroactively catch the violation.
Two mapping tables disagree on which ADRs apply to a resource Rule 1 (resource-type → ADR) and "Resource Type to Context Files Mapping" tables drift apart Reconcile against current .claude/adr/ inventory + ADR-jobs ADR coverage. The two tables should agree on jobs.md and other constraint files.
Renamed skill referenced inline still appears in old form Skill rename (e.g., design-to-project → design-to-spec) propagated to root CLAUDE.md but not here Run Find-SkillReferenceDrift.ps1 (Phase 4a) before claiming "all references updated." Update inline references in lockstep with skill renames.
ADR-jobs (or another newer ADR) added but not in this skill's mapping ADR creation skipped the propagation step in ai-procedure-maintenance Run /ai-procedure-maintenance checklist when adding a new ADR — it explicitly updates the resource-type mapping in this skill.

Last updated 2026-05-16 by ai-procedure-quality-r1 Phase 2b Wave 2b-A.