Skip to content

.ai-context.md Standard

The AI Agent Constitution - Complete guide to creating .ai-context.md files that teach AI agents about your project.


Table of Contents


Overview

What Is .ai-context.md?

.ai-context.md is a standardized context file that lives in your project root and teaches AI agents about:

  • Environment constraints (Docker, filesystem, resources)
  • Security protocols (never ask for API keys)
  • Tech stack and tools (Node.js, Python, test runners)
  • Coding standards (linting, formatting, commit messages)
  • Project-specific workflows

Think of it as: A "Constitution" or "README for AI agents" that ensures consistent, secure behavior.

Benefits

Without .ai-context.md: - ❌ AI agents don't know environment constraints - ❌ May ask users for API keys (security violation) - ❌ May use wrong tools or outdated patterns - ❌ Inconsistent behavior across sessions - ❌ Agents reinvent the wheel each session

With .ai-context.md: - ✅ AI agents self-configure from the file - ✅ Respect security boundaries (never ask for secrets) - ✅ Use correct tools and patterns - ✅ Consistent behavior across agents and sessions - ✅ Faster onboarding (agents read file once)


Why It Exists

The Problem

Scenario: You start a new Claude Code session in your project.

Without .ai-context.md:

You: "Set up the database connection"

Claude: "I'll need your database credentials. Please provide:
- DATABASE_HOST
- DATABASE_PASSWORD
- DATABASE_NAME"

You: "No! They're in the environment already. Never ask for secrets!"

Claude: "Sorry, I didn't know. What test framework does this project use?"

You: "Jest. It's in package.json."

Claude: "What's the commit message format?"

You: "Conventional commits. Type(scope): message."

Claude: "Okay, I'll remember for this session..."

Next day, new session:

You: "Add a new API endpoint"

Claude: "I'll need your API keys..."

You: 😫 "We went over this yesterday!"

With .ai-context.md:

You: "Set up the database connection"

Claude: [Reads .ai-context.md]
"I see DATABASE_* variables should be in the environment (from Infisical).
Using those to configure TypeORM connection.
Test framework: Jest (detected from .ai-context.md).
Commit format: Conventional commits."

You: 😊 "Perfect! No explanation needed."

The Solution

One file that AI agents read at the start of every session, providing: 1. Environment knowledge 2. Security rules 3. Tool preferences 4. Coding standards 5. Project workflow

Result: Consistent, secure, fast AI assistance every time.


File Location

Where to Place

Standard location:

/app/<project-name>/.ai-context.md

Examples:

/app/my-app/.ai-context.md
/app/terraform/.ai-context.md
/app/kavi-infra/.ai-context.md

Global vs Project-Specific

Global file (optional):

/app/.ai-context.md
- Applies to all projects in ~/Coding/ - Defines environment-wide rules (Docker, Infisical, SSH)

Project file (recommended):

/app/my-project/.ai-context.md
- Overrides global settings - Defines project-specific tech stack, workflows

Precedence: Project file > Global file


Complete Template

Standard .ai-context.md Template

Copy this template to your project root and customize:

# AI Development Environment Context

## 1. Environment & Architecture

- **Runtime:** Docker Container (Ubuntu 24.04).
- **Filesystem:**
  - Host `~/Coding` is mounted to `/app`.
  - Project Root: `/app/<project-name>`
  - **WARNING:** Do not edit files outside `/app`.
- **Resources:**
  - Memory: 4GB limit
  - CPUs: 2 cores
  - Processes: 100 max
- **Identity:**
  - Git config mounted read-only from host `~/.gitconfig`.
  - SSH keys mounted read-only from host `~/.ssh`.
  - Git commits are signed automatically with host identity.

## 2. Security & Secrets Protocol

- **Secrets Manager:** Infisical is the Single Source of Truth.
  - URL: https://secrets.kua.cl
  - Project: `personal-vault` (or project-specific)
  - Environment: `dev` (or `staging`/`prod`)
