Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

A-26020: AI-Native Development — Code as Primary Documentation


title: AI-Native Development — Code as Primary Documentation authors:


A-26020: AI-Native Development — Code as Primary Documentation

Problem Statement

The ecosystem uses AI agents (Claude Code, Qwen Code, aider) as primary development tools. These agents read code, tests, and configuration files to understand what they can safely modify. The question is: what documentation strategy maximizes agent safety and productivity across all languages and project types?

Traditional software documentation assumes a human reader with persistent memory who navigates docs separately from code. AI agents operate differently:

  1. Agents are stateless. Each session starts fresh — the agent reads the current file state, not a knowledge base built over months of onboarding (ADR-26030).

  2. Agents have a finite context window. Every token of documentation competes with code tokens for attention budget. NVIDIA RULER shows effective context is only 50-65% of advertised window size (ADR-26038).

  3. Agents read code natively. An LLM parses Python, JavaScript, YAML, or Bash as fluently as prose — often more reliably, because code has deterministic structure while prose is ambiguous.

  4. Agents cannot verify prose accuracy. A docstring that contradicts the code is caught at import time. A separate doc file that contradicts the code passes all CI checks silently (A-26014, Table 1).

These properties invert the traditional documentation hierarchy: code structure is the primary documentation layer, and prose documentation is supplementary context for cases where code alone is insufficient.

Key Insights

1. The Three-Layer Documentation Model

Evidence from A-26014 (script suite doc redundancy) established that three documentation layers now exist in the ecosystem:

LayerLocationVerified by CISurvives refactoring
Contract docstringIn the source fileImport/compile timeYes — moves with the code
Test suiteAdjacent test fileTest runnerYes — fails if contract breaks
Prose documentationSeparate fileExistence check onlyNo — drifts silently

The contract docstring is the most agent-friendly layer because it is:

The test suite is the second layer — it documents contracts by example with parametrized inputs that pytest infrastructure renders as diagnostics.

Prose documentation is the weakest layer for agents. A-26014 found that 15+ instruction docs in tools/docs/scripts_instructions/ contained stale references to deleted config files (evidence.config.yaml, architecture.config.yaml) that would have passed CI silently.

2. The Contract Docstring Pattern Is Language-Agnostic

The contract docstring structure answers one question: “What does a future agent need to read first to work safely in this file?” A-26014: Script Suite Documentation Redundancy established that contract docstrings are one of three documentation layers, and the only one that is both CI-verified and co-located with the code it describes.

The answer is the same regardless of language:

This maps directly to language-specific constructs:

LanguageDocstring mechanismTest mechanism
PythonModule/class/function docstringspytest
JavaScript/TypeScriptJSDoc / /** */ blocksJest, Vitest
BashHeader comment block (# ---)bats, shunit2
YAML/JSON configsDescription fields in schemaJSON Schema validation
SQLCOMMENT ON statementspgTAP

The pattern is: structured metadata at the top of every unit of code, in the language’s native documentation format. This is not a Python convention — it is a development methodology.

3. Why “Any Code, Any Language” — The Agent Context Budget Argument

ADR-26038 establishes context engineering as the core design principle. The MIT/Kellogg finding (cited in ADR-26038) shows that 80% of production agent work is data engineering, governance, and workflow integration — not AI. This means agents spend most of their context budget reading infrastructure code (CI configs, deployment scripts, validation hooks) not just application code.

If only Python files have contract docstrings while Bash scripts, YAML configs, and SQL migrations lack them, the agent must:

  1. Read the entire file to understand scope (expensive)

  2. Guess at boundaries and design decisions (error-prone)

  3. Risk undoing intentional choices it cannot identify (dangerous)

The v0.30-v0.41 Mentor Generator postmortems (documented in A-26002) demonstrated this concretely: “Instructions don’t scale. Each additional instruction increases the probability of failure somewhere else.” When agents must infer intent from unstructured code, they compensate by asking more questions or making conservative (often wrong) assumptions.

4. Test Diagnostics as Agent-Readable Documentation

Ecosystem practice has converged on test patterns that optimize for agent consumers: testing contracts rather than implementation, using semantic assertions, parametrizing inputs. This analysis formalizes these patterns as three principles for agent-native TDD:

  1. Names over messages. Test method names are the primary diagnostic channel. test_rejects_negative_timeout tells the agent the contract; a custom assertion message repeats what the test name already says. Agents parse method names programmatically — assertion strings require natural language understanding.

  2. Parametrize over multiply-assert. @pytest.mark.parametrize with varied inputs lets test infrastructure show which specific input failed. Custom assertion messages are the documentation-in-implementation anti-pattern — they couple to intent that the test name should convey.

  3. Contracts over pipelines. Test docstrings describe what survives refactoring (exit codes, return types, side effects), not what breaks on refactoring (internal call sequences, mock counts). An agent reading assert exit_code == 1 understands the contract; an agent reading assert mock.call_count == 3 understands an implementation detail that will change on the next refactor.

These three principles produce a diagnostics hierarchy for agents encountering a test failure: test name → test framework introspection → contract docstring. Custom messages only where the failure mode is genuinely ambiguous.

5. Relationship to Existing Governance

This methodology connects to multiple existing architectural decisions:

6. What Prose Documentation Remains Necessary

Code-as-documentation does not eliminate all prose. The following require human-authored narrative:

The distinction: prose documents explain cross-cutting concerns that no single file owns. Per-file documentation belongs in the file.

Approach Evaluation

Write an ADR mandating contract docstrings for all code in all languages across the ecosystem. Enforcement via pre-commit hooks (language-specific linters checking for module-level documentation). Existing code migrates incrementally — new files must comply, existing files comply when modified.

Pros:

Cons:

Mitigation: Enforcement checks structure (docstring exists, contains required sections), not semantic quality. Quality comes from code review and agent feedback loops.

Option B: Keep as CLAUDE.md Convention Only

Leave the contract docstring requirement in CLAUDE.md without an ADR.

Pros:

Cons:

Option C: Per-Language ADRs

Write separate ADRs for Python, Bash, YAML, SQL docstring conventions.

Pros:

Cons:

Rejected: The decision is language-agnostic. Language-specific enforcement details belong in the ADR’s Consequences section, not separate ADRs.

References