| layout | page |
|---|---|
| importance | 1 |
| category | Tier 1: Foundation |
| title | 01. Declarative Codebase |
| nav_order | 1 |
| description | Every artifact — code, infrastructure, prompts — lives in version control as a declarative specification. |
| render_with_liquid | false |
Every artifact — application code, infrastructure, configuration, and AI prompts — lives in version control as a declarative, reproducible specification.
A codebase is the single source of truth for a system. In the original 12-Factor App, this meant "one codebase tracked in revision control, many deploys." That principle remains, but the scope of what constitutes a "codebase" has expanded dramatically. Infrastructure-as-Code (IaC), GitOps pipelines, and now prompt-as-code mean the declarative codebase encompasses far more than application source files.
When AI is both a tool used in development and a component of the running system, the boundary of "code" blurs. A system prompt is as much a part of the application's behavior as a controller or service class. If it isn't versioned, reviewed, and deployed through the same pipeline, it's shadow configuration — invisible, unauditable, and unreproducible.
Original Factor #1: Codebase — "One codebase tracked in revision control, many deploys."
The original factor focused on the relationship between a codebase and its deploys. This update retains that principle and extends it to cover:
- Infrastructure definitions (Terraform, Pulumi, CloudFormation)
- GitOps manifests (Kubernetes YAML, Helm charts, Kustomize overlays)
- AI prompts, system instructions, and agent tool definitions
- Evaluation datasets and quality benchmarks (or, for large corpora, the manifests and content hashes that pin them to a specific version in object storage)
- Pipeline definitions (CI/CD as code)
- AI coding assistants (Copilot, Claude Code, Cursor) generate code that must still pass the same review, lint, and test gates as human-written code. The codebase is the arbiter, not the generation method.
- AI-generated code is held to the same review, testing, and CI bar as human-written code — once it lands, it gets no second-class treatment in the codebase. Quality is judged by the gates it passed, not by its origin.
- Track AI authorship in metadata, not in source. Commit trailers (
Assisted-by: claude-code,Co-authored-by:), PR labels, or an audit log are the right surface for provenance — they enable measurement (AI contribution rate, review cycle deltas, defect rates by authorship class, ramp-up impact) without polluting the source with markers that rot. Inline comments like// AI-generatedare an anti-pattern: they degrade as code is edited, create review bias, and make refactoring noisier. The codebase stays clean; the metadata layer carries the signal. - Context files (
AGENTS.md,CLAUDE.md,.cursor/rules/*.mdc,.github/copilot-instructions.md) that guide AI coding assistants are themselves part of the codebase and should be versioned.AGENTS.mdhas emerged as the cross-tool convention and is now stewarded by the Agentic AI Foundation (Linux Foundation); the single-file.cursorrulesis deprecated in favor of the.cursor/rules/directory. Agent Skills directories (SKILL.md, see Factor 2) belong in the same category: versioned, reviewed, and kept small. - Autonomous coding agents (Claude Code, Devin, Codex, GitHub Copilot coding agent) can create branches, write code, run tests, and open pull requests autonomously — increasingly as background agents running in cloud sandboxes. The codebase must be prepared for this: CI gates, evaluation suites (Factor 6), and ephemeral environments (Factor 11) must validate agent-generated changes without human intervention in the loop. The human reviews the output, not the process.
- Prompt-as-code: System prompts, few-shot examples, and chain-of-thought templates are versioned alongside application code. They go through pull requests, code review, and CI checks.
- Agent tool schemas: Tool definitions (JSON Schema, OpenAPI specs) that define what an AI agent can do are declarative specifications that belong in the codebase.
- Evaluation datasets: The golden datasets used to evaluate AI output quality are versioned artifacts. Small datasets can live in the repo like test fixtures; large ML eval corpora (gigabytes to terabytes) live in object storage with the repo holding an immutable, content-addressed pointer (Git LFS, DVC manifest, lakeFS commit, Hugging Face dataset revision, or a versioned S3 URI). The repository is still the source of truth for which version of the dataset a given commit was evaluated against.
- Model configuration: Model selection, reasoning effort, token limits, and other inference parameters are declared in config files, not buried in application code.
Organize AI artifacts alongside traditional code:
repo/
├── src/ # Application source
├── infra/ # IaC definitions
├── k8s/ # GitOps manifests
├── prompts/ # Versioned prompt templates
│ ├── system.md
│ ├── few-shot-examples/
│ └── chains/
├── evals/ # Evaluation datasets and configs
│ ├── golden-set.jsonl
│ └── eval-config.yaml
├── tools/ # Agent tool schemas
│ └── tool-definitions.json
├── specs/ # Feature specs for spec-driven development
├── AGENTS.md # AI coding assistant context (cross-tool)
├── CLAUDE.md # AI coding assistant context (Claude Code)
├── .cursor/rules/ # AI coding assistant context (Cursor)
├── .github/copilot-instructions.md # AI coding assistant context (Copilot)
└── pipeline.yaml # CI/CD definition
Treat prompts as first-class code artifacts with variable interpolation:
# prompts/summarization/system.md
You are a document summarizer for {{company_name}}.
## Instructions
- Summarize the document in {{language}}, max {{max_sentences}} sentences.
- Preserve all numerical data and proper nouns.
- If the document contains PII, replace it with [REDACTED].
## Context
{{retrieved_context}}Load, render, and validate templates through one code path that fails on undefined variables, rather than assembling prompts from string literals scattered through the code.
Use pull requests for prompt changes — diffs are meaningful and reviewable. Tag prompt versions that correspond to production deployments.
When coding agents write most of the implementation, the durable, reviewable artifact moves upstream to the spec. Spec-driven development (SDD), popularized in 2025–2026 by GitHub Spec Kit, AWS Kiro, and OpenSpec, has the human and the agent agree on requirements, a technical design, and a task breakdown before code is generated. The agent implements against that spec, and the spec stays in the repository.
specs/
└── 0042-refund-agent/
├── requirements.md # user stories + acceptance criteria ("WHEN … THE SYSTEM SHALL …")
├── design.md # architecture, interfaces (links to Factor 2 contracts), data model
└── tasks.md # ordered implementation steps the agent executes and checks off
Treat specs like every other declarative artifact in this factor:
- Reviewed before implementation: the spec PR is where design review happens; the implementation PR is checked against it. Reviewers who cannot read every generated line can still verify behavior against an agreed spec.
- Versioned with the code: a behavior change starts as a spec change, so the history explains why the code changed.
- Traceable: acceptance criteria map to tests and eval cases (Factor 6); interface sections link to the contracts they produce (Factor 2).
- Kept honest: a spec that drifts from the code is worse than none. Update it in the same PR as the behavior change, or delete it.
Validate prompts and schemas in the CI pipeline, just like application code. At minimum, CI checks that:
- Prompt templates parse and every variable is defined — a missing variable fails the build instead of rendering as an empty string in production.
- Tool schemas are valid JSON Schema and match the contracts they implement (Factor 2).
- Prompts fit their token budgets once rendered with realistic context (Factor 17).
- A quick evaluation suite passes — a fast subset of the full suite, which still gates the release (Factor 6).
Declare model versions, endpoint configurations, and feature flags in Git, so the GitOps pipeline deploys them on merge:
- Each use case names an immutable model ID — never a floating alias (Factor 16) — together with the previous known-good ID to roll back to.
- Feature flags switch only between evaluated configurations. Flipping a flag between combinations of model, prompt, and parameters that already passed evaluation needs no redeploy; a new combination goes through the eval gate and the release pipeline first (Factor 5, Factor 6).
Rollback is a git revert, not a manual infrastructure change.
A Software Bill of Materials (SBOM) catalogs every software component in a release. For AI applications, this extends to an AI Bill of Materials (AIBOM) — also called an MLBOM — listing model identifiers, prompt versions, evaluation scores, and training data references. Generate AIBOMs in SPDX 3.0 (AI Profile) or CycloneDX 1.6 (ML Extension) format as part of the build pipeline (Factor 5).
The AIBOM is a versioned artifact alongside application code, answering: "What model is in this release? What prompt? What eval score did it achieve?" It is required for supply-chain audits and increasingly expected by enterprise procurement.
GitOps workflows often need encrypted values committed to the repository. SOPS (now a CNCF project, formerly Mozilla SOPS) encrypts file values using AWS KMS, GCP KMS, or age keys — keeping structure visible in diffs while keeping values encrypted. Sealed Secrets for Kubernetes encrypts secrets with a cluster-side public key so only the cluster can decrypt them. Both patterns allow AI API keys, model registry tokens, and vector database credentials to be managed in Git without plaintext exposure.
The original factor's "one codebase, many deploys" still applies. Whether using a monorepo or multi-repo strategy, each deployable unit has a single codebase. Shared libraries are dependencies (Factor 3), not copy-pasted code.
- All application code is in version control with a clear branching strategy
- Infrastructure is defined as code (Terraform, Pulumi, CDK, etc.) and versioned
- Deployment manifests are declarative and versioned (Helm, Kustomize, etc.)
- CI/CD pipelines are defined as code, not configured through UIs
- AI system prompts and templates are versioned alongside application code
- Agent tool definitions and schemas are in the repository
- Evaluation datasets and benchmarks are versioned artifacts
- AI coding assistant context files are maintained and versioned
- Feature specs (requirements, design, tasks) that drive coding agents are versioned in the repository and updated in the same change as the behavior they describe
- AI authorship is tracked in commit metadata or PR labels (not in source comments) so contribution metrics — AI contribution rate, review cycle deltas, defect rates by authorship class — can be measured
- Model configuration (selection, parameters) is declared in config files
- Every production deployment is traceable to a specific commit
- An AIBOM/MLBOM is generated as a build output in SPDX 3.0 or CycloneDX 1.6 format
- Encrypted secrets committed to Git use SOPS or Sealed Secrets — no plaintext secrets in any branch