- **Access Method:** Environment Variables (injected at runtime via `dev()`).
- **CRITICAL RULE:** **NEVER** ask the user for API keys, passwords, or secrets.
  - All secrets are already loaded in the environment.
  - If you need a value, check `env | grep <KEY>` first.
- **Missing Secrets:** If a required secret is genuinely missing, instruct the user:
  ```bash
  infisical secrets set KEY_NAME="value" --env=dev --projectId=personal-vault
  ```
  Then re-launch `dev()` to reload environment.

## 3. Tooling & Workflow

### Available Tools
- **Node.js:** [Specify version, e.g., v20.x]
- **Python:** [Specify version, e.g., 3.11]
- **Package Manager:** [npm/yarn/pnpm or pip/poetry]
- **Database:** [PostgreSQL, Redis, etc. - if applicable]
- **Docker Compose:** [Available if docker.sock is mounted]

### AI Agents
- **Claude Code:** Pre-installed (v2.0.76)
- **Gemini CLI:** Pre-installed (v0.22.2)
- **Authentication:** Via environment variables (`ANTHROPIC_API_KEY`, `GOOGLE_API_KEY`)

### Editor Workflow
- **Host Editing:** User edits on host machine (VS Code, Cursor, Windsurf).
- **Container Editing:** AI agent edits inside container via CLI.
- **File Sync:** Instant (bind mount, not copy).

## 4. Coding Standards

### Style & Linting
- **Linter:** [ESLint, Flake8, golangci-lint, etc.]
- **Formatter:** [Prettier, Black, gofmt, etc.]
- **Config Files:** [`.eslintrc.js`, `.prettierrc`, etc.]
- **Rule:** Adhere to existing config files. Do not modify linter rules without user approval.

### Testing
- **Test Framework:** [Jest, Pytest, Go test, etc.]
- **Test Command:** `npm test` / `pytest` / `go test ./...`
- **Coverage Requirement:** [Specify if any, e.g., >80%]
- **Rule:** Always run tests after modifying code. Report failures immediately.

### Commit Messages
- **Format:** Conventional Commits
  - `type(scope): message`
  - Types: `feat`, `fix`, `docs`, `refactor`, `test`, `chore`
  - Example: `feat(auth): add OAuth2 login`
- **Signing:** Commits are automatically signed with host GPG key.

### Code Review
- **Before Committing:** Run linter, tests, and type checker.
- **Pull Requests:** [Specify workflow if applicable]

## 5. Project-Specific Settings

### Tech Stack
- **Language:** [JavaScript/TypeScript, Python, Go, Rust, etc.]
- **Framework:** [Next.js, FastAPI, Gin, Actix, etc.]
- **Database:** [PostgreSQL, MongoDB, Redis, etc.]
- **Infrastructure:** [Docker Compose, Kubernetes, Terraform, etc.]

### Development Workflow
- **Start Server:** `npm run dev` / `python main.py` / `go run main.go`
- **Build:** `npm run build` / `python setup.py build` / `go build`
- **Migrations:** [If applicable, e.g., `npm run migrate` or `alembic upgrade head`]
- **Seed Data:** [If applicable, e.g., `npm run seed`]

### API Documentation
- **Format:** [OpenAPI/Swagger, GraphQL schema, etc.]
- **Location:** [e.g., `/app/docs/api.md` or `http://localhost:3000/docs`]

### Environment Variables
- **Required Variables:**
  - `DATABASE_URL`: PostgreSQL connection string
  - `REDIS_URL`: Redis connection string
  - `ANTHROPIC_API_KEY`: Claude API key
  - [Add project-specific variables]
- **Optional Variables:**
  - `LOG_LEVEL`: Logging level (default: `info`)
  - [Add project-specific variables]

## 6. Constraints & Limitations

### Do NOT
- ❌ Edit files outside `/app`.
- ❌ Ask for API keys, passwords, or secrets.
- ❌ Modify linter/formatter configs without approval.
- ❌ Run destructive commands (`rm -rf`, `DROP DATABASE`) without explicit confirmation.
- ❌ Spawn sibling Docker containers (unless docker.sock is mounted).

