# Project Constitution

version: 1.0.0 · ratified: {YYYY-MM-DD} · amended: {YYYY-MM-DD}

The constitution holds the non-negotiables for this project. Every PRD, epic, and story
is checked against it before any work is materialized into a spec.

Each article carries an **Enforcement** level:

- **BLOCKER** — an unwaived violation stops the work. The story stays `draft` and cannot
  enter the build loop.
- **WARNING** — recorded in the review report, never blocks.

The **Check** line is what the gate actually evaluates. Keep it concrete and mechanical.
An article whose Check cannot be evaluated by reading the artifact is a WARNING at best.

---

## Article I — Testable Acceptance

**Enforcement**: BLOCKER

**Rule**: Every story that changes behaviour states how it will be verified, in terms
someone else could execute without asking a question.

**Check**: The story has a non-empty `## Verification` section containing at least one
runnable command, and at least one acceptance criterion written in GIVEN-WHEN-THEN form.

---

## Article II — Scope Discipline

**Enforcement**: BLOCKER

**Rule**: Every story declares what it is not doing. Undeclared scope is how stories grow
without anyone deciding they should.

**Check**: `### Out of Scope` is present and non-empty.

---

## Article III — Traceability

**Enforcement**: BLOCKER

**Rule**: Every story traces to at least one requirement in the PRD, and every PRD
requirement is covered by at least one story.

**Check**: The story's `requirements` frontmatter lists at least one FR or NFR id that
exists in `docs/product/prd.md`. No PRD requirement is left uncovered across all stories.

---

## Article IV — Right-Sized Stories

**Enforcement**: WARNING

**Rule**: A story is small enough to implement and verify in one sitting. Stories that
sprawl are epics that have not been split yet.

**Check**: The story has no more than 7 acceptance criteria and touches no more than 10
files in `files_to_modify`.

---

## Article V — Follow Existing Patterns

**Enforcement**: WARNING

**Rule**: New code matches the conventions already in the codebase. Introducing a second
way to do something already done needs a stated reason.

**Check**: The story's `## Technical Notes` names at least one existing file or pattern to
follow, or explicitly states why a new pattern is being introduced.

---

## Article VI — No Silent Failure

**Enforcement**: WARNING

**Rule**: Error paths are specified, not left to the implementer's imagination.

**Check**: For stories touching I/O, network, or persistence, at least one acceptance
criterion covers the failure case.

---

<!--
Add project-specific articles below. Good candidates:

- Technology constraints ("all persistence goes through the repository layer")
- Security non-negotiables ("no secret is ever read from anywhere but the env")
- Performance bars ("no endpoint may exceed 200ms at p95")
- Compliance requirements ("all PII access is audit-logged")
- Team constraints ("no dependency added without an ADR")

Keep the total under about 10 articles. A constitution nobody can hold in their head is
one nobody applies.
-->

## Amendment Process

Amending the constitution bumps `version` and `amended`. Stories already gated against an
older version keep their recorded `constitution.version` — they are not retroactively
invalidated. Re-run the gate on a story to bring it to the current version.

## Waivers

A story may waive a BLOCKER article when the violation is deliberate. A waiver requires
all three fields, or it is treated as a failure:

```yaml
constitution:
  status: waived
  waivers:
    - article: "II"
      rationale: "Timeboxed spike; scope is intentionally open."
      approved_by: "name@example.com"
      approved_at: "{ISO 8601}"
```
