[From constitution.md to Compliance: A Practical Security Layer for SDD]
Analyze with AI
Get AI-powered insights from this Mad Devs tech article:
Most teams adopt AI-assisted development incrementally: a Copilot suggestion here, a GPT-generated scaffold there. Security, meanwhile, stays where it has always lived — in code review checklists, SAST pipelines, and the institutional knowledge of whoever happened to catch the last injection vulnerability. The problem with this split is architectural. When security rules live downstream of the specification phase, they arrive late, apply inconsistently, and depend on human attention that is finite and unevenly distributed across the team.
Spec-driven development (SDD) with AI agents changes the equation — but only if you treat security as a first-class input to the specification itself, rather than an afterthought bolted onto the output. At Mad Devs, we have been refining a workflow that encodes security requirements directly into a file we call constitution.md. This guide documents what that file is, how it is structured, and how it becomes part of an enforceable workflow when connected to agent instructions, automated checks, CI gates, and review protocols.
Constitutional spec-driven development: encoding security rules into your AI workflow
The core idea behind constitutional SDD is straightforward: before an AI agent writes a single line of implementation, it reads a governing document that defines what it is allowed to produce. That document is the constitution. Every output the agent generates (code, architecture decisions, API contracts, migration scripts) is evaluated against those constraints before it lands in the codebase.
This is different from writing a system prompt that says, "Follow OWASP guidelines." A prompt is advisory unless it is backed by verification. A constitutional document becomes structural when its rules are translated into review gates, automated checks, CI pipelines, and traceability artifacts. The document itself is a normative layer. The enforcement comes from what you connect to it.
Why does this matter for AI coding security specifically? Because security requirements have a property that makes them hard to enforce at review time: they are primarily absence requirements. A secure endpoint does not contain SQL injection vulnerabilities. A secure token handler does not log credentials. A secure file upload does not trust client-supplied MIME types. These are things that should not be present, and the absence of something is far harder to audit than the presence of something. If the constraint lives in the specification layer, the agent is less likely to generate the prohibited pattern in the first place. But if it does, the violation is traceable to a specific rule, not to a reviewer's missed comment on line 847.
Constitutional constraints in AI-assisted development make incorrect outputs easier to prevent, detect, and reject before merging. That is the foundation of SDD compliance: not an assertion that security is guaranteed, but a structured, auditable process for reducing the attack surface at the earliest stage.
The constitutional layer: what it is and where it lives
In a typical SDD workflow, there are three layers of documentation:
- The product spec describes what the system should do: features, user stories, acceptance criteria, and domain logic. It answers the question "what."
- The technical spec describes how the system will do it: architecture, data models, API contracts, and technology choices. It answers the question "how."
- The constitution describes what the system is never allowed to do, regardless of what the product spec requests or what the technical spec proposes. It answers the question "What are the absolute constraints?"
The constitutional document sits above both. It is the invariant layer. When an AI agent is working within an SDD workflow, the constitution needs to be in scope before any task begins, but "in scope" depends on how the toolchain is configured, not on the file existing in the repository. In Cursor, AGENTS.md at the repo root is read automatically; other files are loaded at the agent's discretion based on perceived relevance. If constitution.md is not explicitly referenced from AGENTS.md or a .cursor/rules/ file, there is no guarantee the agent will read it. The constitutional layer starts with the wiring, not the document.
Outputs that violate machine-checkable rules are rejected automatically by CI gates. Violations of review-only rules depend on human judgment and can be missed.
Practically, constitution.md lives at the root of the repository, alongside README.md. This placement is intentional. It makes the document discoverable by every contributor, every CI runner, and every AI agent configured to read the repository context. It is not buried in a docs/ folder. It is not a section inside a wiki. It is a first-class file with the same visibility as the project's entry point.
The constitution is also versioned like code. Changes to it go through pull requests with the same scrutiny as changes to core business logic — because they are changes to core business logic. A security rule removed from the constitution has the same risk profile as a security check removed from the codebase.
What constitution.md can and cannot enforce
As noted above, constitution.md is a normative document. By itself, a Markdown file enforces nothing. It becomes part of an enforceable workflow only when three additional layers are present.
- The agent guidance layer is how the AI agent receives the constitution. In Cursor,
AGENTS.mdandProject Rulesserve different functions:AGENTS.mdat the repo root is read automatically at the start of every agent session, whileProject Rulesin .cursor/rules/are loaded based on the agent's judgment about relevance. The same distinction applies across other toolchains — some instructions are always-on, others are contextual. The practical configuration is covered in Step 4 of the workflow below. - The enforcement layer is what actually blocks prohibited output. Semgrep rules, secret scanners, dependency audits, and CI/CD gates are deterministic: they do not interpret intent or make judgment calls. They fail the pipeline, or they do not. For machine-checkable rules — SQL interpolation, secrets in source, unpinned dependencies — the enforcement layer is the actual control. The constitution is the source of record for why the control exists.
- The review and traceability layer covers what cannot be automated. Some rules require architectural judgment: "business logic must not appear in HTTP handlers," "auth library must be project-approved." These cannot be expressed as a Semgrep pattern. They are enforced through PR checklists, mandatory human review for constitutionally flagged code, and the traceability matrix that documents coverage.
The practical implication is this: when you write a constitutional rule, classify it immediately.
| RULE TYPE | ENFORCEMENT MECHANISM |
|---|---|
| Pattern-level prohibition (SQL injection, hardcoded secrets) | Semgrep, git-secrets, custom linter |
| Dependency constraint | Dependency scanner, lockfile audit |
| Data handling requirement | PR checklist, integration test, manual review |
| Architectural invariant | Architecture test, PR checklist |
| Process obligation (traceability update) | PR template gate |
One thing worth stating plainly before the workflow details: the constitution does not make AI-generated code safe. It makes security requirements legible, connected to enforcement mechanisms, and traceable through artifacts. That is a meaningful improvement over ad-hoc review, but it is not a guarantee. The sections that follow describe how to build the workflow; this section is the ceiling on what that workflow can deliver.
Rules without any corresponding enforcement mechanism (no automated check, no PR checklist item, no traceability entry) are aspirational, not constitutional. Review-only rules are still valid constitutional constraints: they create documented review obligations and traceability requirements. The distinction is not between machine-checkable and review-only rules, but between rules that have a defined enforcement path of any kind and rules that exist only as text.
Anatomy of a security-focused constitution.md
Below is a production-oriented template we use as a starting point for backend services. It is opinionated by design — precision over comprehensiveness, but it is not a drop-in solution. Every team's threat model will require additions; the goal is to give the agent unambiguous constraints, not to cover every possible attack surface. Vague rules ("use secure coding practices") give the agent no actionable constraint. Precise rules ("never interpolate user input into SQL strings; use parameterized queries exclusively") leave no ambiguity.
# constitution.md
## Purpose
This document defines the invariant constraints for all AI-assisted development
on this repository. These rules take precedence over product specs, technical
specs, and individual task instructions. No generated output that violates a
rule in this document should be merged without explicit human override and
documented justification.
---
## 1. Security Constraints
### 1.1 Input Handling
- All user-supplied input MUST be validated at the boundary where it enters
the system. Do not pass raw input to downstream functions.
- SQL queries MUST use parameterized statements or a query builder that
prevents interpolation. String concatenation for SQL construction is
prohibited without exception.
- HTML output MUST be escaped by default. Raw rendering of user content
requires explicit sanitization with a reviewed library (e.g., DOMPurify).
Do not mark strings as safe without tracing the sanitization path.
- File uploads MUST be validated by magic bytes, not by client-supplied
MIME type or file extension. Store uploads outside the web root.
### 1.2 Authentication and Authorization
- Authentication logic MUST NOT be written from scratch. Use the
project-approved auth library (see technical spec, section 3).
- Every route that handles non-public data MUST have an explicit authorization
check. Omitting the check is not equivalent to "allow all" -- it is a
violation of this constitution.
- JWTs MUST be verified with the correct algorithm. Do not accept "none"
as a valid algorithm. Pin the accepted algorithm list in configuration,
not in code.
- Session tokens MUST be rotated on privilege escalation and on logout.
### 1.3 Secrets and Credentials
- Secrets (API keys, passwords, private keys, connection strings) MUST NOT
appear in source code, comments, or test fixtures.
- Secrets MUST be provided through approved runtime secret-management
mechanisms: environment variables injected by the deployment platform,
Vault, AWS SSM/Secrets Manager, GCP Secret Manager, or equivalent.
Hardcoded secrets are prohibited regardless of environment.
- Logging MUST NOT emit values from the following data classes: credentials,
tokens, PII (see section 3). Logging the key name is permitted; logging
the value is not.
### 1.4 Dependency and Supply Chain
- Production dependency resolution MUST be reproducible through lockfiles.
Direct production dependencies SHOULD be pinned to an exact version or
constrained according to the package management policy.
- Dependencies flagged with a CVE at severity HIGH or CRITICAL MUST NOT
be introduced. If an existing dependency receives such a CVE, it MUST
be patched or replaced within the SLA defined in the security runbook.
- Dependencies with no release or maintenance activity in 24 months require
documented risk review before introduction or continued use.
### 1.5 Error Handling and Information Disclosure
- Error responses to external clients MUST NOT include stack traces,
internal file paths, database schema details, or library versions.
- Internal errors MUST be logged with full context (for observability) but
returned to the client only as a generic error code and a correlation ID.
- Do not catch and silently swallow exceptions. Every caught exception MUST
either be re-thrown, logged, or handled with documented intent.
---
## 2. Architectural Invariants
- The service MUST follow the layered architecture defined in the technical
spec. Business logic MUST NOT appear in HTTP handlers. Database queries
MUST NOT appear in domain layer objects.
- Infrastructure dependencies (DB clients, cache, message queue) MUST be
injected, not instantiated inline. This is required for testability and
for consistent secret management.
- Cross-service communication MUST go through the defined API contracts.
Direct database access across service boundaries is prohibited.
---
## 3. Data Classification
| Class | Examples | At Rest | Logging |
|--------------|---------------------------------|--------------|--------------|
| Public | Product names, public prices | No req. | Allowed |
| Internal | Internal IDs, audit logs | Encrypted | Allowed |
| Confidential | User PII, email, phone | Encrypted | Key name only|
| Secret | Passwords, tokens, private keys | HSM or Vault | Prohibited |
All data classes require TLS for external traffic. Internal service-to-service
communication applies stricter requirements for Confidential and Secret data:
| Class | External traffic | Internal service-to-service |
|--------------|------------------|-----------------------------|
| Public | TLS | TLS |
| Internal | TLS | TLS |
| Confidential | TLS | mTLS where supported |
| Secret | TLS | mTLS |
All AI-generated code that touches Confidential or Secret class data MUST
be flagged for mandatory human review before merge, regardless of test coverage.
---
## 4. Compliance Anchors
- OWASP Top 10:2021: rules in section 1 map to A01-A05, A09. This mapping
uses the 2021 release because many enterprise control frameworks and internal
policies still reference it. For new programs, validate the same rules
against the current OWASP Top Ten release.
See /docs/compliance/traceability.md.
- SOC 2 Type II (if applicable): logging and secret management rules support
the Availability and Confidentiality criteria.
- GDPR: PII handling rules in section 3 implement the data minimization and
integrity principles. Any new collection of personal data MUST be reviewed
against the data processing agreement before implementation begins.
---
## 5. Override Protocol
A rule in this constitution may be overridden only by:
1. A pull request that explicitly modifies this document, reviewed and approved
by at least two senior engineers and the security lead.
2. A documented exception in /docs/compliance/exceptions.md that references
the specific rule, the justification, the risk owner, and the expiry date.
AI-generated code does not override constitutional rules. If the agent produces
output that requires an override, the override goes through the human protocol
above, not through re-prompting.Several structural decisions in this template are worth explaining.
- Precision over breadth. Each rule names a specific prohibited pattern and a specific permitted alternative. "Use secure coding practices" is not a constitutional rule. "String concatenation for SQL construction is prohibited without exception" is.
Important note: The "without exception" phrasing is intentional: it closes the door on ad-hoc justifications at generation time. The exception surface — approved query builders that internally use string construction — belongs in the technical spec, not in the constitutional rule itself.
- Data classification with split transit requirements. The table separates external and internal transit requirements. mTLS is appropriate for internal service-to-service communication on Confidential and Secret data paths, but it is not universally applicable to public API traffic. Conflating the two creates rules that cannot be followed in practice.
- The override protocol. Constitutional rules without a legitimate escape valve generate workarounds rather than compliance. The override protocol makes exceptions visible, documented, and time-bounded. Build it before you need it.
Real-world case: securing a backend API service with constitutional SDD
The following scenario is a constructed illustration based on patterns we observe across backend API services at Mad Devs — not a single documented project with recorded metrics, but a representative example of how the constitutional layer behaves in practice.
The scenario — a multi-tenant SaaS product with user authentication, file uploads, and a third-party payment integration — represents three classic failure modes in AI-generated code when produced without constitutional constraints.
The threat model surface
The threat model identified four high-priority threats:
- Tenant data leakage through missing authorization checks on data queries.
- File upload abuse via MIME type spoofing and path traversal.
- Credential exposure through verbose error logging during payment processing.
- Dependency chain compromise via unpinned third-party packages in the payment integration.
Each threat is mapped directly to a constitutional rule in sections 1.1 through 1.4.
Generating the authentication layer
We prompted the agent to generate the JWT authentication middleware using the constitution as a constraint. The agent produced a middleware that pinned the accepted algorithm to RS256, rejected tokens without expiry claims, and included a rotation hook on privilege escalation. The agent also flagged one judgment call: the spec did not specify behavior for expired tokens with valid signatures. The flag went to the human reviewer, who added the rule to the constitution and to the technical spec before the middleware was merged. The constitution grew from the gap.
Generating the file upload handler
In unconstrained generation tests, AI agents commonly produce handlers that validate by Content-Type header and store the file in a path derived from the original filename. Both patterns are prohibited in the constitution. With the constitution in scope, the agent produced a handler that reads the magic bytes of the uploaded file, validates against an allowlist of permitted types, generates a UUID-based storage path, and stores the file in a non-web-accessible bucket. The diff between the unconstrained and constrained outputs addressed four distinct vulnerability classes before code review began.
Payment integration and logging
The payment integration required calls to a third-party API with a secret key. The constitution's logging rules (section 1.3) prohibit logging token values. The agent generated a logging wrapper that redacted the Authorization header before passing the request log to the observability stack. The redaction was not in the original task instruction — it was inferred from the constitutional rule. That inference is what the constitutional layer is designed to produce.
What the constitutional layer did not catch
The agent produced a race condition in the file upload cleanup routine — a logic error that had no security implications but would have caused silent data loss under concurrent load. Constitutional constraints do not replace logic review or integration testing. The race condition was caught in code review. The security issues were addressed by the constitution. Each layer caught what it was designed to catch.
Step-by-step guide to build a constitutional SDD workflow
This is the workflow we run for any new backend service. The steps are sequential; skipping earlier steps undermines the guarantees of later ones.
Step 1: Draft the product spec and threat model in parallel
Before touching the constitution, run a lightweight threat model against the product spec. You do not need a full STRIDE exercise. A table in the spec document that lists the assets, the trust boundaries, and the top threats per boundary is enough to get started. The threat model is the source of truth for which security rules belong in the constitution. Rules without a corresponding threat are noise; threats without a corresponding rule are gaps.
Step 2: Write constitutional constraints from the threat model
For each threat in the model, write at least one prohibition and at least one required mitigation in the constitution. The prohibition closes the attack vector. The required mitigation specifies what the agent must produce instead. At this point, also classify each rule as machine-checkable or review-only (see the table in the previous section). Commit this version of constitution.md before the technical spec is written.
Step 3: Write the technical spec with the constitution as a constraint
The technical spec is written with the constitution open. Architecture choices that would require a constitutional override are replaced with choices that comply. If compliance is genuinely impossible for a given technology choice, that is a signal to revisit either the technology or the rule — through the override protocol, not by ignoring the constitution.
Step 4: Configure the AI agent to read the constitution first
In Cursor, place the constitution in Project Rules or reference it from AGENTS.md, depending on how the team's rule configuration is structured. In GitHub Copilot, configure repository custom instructions to reference the constitution file. For custom agents, prepend the constitution as a high-priority context at the start of each task instruction. The goal is that the agent reads the constitution before it reads the task, and that the task is always scoped by the constitution.
Step 5: Generate implementation artifacts with constitution-scoped prompts
When prompting the agent for implementation, reference the constitution explicitly as a scope declaration, not a reminder:
Generate the user registration endpoint according to the technical spec (section 4.2). Apply all constraints in constitution.md section 1.
Output the handler, the validation schema, and the unit tests. Flag any design decision that required a judgment call under the constitution rules.The explicit reference to section 1 asks the agent to apply a specific subset of rules and to surface its own uncertainty. Flagged judgment calls become review targets.
Step 6: Run a constitutional review before code review
Before the PR goes to a human reviewer, run the constitutional check. For machine-checkable rules, this is automated. For review-only rules, this is a checklist pass. Human code review then focuses on logic, architecture, and edge cases — not on catching the injection vulnerability that the constitutional layer should have addressed.
Step 7: Record the traceability artifact
For every merged PR that touches a constitutionally constrained area, update the traceability matrix. This is the audit trail that makes SDD compliance demonstrable rather than asserted.
Creating a compliance traceability matrix from SDD artifacts
A traceability matrix connects each constitutional rule to the artifacts that demonstrate its enforcement. Without this matrix, SDD compliance is a claim. With it, there is evidence.
The matrix has five columns:
| RULE ID | RULE SUMMARY | SOURCE REQUIMENT | IMPLEMENTING ARTEFACT | VERIFICATION METHOD |
|---|---|---|---|---|
| SEC-1.1-A | Parameterized queries only | OWASP A03:2021 | src/db/queries.ts | Semgrep rule SEC-1.1-A, PR #142 |
| SEC-1.2-B | Explicit authz on every route | Internal threat model T-01 | src/middleware/authz.ts | Route coverage script, PR #148 |
| SEC-1.3-A | No secrets in source | SOC 2 CC6.1 | .env.example, Vault config | git-secrets pre-commit, CI scan |
| SEC-1.4-A | Reproducible dependency resolution | Supply chain threat T-04 | package-lock.json | Dependabot + CI lockfile check |
| SEC-1.5-A | No stack traces in responses | OWASP A09:2021 | src/middleware/errorHandler.ts | Integration test suite, PR #151 |
The "Implementing artifact" column links the constitutional rule to the code. The "Verification method" column links the code to the evidence that the rule is actually enforced. Without both columns, the matrix documents intent, not coverage.
We maintain the matrix as a Markdown file at /docs/compliance/traceability.md and update it as part of the PR template for any change touching a constitutionally constrained area. The PR template includes a required section:
## Constitutional compliance
- [ ] I have checked all changes against constitution.md
- [ ] New constitutional constraints introduced: [list or N/A]
- [ ] Traceability matrix updated: [link to commit or N/A]
- [ ] Constitutional override required: [link to exception doc or N/A]This makes the update a required step, not an optional one. The compliance artifact is produced as part of the development workflow, not assembled retrospectively before an audit.
Integrating constitutional checks into CI/CD
The constitutional layer connects to CI/CD at three levels. Each level catches a different class of violation.
Pre-commit: pattern-level checks
Pre-commit hooks run fast, static checks against prohibited patterns most likely to appear in AI-generated code. We use git-secrets for credential detection and custom Semgrep rules derived from the machine-checkable rules in the constitution. The key constraint: not every constitutional rule can be expressed as a Semgrep pattern. Rules about architectural boundaries, approved library usage, or authorization coverage require different mechanisms. Machine-checkable rules are translated into Semgrep, secret scanners, or custom scripts. Non-machine-checkable rules remain review obligations tied to traceability artifacts.
Here is a corrected Semgrep rule derived from SEC-1.1-A:
rules:
- id: constitution-sec-1-1-a-sql-injection
message: >
SQL string interpolation detected. constitution.md SEC-1.1-A requires
parameterized queries. Replace raw interpolation with parameterized
queries or a project-approved query builder.
languages: [javascript, typescript]
severity: ERROR
metadata:
constitution_rule: SEC-1.1-A
owasp: A03:2021
pattern-either:
- pattern: |
$DB.query("..." + $INPUT)
- pattern: |
$DB.query(`...${$INPUT}...`)Note that pattern-either is required here because the two patterns represent alternatives, not conditions that must both match simultaneously. The example is a simplified pattern-level check. A production implementation would also cover ORM-specific query methods, tagged templates, and taint tracking for user input flowing to query sinks.
PR check: AI-assisted constitutional review
For a broader constitutional check, we run an AI-assisted review pass as a required CI step on PRs touching security-sensitive paths. The step sends the diff to a review agent with the constitution as context and asks: "Does this diff contain any output prohibited by the attached constitution? List each potential violation with the rule ID and the line reference." The output is posted as a PR comment labeled as advisory, non-blocking. Human reviewers must address each flagged item explicitly. Dismissing a flag without comment fails the review.
This step has false positives and false negatives. Treating it as an automated gate rather than a triage tool produces both false confidence and alert fatigue. Its value is in surfacing judgment calls for human attention, not in replacing human review.
Dependency scan: supply chain constraints
The dependency constraints in section 1.4 are enforced by a dedicated CI step that checks: production dependencies are resolvable from a committed lockfile, no dependency has a CVE at HIGH or CRITICAL severity in the current advisory database, and dependencies with no maintenance activity in 24 months are flagged for review rather than automatically blocked. The last check catches abandoned packages without treating all stable, mature libraries as suspects.
Deployment gate: compliance coverage check
Before deployment to production, a final gate verifies that the traceability matrix covers all constitutionally constrained modules that changed in the release. The gate reads a coverage registry that maps file paths to the constitutional rules that apply:
# docs/compliance/coverage.yml
constitutional_coverage:
- path: src/routes/payments/**
rules: [SEC-1.2-B, SEC-1.3-A, SEC-1.5-A]
- path: src/uploads/**
rules: [SEC-1.1-D, SEC-1.3-A]
- path: src/auth/**
rules: [SEC-1.2-A, SEC-1.2-B, SEC-1.2-C, SEC-1.2-D]The gate compares modified files against this registry and fails if a modified file has no corresponding matrix entry. This is a coarse check — it does not verify the accuracy of the entry, only that one exists. The accuracy is the responsibility of the review process. The gate catches the case where a compliant codebase drifts because someone merged a change without updating the matrix.
Limitations and honest trade-offs
Constitutional SDD is a meaningful improvement over ad-hoc AI coding assistant security best practices, but it is not a security guarantee. The following limitations are real, and teams that underestimate them will be disappointed.
The constitution only constrains what the agent actually reads. Context management in long agentic sessions is an active problem. In sessions that span many files and many turns, the constitution may be partially or fully displaced from the agent's effective context. We mitigate this by re-injecting the constitution at the start of each new task instruction, but this is a workaround for a fundamental limitation of the current generation of AI tooling.
Omission rules degrade faster than permission rules, even when the constitution stays in context. A rule that says "always use parameterized queries" is a positive instruction the agent can pattern-match against. A rule that says "never log credential values" requires the agent to reason about what counts as a credential, what counts as logging, and whether a given code path reaches a log sink — across the full scope of the generated output. As session complexity grows, omission rules are the first to be applied inconsistently, independently of context window pressure. This means the rules that matter most for security are also the ones most vulnerable to degradation. Machine-checkable enforcement for omission rules is not optional; it is the primary control.
Rules are only as precise as the person who wrote them. A vague rule produces vague enforcement. Writing precise, actionable rules requires security domain knowledge. If the team lacks that knowledge, the constitution will have gaps — and those gaps will look like coverage because the rule exists even when the underlying threat is not addressed. An external review of the constitution itself, separate from a codebase audit, is a worthwhile investment.
AI-assisted review has false positives and false negatives. The false negative rate is the more dangerous of the two. Teams that treat the AI review pass as a security gate rather than a triage tool will develop false confidence. The constitutional layer reduces the surface area that human reviewers must cover; it does not replace human judgment.
The traceability matrix requires maintenance discipline. The matrix becomes stale during high-velocity sprints when the PR template feels like overhead. The solution is enforcement at the PR gate level — make the matrix update a blocking checklist item, not an advisory one — but this requires team agreement and consistent follow-through.
Constitutional rules create real development friction. A rule that prohibits a convenient pattern will generate frustration, especially when the pattern feels safe in a specific context. This friction is intentional. But teams should build the override protocol before they need it. A legitimate, documented escape valve reduces the pressure to route around the rules informally.
Spec security does not equal runtime security. Constitutional SDD enforces spec security at generation time. It does not enforce runtime behavior. A constitutionally compliant codebase can still fail at runtime due to misconfigured infrastructure, compromised dependencies, or attack vectors that were not in the original threat model. Constitutional SDD belongs alongside runtime monitoring, penetration testing, and incident response — not instead of them.
Сonclusion
Constitutional SDD represents a structural shift in how security requirements travel through the development process. Instead of arriving as feedback on code that already exists, they arrive as constraints on code that has not been generated yet. The constitution.md file is the mechanism that makes this shift concrete: a versioned, auditable document that sits at the top of the specification hierarchy and shapes every AI-generated artifact beneath it.
The investment is real. Writing precise constitutional rules requires domain knowledge. Maintaining the traceability matrix requires discipline. Integrating constitutional checks into CI requires pipeline work. But the return is also real: a class of security vulnerabilities that is addressed by construction rather than caught by inspection, and a compliance posture that can be demonstrated through artifacts rather than asserted through policy documents.
And once again, the constitution does not make AI-generated code safe. It makes the safety requirements legible, connected to enforcement, and traceable.
