Skip to content
Blog

Context-Driven Development: Managing AI Agents, System Architecture, and CI/CD with INTENT.md, DESIGN.md, and AGENTS.md

Learn how to enforce structured context for AI coding agents and CI/CD pipelines using INTENT.md, DESIGN.md, and AGENTS.md with automated GitHub Actions guardrails.

Published on September 3, 2026

AI Assistant

Building software alongside AI coding assistants has exposed a fundamental flaw in traditional repository documentation: standard README files were written for human developers skim-reading quickstart guides, not for AI tools requiring structured system context.

Without precise constraints, AI agents hallucinate dependencies, introduce architectural anti-patterns, and drift away from core product requirements. To solve this, engineering teams are adopting a context framework using dedicated Markdown files: INTENT.md, DESIGN.md, and AGENTS.md, alongside specialized design system documentation.


1. The Core Framework: Defining the Roles

Each file targets a distinct layer of the software lifecycle, transforming documentation into machine-readable guardrails.

  • INTENT.md (The “Why” & “What”): Defines product requirements, targeted user personas, KPIs, and explicitly out-of-scope items. It anchors the high-level business goals so implementations do not suffer scope creep.
  • DESIGN.md (Software System Architecture): Maps technical architecture, API contracts, database schemas, and non-functional bounds. Note: DESIGN.md focuses strictly on software and system architecture (backend/frontend logic, data flow, state management), not UI visual design.
  • AGENTS.md (Execution Rules): Acts as system instructions for context-aware developer tools (like Claude Code, Cursor, or custom agents). It outlines formatting rules, CLI build commands, and strict operational guardrails.
  • THEME.md / COMPONENTS.md (UI Design System): Dedicates a explicit space for frontend visual guidelines, typography, color palettes, design tokens, and UI component standards.
DocumentPrimary FocusCore Contents
INTENT.mdBusiness Logic & VisionProblem statement, user stories, success metrics, non-goals
DESIGN.mdSystem ArchitectureSchemas, API definitions, stack boundaries, security standards
AGENTS.mdAgent Operational RulesCommand syntax, code style conventions, forbidden file operations
THEME.mdUI Design SystemColor palettes, typography scales, spacing tokens, component rules

2. Clarifying System Architecture vs. UI Design System

A common point of confusion is whether DESIGN.md serves as a UI design system. In software engineering context frameworks, they are kept strictly distinct:

  • System Design (DESIGN.md): Addresses software engineering structure—how data flows from database tables to backend services and frontend state stores.
  • UI Design System (THEME.md / COMPONENTS.md / tokens.json): Addresses visual interface standards—defining design tokens, typography, padding, color variables, and reusable UI components.

For frontend-heavy applications, keep system architecture inside DESIGN.md and reference visual design rules via THEME.md or a machine-readable tokens.json.


3. Production-Ready File Templates

Copy these base templates directly into the root of your repository to establish standard context boundaries.

INTENT.md Template

# Product Intent & Vision

## 1. Problem Statement
- **Context**: [Brief description of current pain point or gap]
- **Target User**: [Persona or user group impacted]
- **Value Proposition**: [Why this feature/project matters]

## 2. Core Goals & Outcomes
- [ ] Goal 1: [Specific, measurable outcome]
- [ ] Goal 2: [Specific, measurable outcome]

## 3. Scope Boundaries
### In-Scope
- [Feature / Capability 1]
- [Feature / Capability 2]

### Out-of-Scope (Non-Goals)
- [Explicitly excluded item 1]
- [Explicitly excluded item 2]

DESIGN.md Template (System Architecture)

# System & Technical Architecture

## 1. Architecture Overview
- **Tech Stack**: [e.g., React, Node.js, PostgreSQL, Redis]
- **Design Pattern**: [e.g., Clean Architecture, Event-Driven]

## 2. Data Models & Schemas
```dbml
Table users {
  id integer [primary key]
  email varchar
  created_at timestamp
}
```

## 3. API Contracts

* **`POST /api/v1/resource`**
* **Request Body**: `{ "field": "value" }`
* **Response**: `{ "id": "123", "status": "created" }`

## 4. Non-Functional Standards

* **Performance**: Response time < 200ms at p95
* **Security**: OAuth2 + JWT authentication, strict input sanitization

THEME.md Template (UI Design System Guidelines)

# UI Design System & Visual Guidelines

## 1. Color Palette
- **Primary**: `#3B82F6` (Brand Blue)
- **Secondary**: `#10B981` (Accent Green)
- **Neutral Dark**: `#111827` (Primary Text)
- **Neutral Light**: `#F9FAFB` (Background)

