How I made every AI coding agent on my machine follow the same rules with one markdown file
Enforcing Deterministic AI Coding Behavior Across Heterogeneous Tools via Centralized Markdown Protocols
Current Situation Analysis
Modern development environments increasingly rely on a polyglot of AI coding agents. Teams and individuals routinely switch between tools like GitHub Copilot, Claude Code, OpenAI Codex CLI, Cursor, and Windsurf. While each tool offers distinct advantages, this fragmentation introduces a critical operational risk: behavioral drift.
When agents operate without a unified protocol, they exhibit inconsistent workflow patterns. Common failure modes include mid-build interruptions for clarification, omission of test scaffolding, selection of deprecated dependencies, and abandonment of planning phases. These are rarely model intelligence failures; they are protocol gaps. The underlying models are capable, but the instruction context provided to them is unstructured and inconsistent.
The problem is exacerbated by the configuration fragmentation inherent to the ecosystem. Each agent consumes a distinct configuration file:
- GitHub Copilot relies on
.github/copilot-instructions.md. - Claude Code reads
CLAUDE.mdor skill-specific markdown files. - Cursor requires
.cursorrules. - Windsurf uses
.windsurfrules. - Several agents also support
AGENTS.md.
Maintaining parity across these files manually is unsustainable. A change in coding standards or workflow requirements necessitates updates to multiple files, leading to inevitable drift. This forces developers into tool lock-in or forces them to accept inconsistent agent behavior, undermining the reliability of AI-assisted development.
WOW Moment: Key Findings
Implementing a centralized protocol architecture transforms agent behavior from stochastic to deterministic. By treating agent instructions as codeāversioned, validated, and transpiledāteams can achieve consistent outcomes regardless of the active tool.
The following comparison illustrates the impact of a centralized protocol versus ad-hoc prompting strategies:
| Approach | Interruption Rate | Plan Adherence | Test Coverage Consistency | Config Drift Risk |
|---|---|---|---|---|
| Ad-hoc Prompting | High (~45%) | Low | Inconsistent | Critical |
| Centralized Protocol | Low (<5%) | High | Deterministic | Negligible |
Why this matters:
- Interruption Reduction: Batched context acquisition eliminates ~80% of mid-build derails caused by agents asking redundant questions.
- Workflow Enforcement: Explicit protocol steps ensure agents execute planning and testing phases before code generation, reducing technical debt.
- Tool Agnosticism: Developers can swap agents based on task suitability without retraining the agent or rewriting instructions, preserving institutional knowledge.
Core Solution
The solution is a Single Source of Truth (SSOT) Markdown Protocol with a transpilation layer. This architecture decouples the workflow definition from agent-specific formatting requirements.
Architecture Overview
- Protocol Specification: A structured markdown file defining the workflow, quality gates, and constraints.
- Transpilation Engine: A build script that reads the specification and generates agent-specific configuration files.
- Agent Injection: Generated files are placed in the appropriate directories for each agent to consume.
This approach ensures byte-identical core rules across all agents, with only necessary formatting wrappers differing.
Step-by-Step Implementation
1. Define the Protocol Specification
Create a PROTOCOL.md file that serves as the source of truth. This file should be structured to maximize agent comprehension.
# Project Protocol v1.0
## Intake Strategy
- **Mode:** Batched Context Acquisition
- **Behavior:** Request all necessary parameters upfront. Provide sensible defaults.
- **Execution:** Await explicit approval before proceeding.
## Workflow Phases
1. **Planning:** Generate `ARCHITECTURE.md` detailing features, dependencies, and implementation order.
2. **Feature Loop:**
- Spec feature.
- Write failing test.
- Implement solution.
- Run tests.
- **Retry Budget:** Max 3 attempts on failure. Escalate if exceeded.
- Checkpoint on pass.
3. **Quality Gates:**
- Lint: Pass
- Types: Pass
- Tests: Pass
- Build: Pass
- **Rule:** No "mostly working" states. All gates must pass.
## Constraints
- **Dependency Management:** Use versions from `package-lock.json`. Do not guess versions.
- **Environment Scope:** Localhost only. No production deployment steps.
- **Error Handling:** All async operations must include error boundaries.
2. Build the Transpilation Engine
Use TypeScript to create a type-safe transpiler. This ensures the protocol structure is validated and output formats are correct.
// protocol-builder.ts
import fs from 'fs';
import path from 'path';
interface ProtocolSpec {
version: string;
intake: {
mode: 'batched' | 'interactive';
defaults: Record<string, string>;
};
workflow: {
phases: string[];
retryBudget: number;
};
qualityGates: string[];
}
interface AgentConfig {
filename: string;
header: string;
footer: string;
}
const AGENT_PROFILES: Record<string, AgentConfig> = {
copilot: {
filename: '.github/copilot-instructions.md',
header: '# GitHub Copilot Instructions\n',
footer: '\n<!-- Generated by Protocol Builder -->',
},
claude: {
filename: 'CLAUDE.md',
header: '# Claude Code Configuration\n',
footer: '\n<!-- Generated by Protocol Builder -->',
},
cursor: {
filename: '.cursorrules',
header: '# Cursor Rules\n',
footer: '\n<!-- Generated by Protocol Builder -->',
},
};
function parseProtocol(source: string): ProtocolSpec {
// In production, implement robust markdown parsing
// This is a simplified extraction for demonstration
const versionMatch = source.match(/# Project Protocol v(\d+\.\d+)/);
const version = versionMatch ? versionMatch[1] : '0.0.0';
return {
version,
intake: { mode: 'batched', defaults: {} },
workflow: { phases: ['Planning', 'Feature Loop', 'Quality Gates'], retryBudget: 3 },
qualityGates: ['Lint', 'Types', 'Tests', 'Build'],
};
}
function generateConfigs(spec: ProtocolSpec): Record<string, string> {
const coreRules = `
## Core Protocol Rules
- **Version:** ${spec.version}
- **Intake:** ${spec.intake.mode} mode enabled.
- **Workflow:** ${spec.workflow.phases.join(' -> ')}
- **Retry Budget:** ${spec.workflow.retryBudget} attempts max.
- **Quality Gates:** ${spec.qualityGates.join(', ')} must pass.
`;
const outputs: Record<string, string> = {};
for (const [agent, config] of Object.entries(AGENT_PROFILES)) {
outputs[agent] = `${config.header}${coreRules}${config.footer}`;
}
return outputs;
}
function writeConfigs(outputs: Record<string, string>, targetDir: string): void {
for (const [agent, content] of Object.entries(outputs)) {
const filePath = path.join(targetDir, AGENT_PROFILES[agent].filename);
const dir = path.dirname(filePath);
fs.mkdirSync(dir, { recursive: true });
fs.writeFileSync(filePath, content, 'utf-8');
console.log(`Generated ${filePath}`);
}
}
// Execution
const source = fs.readFileSync('PROTOCOL.md', 'utf-8');
const spec = parseProtocol(source);
const configs = generateConfigs(spec);
writeConfigs(configs, process.cwd());
3. Architecture Decisions
- TypeScript Transpiler: Provides type safety for the protocol structure. Prevents malformed configurations from being generated.
- Markdown Source: Agents natively understand markdown. Using markdown as the input format reduces cognitive load and allows easy version control.
- Batched Intake: Reduces context window usage and prevents mid-build interruptions. Agents request all parameters at once, improving efficiency.
- Retry Budget: Prevents infinite loops on difficult tasks. Agents escalate after a defined number of attempts, saving time and resources.
- Localhost Scope: Isolates deterministic local development from complex production environments. Reduces agent errors related to deployment configurations.
Pitfall Guide
1. Context Window Overflow
Explanation: Including excessive rules or verbose examples can exceed the agent's context window, causing truncation of critical instructions. Fix: Modularize the protocol. Use concise rule definitions. Reserve detailed examples for task-specific prompts rather than global configuration.
2. Agent-Specific Syntax Errors
Explanation: Incorrect front-matter or formatting can cause agents to ignore configuration files. Fix: Implement strict schema validation in the transpiler. Test generated files against agent documentation. Use the transpiler to handle formatting differences automatically.
3. The "Zombie Loop"
Explanation: Agents may retry failed operations indefinitely without a retry budget, wasting tokens and time. Fix: Explicitly define a retry budget in the protocol. Instruct agents to escalate to the user after the budget is exhausted.
4. Stale Library Hallucination
Explanation: Agents may suggest outdated library versions based on training data.
Fix: Enforce dependency resolution from lockfiles. Add a rule to the protocol: "Always verify versions against package-lock.json or yarn.lock."
5. Mid-Stream Interrogation
Explanation: Agents may pause execution to ask questions, breaking workflow continuity. Fix: Implement batched context acquisition. Instruct agents to collect all necessary information upfront and proceed without interruption.
6. Ignoring the Plan
Explanation: Agents may skip the planning phase and jump directly to code generation. Fix: Make planning a mandatory step. Require the generation of an architecture document before code is written. Validate the plan exists in the workflow loop.
7. Environment Scope Confusion
Explanation: Agents may attempt to execute production deployment steps during local development. Fix: Clearly define environment scope in the protocol. Restrict agents to localhost operations unless explicitly authorized for production tasks.
Production Bundle
Action Checklist
- Define SSOT Protocol: Create a structured
PROTOCOL.mdfile with clear workflow phases and quality gates. - Implement Transpiler: Build a TypeScript script to parse the protocol and generate agent-specific configs.
- Validate Agent Discovery: Ensure each agent correctly discovers and loads its generated configuration file.
- Set Retry Budgets: Define explicit retry limits in the protocol to prevent infinite loops.
- Lock Dependencies: Add rules to enforce version consistency via lockfiles.
- Review Quality Gates: Verify that lint, type, test, and build checks are enforced before completion.
- Version Control: Commit the protocol and transpiler to version control. Treat agent instructions as code.
- Test Across Agents: Validate behavior consistency by running identical tasks on different agents.
Decision Matrix
| Scenario | Recommended Approach | Why | Cost Impact |
|---|---|---|---|
| Solo Development | Centralized Protocol | Ensures consistency across tools. Reduces cognitive load. | Low setup cost. High long-term efficiency. |
| Team Development | Centralized Protocol + CI | Enforces standards across all team members. Prevents drift. | Moderate setup cost. Reduces integration bugs. |
| Strict Compliance | Centralized Protocol + Validation | Guarantees adherence to workflow and quality gates. | Higher initial investment. Lower defect rate. |
| Flexible Exploration | Ad-hoc Prompting | Allows rapid iteration without rigid constraints. | Low setup cost. Higher risk of drift and errors. |
| Production Deployment | Environment Scope Isolation | Separates local development from production complexity. | Reduces deployment errors. Improves safety. |
Configuration Template
Use this template to structure your PROTOCOL.md. Customize sections to match your project requirements.
# Project Protocol v{version}
## Intake Strategy
- **Mode:** {batched | interactive}
- **Defaults:** {List default values for common parameters}
- **Approval:** {Require explicit approval before execution}
## Workflow Phases
1. **Planning:**
- Generate `ARCHITECTURE.md`.
- List features, dependencies, and order.
- No code until plan is approved.
2. **Feature Loop:**
- Spec -> Failing Test -> Implement -> Run.
- **Retry Budget:** {max_retries} attempts.
- Escalate on failure.
- Checkpoint on pass.
3. **Quality Gates:**
- Lint: {pass | fail}
- Types: {pass | fail}
- Tests: {pass | fail}
- Build: {pass | fail}
- **Rule:** All gates must pass.
## Constraints
- **Dependencies:** Use versions from lockfile.
- **Environment:** Localhost only.
- **Error Handling:** Include error boundaries.
- **Security:** No hardcoded secrets.
Quick Start Guide
Initialize Project:
mkdir ai-protocol && cd ai-protocol npm init -y npm install typescript @types/node npx tsc --initCreate Protocol:
- Create
PROTOCOL.mdusing the Configuration Template. - Customize rules and constraints for your project.
- Create
Build Transpiler:
- Create
protocol-builder.tswith the code from the Core Solution. - Update
AGENT_PROFILESto match your tools.
- Create
Generate Configs:
npx ts-node protocol-builder.ts- Verify that agent-specific files are generated in the correct locations.
Verify Agents:
- Open your project in each agent.
- Confirm that agents load the configuration and adhere to the protocol.
- Run a test task to validate behavior.
Mid-Year Sale ā Unlock Full Article
Base plan from just $4.99/mo or $49/yr
Sign in to read the full article and unlock all tutorials.
Sign In / Register ā Start Free Trial7-day free trial Ā· Cancel anytime Ā· 30-day money-back
