# adr-aware
---
description: Automatically load and apply relevant ADRs when creating or modifying resources
tags: [adr, architecture, design, conventions]
techStack: [all]
appliesTo: ["**/*.cs", "**/*.ts", "**/*.tsx"]
alwaysApply: true
---
## 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 all ADRs
---
## 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 |
| **Caching** | `*Cache*.cs`, `IDistributedCache`, `IMemoryCache` | ADR-009 |
| **Dataverse Plugin** | `*Plugin.cs` in plugins folder | ADR-002 |
| **Graph/SPE Integration** | `*Spe*.cs`, `*Graph*.cs`, `*Drive*.cs` | ADR-007 |
| **PCF Control** | `*.tsx` in pcf/, `ControlManifest.Input.xml` | ADR-006, ADR-011, ADR-012, ADR-021 |
| **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` | ADR-001, ADR-004 |
| **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
- Plugin work → .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 code examples
- 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 |
| Plugin | `.claude/constraints/plugins.md` | `.claude/patterns/dataverse/` | ADR-002 |
| Auth/OAuth | `.claude/constraints/auth.md` | `.claude/patterns/auth/` | ADR-003, 008 |
| 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-001, 004, 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:
```csharp
// ✅ DO: Reference ADRs in significant architectural code
public static class NavMapEndpoints
{
///
/// ADR Compliance:
/// - ADR-001: Minimal API (no controllers)
/// - ADR-008: Endpoint-level authorization
/// - ADR-009: Redis-first caching (L1 exception for metadata)
///
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 + Workers | No Azure Functions | `[FunctionName]`, `Microsoft.Azure.Functions` |
| ADR-002 | Thin Plugins | No HTTP in plugins; <50ms | `HttpClient` in Plugin class |
| 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 | ≤15 DI registrations | 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 |
---
## Integration with Other Skills
### design-to-project
- Phase 2 (Context) should invoke ADR lookup using the mapping table
- Generated CLAUDE.md should list applicable ADRs
### task-create
- Task `` should include ADR references
- Task `` 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**:
```csharp
// ADR-001: Minimal API pattern
app.MapGet("/api/documents/{id}/metadata", GetDocumentMetadataAsync)
.AddEndpointFilter() // 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**:
```typescript
// 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.
---
*Last updated: December 25, 2025*