## 2. Typography Scale
- **Font Family**: Inter, sans-serif
- **Heading 1**: 32px / Bold / Line Height: 1.2
- **Body**: 16px / Regular / Line Height: 1.5

## 3. Spacing & Tokens
- **Grid Unit**: 4px base (4px, 8px, 16px, 24px, 32px)
- **Border Radius**: Small (`4px`), Medium (`8px`), Large (`16px`)

AGENTS.md Template

# AI Agent Operational Rules

## 1. Repository Guardrails
- **DO NOT** delete or overwrite database migration scripts without explicit human approval.
- **DO NOT** modify lockfiles manually (`package-lock.json`, `Cargo.lock`).
- **DO NOT** commit secrets, API keys, or raw `.env` files.

## 2. CLI Commands
- **Build**: `npm run build`
- **Test**: `npm test`
- **Lint**: `npm run lint`

## 3. Style Conventions
- **Naming**: camelCase for functions/variables, PascalCase for components.
- **Typing**: Strict TypeScript — no `any`.
- **Testing**: Every new route or helper requires unit tests.

4. Automated Enforcement with GitHub Actions

To prevent these files from suffering documentation drift, you must turn them into hard quality gates. The following GitHub Action checks PR diffs and fails the build if core system files (like schemas or API routes) are modified without corresponding updates to DESIGN.md or INTENT.md.

Save this file as .github/workflows/documentation-drift-guard.yml:

name: Documentation Drift Guard

on:
  pull_request:
    types: [opened, synchronize, re-opened]

permissions:
  contents: read
  pull-requests: write

jobs:
  check-doc-drift:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Detect Architectural & Schema Changes
        id: detect-changes
        run: |
          CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)
          
          SCHEMA_PATTERN="^(src/db/|prisma/|migrations/|src/models/|api/|schemas/|\.env\.example)"
          INTENT_PATTERN="^(src/features/|src/pages/|routes/)"
          
          SCHEMA_CHANGED=false
          FEATURE_CHANGED=false
          DESIGN_UPDATED=false
          INTENT_UPDATED=false
          
          if echo "$CHANGED_FILES" | grep -qE "$SCHEMA_PATTERN"; then SCHEMA_CHANGED=true; fi
          if echo "$CHANGED_FILES" | grep -qE "$INTENT_PATTERN"; then FEATURE_CHANGED=true; fi
          if echo "$CHANGED_FILES" | grep -q "^DESIGN.md"; then DESIGN_UPDATED=true; fi
          if echo "$CHANGED_FILES" | grep -q "^INTENT.md"; then INTENT_UPDATED=true; fi
          
          echo "schema_changed=$SCHEMA_CHANGED" >> $GITHUB_OUTPUT
          echo "feature_changed=$FEATURE_CHANGED" >> $GITHUB_OUTPUT
          echo "design_updated=$DESIGN_UPDATED" >> $GITHUB_OUTPUT
          echo "intent_updated=$INTENT_UPDATED" >> $GITHUB_OUTPUT

      - name: Enforce Documentation Updates
        uses: actions/github-script@v7
        with:
          script: |
            const schemaChanged = '${{ steps.detect-changes.outputs.schema_changed }}' === 'true';
            const featureChanged = '${{ steps.detect-changes.outputs.feature_changed }}' === 'true';
            const designUpdated = '${{ steps.detect-changes.outputs.design_updated }}' === 'true';
            const intentUpdated = '${{ steps.detect-changes.outputs.intent_updated }}' === 'true';
            
            let errors = [];
            
            if (schemaChanged && !designUpdated) {
              errors.push("DESIGN.md Drift: Schema or API route changes were detected without an update to DESIGN.md.");
            }
            
            if (featureChanged && !intentUpdated) {
              errors.push("INTENT.md Drift: Feature routes were modified without an update to INTENT.md.");
            }
            
            if (errors.length > 0) {
              core.setFailed(`PR blocked due to documentation drift:\n${errors.join('\n')}`);
            }

5. Blocking Merges via Branch Protection Rules

Failing the GitHub Action step is the first step; preventing developers or auto-merge bots from bypassing the failure requires enforcing branch protection rules.

  1. Navigate to Settings > Branches (or Rulesets) in your repository.
  2. Select your main protection rule for your target branch (e.g., main).
  3. Enable Require status checks to pass before merging.
  4. Add check-doc-drift to the list of required checks.
  5. Save the configuration.

By tying INTENT.md, DESIGN.md, THEME.md, and AGENTS.md directly into your CI pipeline, you ensure that as code evolves, the contextual instructions guiding both human reviewers and automated AI models remain synchronized with production realities.