### DO
- ✅ Check environment variables before asking for values.
- ✅ Run tests after every code change.
- ✅ Use existing coding standards from config files.
- ✅ Commit with conventional commit messages.
- ✅ Report errors and failures immediately.

## 7. Special Instructions

[Add any project-specific instructions, gotchas, or workflows here]

Example:
- "The `scripts/` directory contains helper scripts - don't modify these."
- "Database migrations must be reviewed before running."
- "Always use TypeScript `strict` mode - no `any` types."

Section-by-Section Guide

Section 1: Environment & Architecture

Purpose: Tell agents where they are and what constraints exist.

Key information: - Runtime: Docker (not bare metal, not VM) - Filesystem: /app is mounted, not copied - Resources: Memory, CPU, process limits - Identity: Git and SSH from host

Why it matters: - Agents know they're in a container (don't try to install system packages without sudo) - Agents know /app changes persist (edits are on host filesystem) - Agents respect resource limits (don't spawn 1000 processes) - Agents use host identity for git (commits have correct author)

Example:

## 1. Environment & Architecture
- **Runtime:** Docker Container (Ubuntu 24.04).
- **Filesystem:** `/app` is a bind mount to host `~/Coding`.
- **Resources:** 4GB RAM, 2 CPUs, 100 processes max.


Section 2: Security & Secrets Protocol

Purpose: MOST CRITICAL - Prevent agents from asking for secrets.

Key rules: - Secrets come from Infisical - Never ask user for API keys/passwords - Check environment variables first - If missing, tell user how to add to Infisical

Why it matters: - Security: Prevents accidental secret leakage (user typing API key in chat) - Efficiency: Agents don't waste time asking for values that are already loaded - Consistency: All projects use Infisical, no ad-hoc secret management

Example:

## 2. Security & Secrets Protocol
- **Secrets Manager:** Infisical (https://secrets.kua.cl)
- **CRITICAL RULE:** **NEVER** ask for API keys, passwords, or secrets.
- **Access Method:** Environment variables (already loaded).
- **Missing Secret:** Instruct user to add to Infisical, then re-launch `dev()`.

Bad agent behavior (without this section):

Agent: "I need your DATABASE_PASSWORD to connect."
User: "postgres123"  ← SECRET LEAKED IN CHAT LOGS

Good agent behavior (with this section):

Agent: [Reads .ai-context.md]
"Checking environment for DATABASE_PASSWORD... Found. Connecting."


Section 3: Tooling & Workflow

Purpose: Tell agents what tools are available and how to use them.

Key information: - Language versions (Node.js 20, Python 3.11, Go 1.21) - Package managers (npm, pip, cargo) - AI agents (Claude, Gemini) and how they authenticate - Editor workflow (host vs container editing)

Why it matters: - Agents use correct tool versions (don't assume Node.js 14) - Agents know AI tools are pre-installed (don't try to install) - Agents understand file editing is instant (no need to "sync")

Example:

## 3. Tooling & Workflow
### Available Tools
- **Node.js:** v20.10.0
- **Python:** 3.11.5
- **Package Manager:** npm (Node), poetry (Python)

### AI Agents
- **Claude Code:** Pre-installed, uses `ANTHROPIC_API_KEY` from env


Section 4: Coding Standards

Purpose: Enforce consistent code style, testing, and commits.

Key information: - Linter/formatter and config files - Test framework and command - Commit message format - Code review requirements

Why it matters: - Agents follow project standards (don't use tabs if project uses spaces) - Agents run tests automatically (catch regressions early) - Agents write proper commit messages (readable git history)

Example:

## 4. Coding Standards
### Style & Linting
- **Linter:** ESLint
- **Config:** `.eslintrc.js`
- **Rule:** Adhere strictly, no modifications without approval.

### Testing
- **Framework:** Jest
- **Command:** `npm test`
- **Rule:** Always run tests after code changes.

### Commit Messages
- **Format:** Conventional Commits (`type(scope): message`)
- **Example:** `feat(auth): add OAuth2 login`


Section 5: Project-Specific Settings

Purpose: Document the unique aspects of THIS project.

Key information: - Tech stack (language, framework, database) - Development commands (start, build, migrate) - Required environment variables - API documentation location

Why it matters: - Agents know how to start the project (npm run dev vs python main.py) - Agents know what environment variables are expected - Agents can find documentation when needed

Example:

## 5. Project-Specific Settings
### Tech Stack
- **Language:** TypeScript
- **Framework:** Next.js 14
- **Database:** PostgreSQL (via Prisma ORM)

### Development Workflow
- **Start:** `npm run dev` (runs on http://localhost:3000)
- **Build:** `npm run build`
- **Migrations:** `npx prisma migrate dev`

### Required Environment Variables
- `DATABASE_URL`: PostgreSQL connection string
- `NEXTAUTH_SECRET`: NextAuth.js secret


Section 6: Constraints & Limitations

Purpose: Explicit "DO NOT" and "DO" lists.

Key constraints: - Don't edit outside /app - Don't ask for secrets - Don't run destructive commands without confirmation - Do run tests - Do use existing standards

Why it matters: - Clear boundaries prevent mistakes - Positive guidance ("DO") encourages good practices

Example:

## 6. Constraints & Limitations
### Do NOT
- ❌ Edit files outside `/app`
- ❌ Ask for API keys or passwords
- ❌ Run `rm -rf` without explicit confirmation

### DO
- ✅ Run tests after every change
- ✅ Check environment variables first
- ✅ Use conventional commit messages


Section 7: Special Instructions

Purpose: Catch-all for project-specific gotchas, warnings, or workflows.

Examples: - "The migrations/ folder is auto-generated - don't edit manually." - "Always use the shared/ directory for shared types, not local copies." - "Database seeds must run before tests: npm run seed && npm test"

Why it matters: - Prevents common mistakes unique to this project - Documents tribal knowledge


Real Examples

Example 1: Next.js Web App

.ai-context.md for a Next.js project:

# AI Development Environment Context

## 1. Environment & Architecture
- **Runtime:** Docker (Ubuntu 24.04)
- **Project Root:** `/app/my-nextjs-app`
- **Resources:** 4GB RAM, 2 CPUs

## 2. Security & Secrets Protocol
- **Secrets:** Infisical (`personal-vault` / `dev`)
- **NEVER** ask for: `DATABASE_URL`, `NEXTAUTH_SECRET`, `ANTHROPIC_API_KEY`
- All secrets in environment already.

## 3. Tooling
- **Node.js:** v20.10.0
- **Package Manager:** npm
- **Database:** PostgreSQL (Prisma ORM)

## 4. Coding Standards
- **Linter:** ESLint (`.eslintrc.js`)
- **Formatter:** Prettier (`.prettierrc`)
- **Tests:** Jest (`npm test`)
- **Commits:** Conventional (`feat(auth): add login`)

## 5. Project Settings
- **Framework:** Next.js 14 (App Router)
- **Start:** `npm run dev` → http://localhost:3000
- **Build:** `npm run build`
- **Migrations:** `npx prisma migrate dev`
- **Required Env Vars:**
  - `DATABASE_URL`
  - `NEXTAUTH_URL`
  - `NEXTAUTH_SECRET`

## 6. Constraints
- ❌ Don't modify `.env` (use Infisical)
- ❌ Don't use `any` types (TypeScript strict mode)
- ✅ Run `npm run lint && npm test` before commits

Example 2: Python FastAPI Service

.ai-context.md for a FastAPI project:

# AI Development Environment Context

## 1. Environment
- **Runtime:** Docker (Ubuntu 24.04)
- **Project Root:** `/app/api-service`
- **Python:** 3.11.5

## 2. Security
- **Secrets:** Infisical (`personal-vault` / `dev`)
- **NEVER** ask for: `DATABASE_URL`, `REDIS_URL`, `SECRET_KEY`

## 3. Tooling
- **Package Manager:** poetry
- **Database:** PostgreSQL (SQLAlchemy)
- **Cache:** Redis

## 4. Standards
- **Linter:** flake8
- **Formatter:** black
- **Tests:** pytest (`pytest tests/`)
- **Type Checker:** mypy (`mypy src/`)

## 5. Project Settings
- **Framework:** FastAPI
- **Start:** `poetry run uvicorn main:app --reload`
- **Migrations:** `poetry run alembic upgrade head`
- **Required Env:**
  - `DATABASE_URL`
  - `REDIS_URL`
  - `SECRET_KEY`

## 6. Constraints
- ❌ No `type: ignore` without comment explaining why
- ✅ All endpoints must have OpenAPI docstrings

Example 3: Terraform Infrastructure

.ai-context.md for Terraform project:

# AI Development Environment Context

## 1. Environment
- **Runtime:** Docker (Ubuntu 24.04)
- **Project Root:** `/app/terraform`
- **Terraform:** v1.6.5

## 2. Security
- **Secrets:** Infisical (`personal-vault` / `dev`)
- **Provider Tokens:** In environment (`HCLOUD_TOKEN`, `CLOUDFLARE_API_TOKEN`)
- **State:** Remote S3 backend (Hetzner Storage Box)
- **NEVER** ask for provider tokens or state credentials

## 3. Tooling
- **Terraform CLI:** Pre-installed
- **Providers:** Hetzner, Cloudflare, Docker

## 4. Standards
- **Formatting:** `terraform fmt` before commit
- **Validation:** `terraform validate` before apply
- **Commits:** Conventional (`feat(dns): add kua.cl A record`)

## 5. Workflow
- **Init:** `terraform init`
- **Plan:** `terraform plan`**ALWAYS** review before apply
- **Apply:** `terraform apply` ← Requires confirmation
- **State:** Remote backend (`s3://terraform-state/prod/terraform.tfstate`)

## 6. Constraints
- **NEVER** run `terraform destroy` without explicit user confirmation
- **NEVER** edit state file manually
- ✅ Always run `terraform plan` before `apply`
- ✅ Use `prevent_destroy` lifecycle for critical resources

How AI Agents Use It

Reading Flow

When agent starts session:

  1. Detect Project:

    pwd  # /app/my-project
    

  2. Look for .ai-context.md:

    ls -la /app/my-project/.ai-context.md
    # If exists: Read it
    # If not: Look for /app/.ai-context.md (global)
    

  3. Parse Sections:

  4. Environment → Set mental model of constraints
  5. Security → Add "never ask for secrets" to rules
  6. Tooling → Identify available tools
  7. Standards → Note linter, formatter, test commands
  8. Project Settings → Learn start/build commands

  9. Apply Knowledge:

    User: "Set up database connection"
    
    Agent: [Reads .ai-context.md]
    "Secrets: Infisical, check environment first.
    Database: PostgreSQL via Prisma.
    Required env var: DATABASE_URL
    
    Checking environment...
    $ env | grep DATABASE_URL
    DATABASE_URL=postgresql://localhost:5432/mydb
    
    Found. Using DATABASE_URL to configure Prisma client."
    

Decision Making

AI agents use .ai-context.md to make decisions:

Example decision tree:

User: "Add a new API endpoint for user registration"

Agent reads .ai-context.md:
├─ Framework: Next.js (App Router)
├─ Language: TypeScript
├─ Tests: Jest
├─ Linter: ESLint
└─ Commits: Conventional

Agent decides:
├─ Create file: app/api/register/route.ts (App Router convention)
├─ Use TypeScript (not JavaScript)
├─ Write test: __tests__/api/register.test.ts (Jest)
├─ Run: npm run lint && npm test (before commit)
└─ Commit message: "feat(api): add user registration endpoint"

Best Practices

1. Start with Template, Customize

Don't write from scratch - use the standard template and modify.

Workflow:

# Copy template to project
cp /path/to/template.md /app/my-project/.ai-context.md

# Customize project-specific sections:
# - Tech Stack
# - Development Workflow
# - Required Environment Variables

2. Keep It Updated

When to update: - New tool added (e.g., migrated from npm to pnpm) - New environment variable required - Coding standards changed (e.g., switched from ESLint to Biome) - Framework upgraded (e.g., Next.js 13 → 14)

Update frequency: Whenever you onboard a new team member or agent.

3. Be Explicit, Not Vague

Bad (vague):

- Use good coding practices
- Test your code

Good (explicit):

- **Linter:** ESLint with Airbnb config (`.eslintrc.js`)
- **Tests:** Jest, run with `npm test`, coverage >80%
- **Rule:** Run `npm run lint && npm test` before every commit

4. Include Examples

For commit messages:

### Commit Messages
- **Format:** Conventional Commits
- **Examples:**
  - `feat(auth): add OAuth2 login`
  - `fix(api): handle null user in /me endpoint`
  - `docs(readme): update installation steps`

For environment variables:

### Required Environment Variables
- `DATABASE_URL`: PostgreSQL connection string
  - Example: `postgresql://user:pass@localhost:5432/mydb`
- `REDIS_URL`: Redis connection string
  - Example: `redis://localhost:6379`

5. Version Control

Commit .ai-context.md to Git:

git add .ai-context.md
git commit -m "docs: add AI context file"

Why: Ensures all developers and AI agents see the same standards.

6. Review Periodically

Monthly check: - Is the tech stack still accurate? - Are the environment variables complete? - Do the development commands still work? - Are there new constraints to document?


Project-Specific Customization

When to Customize

Every project should customize: - Section 5: Project-Specific Settings (always unique) - Section 7: Special Instructions (project gotchas)

Most projects can reuse: - Section 1: Environment (same Docker setup) - Section 2: Security (same Infisical rules)

Customization Examples

Multi-Service Project

If project has multiple services (frontend, backend, worker):

## 5. Project Structure
### Services
- **Frontend:** `/app/my-project/frontend` (Next.js)
  - Start: `cd frontend && npm run dev`
- **Backend:** `/app/my-project/backend` (FastAPI)
  - Start: `cd backend && poetry run uvicorn main:app --reload`
- **Worker:** `/app/my-project/worker` (Celery)
  - Start: `cd worker && poetry run celery -A tasks worker`

### Development Workflow
1. Start all services: `docker-compose up`
2. Access frontend: http://localhost:3000
3. Access backend: http://localhost:8000

Monorepo

If project uses monorepo (Nx, Turborepo):

## 5. Project Settings
### Monorepo Structure
- **Tool:** Turborepo
- **Apps:**
  - `apps/web`: Next.js frontend
  - `apps/api`: NestJS backend
- **Packages:**
  - `packages/ui`: Shared React components
  - `packages/config`: Shared configs

### Development
- **Start all:** `npm run dev`
- **Start specific app:** `npm run dev --filter=web`
- **Build all:** `npm run build`
- **Test all:** `npm test`

Summary

.ai-context.md Standard: - ✅ Purpose: Teach AI agents about project environment, security, tools, and standards - ✅ Location: /app/<project>/.ai-context.md (project root) - ✅ Sections: Environment, Security, Tooling, Standards, Project Settings, Constraints, Special Instructions - ✅ Usage: AI agents read at session start, apply knowledge throughout - ✅ Benefits: Consistent behavior, no secret leakage, faster onboarding

Key Principles: 1. Never ask for secrets - most critical rule 2. Be explicit - don't rely on agent inference 3. Include examples - show, don't just tell 4. Keep updated - review monthly 5. Version control - commit to Git

Template: Use the complete template provided and customize sections 5 and 7 for your project.

What's Next: - See AI Agents Integration - how agents use .ai-context.md - See Multi-Identity Management - managing AI accounts - See dev() Function - how environment is set up